#5375: Regression in newName
---------------------------------+------------------------------------------
Reporter: reinerp | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Template Haskell | Version: 7.3
Keywords: | Testcase:
Blockedby: | Difficulty:
Os: Unknown/Multiple | Blocking:
Architecture: Unknown/Multiple | Failure: GHC rejects valid program
---------------------------------+------------------------------------------
Comment(by simonpj):
Aha. This is a consequence of fixing another bug #5037! (See also `Note
[Binders in Template Haskell]` in source:compiler/hsSyn/Convert.lhs.)
Consider this:
{{{
x = 4
y = $(do { x <- newName "x"; return (LamE (VarP x) (VarE (mkName "x"))) })
}}}
So the ''binder'' is made with `newName`, but the ''occurrence'' is made
with `mkName` (the "dynamic binding" bit of TH). Clearly, I think, the
occurrence should should bind to the lambda, not to the top-level x. So
the defns should end up thus:
{{{
-- Like this
x = 4
y = \x -> x
-- NOT like this
x = 4
y = \x' -> x
}}}
Similarly, what do you think should happen here:
{{{
$( do { x <- newName "x"; return (ValD (VarP x) (LitE 3)) } )
v = x
}}}
Current the `newName` expands to something that captures the `x` below the
splice:
{{{
-- We get this
x = 3
v = x
-- NOT this
x' = 3
v = x
}}}
Remember too that the `newName` stuff is what happens behind the scences
with a quotation like `[d| x = 3 |]`.
For your data type example, suppose we had
{{{
-- declare 'data E = D' with a fresh name 'D'
$(do
nm <- newName "D"
return $ [DataD [] (mkName "E") [] [NormalC nm []] []] )
f :: E
f = D
}}}
Wouldn't you expect the `D` in the defn of F to bind to the `D` declared
by the spliced data type decl? Just as if you'd written
{{{
data E = D
f :: E
f = D
}}}
Remember, again, that quotation uses `newName` for binders, and you'd
''definitely'' expect this to expand to the above code:
{{{
$( [d| data E = D |] )
f :: E
f = D
}}}
In short, it seems to me that the "multiple definitions" thing is right.
But I accept that:
* There is therefore no way to splice in a data type decl that is
guaranteed not to clash with any existing one. That's bad. (In the case
of terms, lambdas etc simply ''shadow'' existing defns, so the problem
doesn't arise.) Maybe we need a way to make a fresh name that can be
referred to ''only'' by knowing the name, and not by `mkName` or by open
Haskell code?
* The "internal error" message from the type checker is terrible.
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/5375#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs