[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