[GHC] #13782: Bullish use of Template Haskell's newName causes GHC internal error
GHC
ghc-devs at haskell.org
Mon Jun 12 20:05:35 UTC 2017
#13782: Bullish use of Template Haskell's newName causes GHC internal error
-------------------------------------+-------------------------------------
Reporter: RyanGlScott | Owner: carlostome
Type: bug | Status: new
Priority: high | Milestone: 8.2.1
Component: Template Haskell | Version: 8.0.1
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: Compile-time | Unknown/Multiple
crash or panic | Test Case:
Blocked By: | Blocking:
Related Tickets: #12503 | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by carlostome):
After some debugging I found out that the bug arises in the following
function from
[https://git.haskell.org/ghc.git/blob/HEAD:/compiler/rename/RnTypes.hs#l1711
RnTypes]
{{{
#!haskell
extract_hs_tv_bndrs :: [LHsTyVarBndr GhcPs] -> FreeKiTyVars
-> FreeKiTyVars -> RnM FreeKiTyVars
-- In (forall (a :: Maybe e). a -> b) we have
-- 'a' is bound by the forall
-- 'b' is a free type variable
-- 'e' is a free kind variable
extract_hs_tv_bndrs tvs
(FKTV acc_kvs acc_k_set acc_tvs acc_t_set acc_all)
-- Note accumulator comes first
(FKTV body_kvs body_k_set body_tvs body_t_set
body_all)
| null tvs
= return $
FKTV (body_kvs ++ acc_kvs) (body_k_set `unionOccSets` acc_k_set)
(body_tvs ++ acc_tvs) (body_t_set `unionOccSets` acc_t_set)
(body_all ++ acc_all)
| otherwise
= do { FKTV bndr_kvs bndr_k_set _ _ _
<- foldrM extract_lkind emptyFKTV [k | L _ (KindedTyVar _ k) <-
tvs]
; let locals = mkOccSet $ map (rdrNameOcc . hsLTyVarName) tvs
; return $
FKTV (filterOut ((`elemOccSet` locals) . rdrNameOcc . unLoc)
(bndr_kvs ++ body_kvs) ++ acc_kvs)
((body_k_set `minusOccSet` locals) `unionOccSets` acc_k_set
`unionOccSets` bndr_k_set)
(filterOut ((`elemOccSet` locals) . rdrNameOcc . unLoc)
body_tvs ++ acc_tvs)
((body_t_set `minusOccSet` locals) `unionOccSets` acc_t_set)
(filterOut ((`elemOccSet` locals) . rdrNameOcc . unLoc)
(bndr_kvs ++ body_all) ++ acc_all) }
}}}
In the case ''tvs'' is empty, the '''locals''' variable holds the set of
OccName found in tvs. The OccName of variable ''a2'' in the program with
the line:
{{{#!haskell
[f,a2] <- mapM newName ["f","a"]
}}}
is 'a' and thus the variable is filtered out from ''bndr_kvs ++ body_kvs''
(Which I guess holds the variable 'a' from ''data Maybe a''). However, in
the program with the line:
{{{#!haskell
[f,a2] <- mapM newName ["f","b"]
}}}
the ''OccName'' of ''a2'' is "b" and doesn't get filtered out because it's
OccName is not "a".
In the previous version of the commit
6746549772c5cc0ac66c0fce562f297f4d4b80a2 that changed this function, the
variables where filtered regarding the full name (Which in this case is a
''Exact'' name) not only its OccName and the problem didn't existed.
I guess one way to solve this would be to filter out again based on full
names and not only the ''OccName'' of variables.
Any thoughts?
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13782#comment:4>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list