Allow type families to use GADT syntax (and be GADTs)
[ghc-hetmet.git] / compiler / rename / RnBinds.lhs
index 134a929..23a22c9 100644 (file)
@@ -37,7 +37,7 @@ import RdrName                ( RdrName, rdrNameOcc )
 import SrcLoc
 import ListSetOps      ( findDupsEq )
 import BasicTypes      ( RecFlag(..) )
-import Digraph         ( SCC(..), stronglyConnComp )
+import Digraph         ( SCC(..), stronglyConnCompFromEdgedVertices )
 import Bag
 import Outputable
 import FastString
@@ -312,15 +312,14 @@ rnValBindsRHSGen :: (FreeVars -> FreeVars)  -- for trimming free var sets
 
 rnValBindsRHSGen trim bound_names (ValBindsIn mbinds sigs) = do
    -- rename the sigs
-   env <- getGblEnv
-   traceRn (ptext (sLit "Rename sigs") <+> ppr (tcg_rdr_env env))
    sigs' <- renameSigs (Just (mkNameSet bound_names)) okBindSig sigs
    -- rename the RHSes
    binds_w_dus <- mapBagM (rnBind (mkSigTvFn sigs') trim) mbinds
-   let (anal_binds, anal_dus) = depAnalBinds binds_w_dus
-       (valbind', valbind'_dus) = (ValBindsOut anal_binds sigs',
-                                   usesOnly (hsSigsFVs sigs') `plusDU` anal_dus)
-   return (valbind', valbind'_dus)
+   case depAnalBinds binds_w_dus of
+       (anal_binds, anal_dus) ->
+           do let valbind' = ValBindsOut anal_binds sigs'
+                  valbind'_dus = usesOnly (hsSigsFVs sigs') `plusDU` anal_dus
+              return (valbind', valbind'_dus)
 
 rnValBindsRHSGen _ _ b = pprPanic "rnValBindsRHSGen" (ppr b)
 
@@ -494,11 +493,13 @@ rnBind _ trim (L loc (PatBind { pat_lhs = pat,
 
        ; (grhss', fvs) <- rnGRHSs PatBindRhs grhss
                -- No scoped type variables for pattern bindings
+       ; let fvs' = trim fvs
 
-       ; return (L loc (PatBind { pat_lhs = pat, 
+       ; fvs' `seq` -- See Note [Free-variable space leak]
+      return (L loc (PatBind { pat_lhs = pat,
                                   pat_rhs = grhss', 
                                     pat_rhs_ty = placeHolderType, 
-                                  bind_fvs = trim fvs }), 
+                                  bind_fvs = fvs' }),
                  bndrs, pat_fvs `plusFV` fvs) }
 
 rnBind sig_fn 
@@ -516,20 +517,35 @@ rnBind sig_fn
        ; (matches', fvs) <- bindSigTyVarsFV (sig_fn plain_name) $
                                -- bindSigTyVars tests for Opt_ScopedTyVars
                             rnMatchGroup (FunRhs plain_name inf) matches
+       ; let fvs' = trim fvs
 
        ; checkPrecMatch inf plain_name matches'
 
-       ; return (L loc (FunBind { fun_id = name, 
+       ; fvs' `seq` -- See Note [Free-variable space leak]
+      return (L loc (FunBind { fun_id = name,
                                   fun_infix = inf, 
                                   fun_matches = matches',
-                                    bind_fvs = trim fvs, 
+                                    bind_fvs = fvs',
                                   fun_co_fn = idHsWrapper, 
                                   fun_tick = Nothing }), 
                  [plain_name], fvs)
       }
 
 rnBind _ _ b = pprPanic "rnBind" (ppr b)
-               
+
+{-
+Note [Free-variable space leak]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We have
+    fvs' = trim fvs
+and we seq fvs' before turning it as part of a record.
+
+The reason is that trim is sometimes something like
+    \xs -> intersectNameSet (mkNameSet bound_names) xs
+and we don't want to retain the list bound_names. This showed up in
+trac ticket #1136.
+-}
+
 ---------------------
 depAnalBinds :: Bag (LHsBind Name, [Name], Uses)
             -> ([(RecFlag, LHsBinds Name)], DefUses)
@@ -538,7 +554,7 @@ depAnalBinds :: Bag (LHsBind Name, [Name], Uses)
 depAnalBinds binds_w_dus
   = (map get_binds sccs, map get_du sccs)
   where
-    sccs = stronglyConnComp edges
+    sccs = stronglyConnCompFromEdgedVertices edges
 
     keyd_nodes = bagToList binds_w_dus `zip` [0::Int ..]
 
@@ -705,7 +721,7 @@ renameSigs mb_names ok_sig sigs
 renameSig :: Maybe NameSet -> Sig RdrName -> RnM (Sig Name)
 -- FixitySig is renamed elsewhere.
 renameSig mb_names sig@(TypeSig v ty)
-  = do { new_v <- lookupSigOccRn mb_names sig v
+  = do { new_v <- lookupSigLocOccRn mb_names sig v
        ; new_ty <- rnHsSigType (quotes (ppr v)) ty
        ; return (TypeSig new_v new_ty) }
 
@@ -714,16 +730,16 @@ renameSig _ (SpecInstSig ty)
        ; return (SpecInstSig new_ty) }
 
 renameSig mb_names sig@(SpecSig v ty inl)
-  = do { new_v <- lookupSigOccRn mb_names sig v
+  = do { new_v <- lookupSigLocOccRn mb_names sig v
        ; new_ty <- rnHsSigType (quotes (ppr v)) ty
        ; return (SpecSig new_v new_ty inl) }
 
 renameSig mb_names sig@(InlineSig v s)
-  = do { new_v <- lookupSigOccRn mb_names sig v
+  = do { new_v <- lookupSigLocOccRn mb_names sig v
        ; return (InlineSig new_v s) }
 
 renameSig mb_names sig@(FixSig (FixitySig v f))
-  = do { new_v <- lookupSigOccRn mb_names sig v
+  = do { new_v <- lookupSigLocOccRn mb_names sig v
        ; return (FixSig (FixitySig new_v f)) }
 
 -- lookupSigOccRn is used for type signatures and pragmas
@@ -745,13 +761,16 @@ renameSig mb_names sig@(FixSig (FixitySig v f))
 -- return the imported 'f', so that later on the reanamer will
 -- correctly report "misplaced type sig".
 
-lookupSigOccRn :: Maybe NameSet -> Sig RdrName -> Located RdrName -> RnM (Located Name)
-lookupSigOccRn mb_names sig (L loc v)
+lookupSigLocOccRn :: Maybe NameSet -> Sig RdrName -> Located RdrName -> RnM (Located Name)
+lookupSigLocOccRn mb_names sig = wrapLocM (lookupSigOccRn mb_names sig)
+
+lookupSigOccRn :: Maybe NameSet -> Sig RdrName -> RdrName -> RnM Name
+lookupSigOccRn mb_names sig v
   = do         { mb_n <- lookupBndrRn_maybe v
        ; case mb_n of {
            Just n  -> case mb_names of {
-                       Nothing                      -> return (L loc n) ;
-                       Just ns | n `elemNameSet` ns -> return (L loc n) 
+                       Nothing                      -> return n ;
+                       Just ns | n `elemNameSet` ns -> return n 
                                | otherwise -> bale_out_with local_msg } ;
                          
            Nothing -> do
@@ -766,7 +785,7 @@ lookupSigOccRn mb_names sig (L loc v)
                                <+> ptext (sLit "for") <+> quotes (ppr v)
                           , nest 2 $ ptext (sLit "lacks an accompanying binding")]
                       $$ nest 2 msg)
-            ; return (L loc (mkUnboundName v)) }
+            ; return (mkUnboundName v) }
 
     local_msg = parens $ ptext (sLit "The")  <+> hsSigDoc sig <+> ptext (sLit "must be given where")
                         <+> quotes (ppr v) <+> ptext (sLit "is declared")
@@ -784,9 +803,9 @@ lookupSigOccRn mb_names sig (L loc v)
 
 \begin{code}
 rnMatchGroup :: HsMatchContext Name -> MatchGroup RdrName -> RnM (MatchGroup Name, FreeVars)
-rnMatchGroup ctxt (MatchGroup ms _) = do
-    (new_ms, ms_fvs) <- mapFvRn (rnMatch ctxt) ms
-    return (MatchGroup new_ms placeHolderType, ms_fvs)
+rnMatchGroup ctxt (MatchGroup ms _) 
+  = do { (new_ms, ms_fvs) <- mapFvRn (rnMatch ctxt) ms
+       ; return (MatchGroup new_ms placeHolderType, ms_fvs) }
 
 rnMatch :: HsMatchContext Name -> LMatch RdrName -> RnM (LMatch Name, FreeVars)
 rnMatch ctxt  = wrapLocFstM (rnMatch' ctxt)