
#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