X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Frename%2FRnBinds.lhs;h=0dcd42168e740c0f6c5a9241c7dacb546d5adef7;hb=9d0c8f842e35dde3d570580cf62a32779f66a6de;hp=fae6ae8e52ee5bddd12bf7c31ba873ddd1e19fcc;hpb=c2def8304ba7c48c4a3e652a63f136ebcd453674;p=ghc-hetmet.git diff --git a/compiler/rename/RnBinds.lhs b/compiler/rename/RnBinds.lhs index fae6ae8..0dcd421 100644 --- a/compiler/rename/RnBinds.lhs +++ b/compiler/rename/RnBinds.lhs @@ -28,7 +28,6 @@ import RnPat (rnPatsAndThen_LocalRightwards, rnBindPat, ) import RnEnv -import PrelNames ( mkUnboundName ) import DynFlags ( DynFlag(..) ) import Name import NameEnv @@ -161,7 +160,7 @@ rnTopBindsLHS :: MiniFixityEnv rnTopBindsLHS fix_env binds = (uncurry $ rnValBindsLHSFromDoc (topRecNameMaker fix_env)) (bindersAndDoc binds) binds -rnTopBindsRHS :: [Name] -- the names bound by these binds +rnTopBindsRHS :: NameSet -- Names bound by these binds -> HsValBindsLR Name RdrName -> RnM (HsValBinds Name, DefUses) rnTopBindsRHS bound_names binds = @@ -170,18 +169,17 @@ rnTopBindsRHS bound_names binds = then rnTopBindsBoot binds else rnValBindsRHSGen (\x -> x) -- don't trim free vars bound_names binds } - --- wrapper if we don't need to do anything in between the left and right, +-- Wrapper if we don't need to do anything in between the left and right, -- or anything else in the scope of the left -- --- never used when there are fixity declarations +-- Never used when there are fixity declarations rnTopBinds :: HsValBinds RdrName -> RnM (HsValBinds Name, DefUses) rnTopBinds b = do nl <- rnTopBindsLHS emptyFsEnv b let bound_names = map unLoc (collectHsValBinders nl) - bindLocalNames bound_names $ rnTopBindsRHS bound_names nl + bindLocalNames bound_names $ rnTopBindsRHS (mkNameSet bound_names) nl rnTopBindsBoot :: HsValBindsLR Name RdrName -> RnM (HsValBinds Name, DefUses) @@ -306,21 +304,20 @@ rnValBindsLHSFromDoc _ _ _ b = pprPanic "rnValBindsLHSFromDoc" (ppr b) rnValBindsRHSGen :: (FreeVars -> FreeVars) -- for trimming free var sets -- The trimming function trims the free vars we attach to a -- binding so that it stays reasonably small - -> [Name] -- names bound by the LHSes + -> NameSet -- Names bound by the LHSes -> HsValBindsLR Name RdrName -> RnM (HsValBinds Name, DefUses) 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 + sigs' <- renameSigs (Just 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) @@ -330,12 +327,12 @@ rnValBindsRHSGen _ _ b = pprPanic "rnValBindsRHSGen" (ppr b) -- it doesn't (and can't: we don't have the thing inside the binds) happen here -- -- The client is also responsible for bringing the fixities into scope -rnValBindsRHS :: [Name] -- names bound by the LHSes +rnValBindsRHS :: NameSet -- names bound by the LHSes -> HsValBindsLR Name RdrName -> RnM (HsValBinds Name, DefUses) rnValBindsRHS bound_names binds = rnValBindsRHSGen (\ fvs -> -- only keep the names the names from this group - intersectNameSet (mkNameSet bound_names) fvs) bound_names binds + intersectNameSet bound_names fvs) bound_names binds -- for local binds @@ -360,7 +357,7 @@ rnValBindsAndThen binds@(ValBindsIn _ sigs) thing_inside ; bindLocalNamesFV_WithFixities bound_names new_fixities $ do { -- (C) Do the RHS and thing inside - (binds', dus) <- rnValBindsRHS bound_names new_lhs + (binds', dus) <- rnValBindsRHS (mkNameSet bound_names) new_lhs ; (result, result_fvs) <- thing_inside binds' -- Report unused bindings based on the (accurate) @@ -494,11 +491,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 +515,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) @@ -704,8 +718,10 @@ renameSigs mb_names ok_sig sigs renameSig :: Maybe NameSet -> Sig RdrName -> RnM (Sig Name) -- FixitySig is renamed elsewhere. +renameSig _ (IdSig x) + = return (IdSig x) -- Actually this never occurs renameSig mb_names sig@(TypeSig v ty) - = do { new_v <- lookupSigLocOccRn mb_names sig v + = do { new_v <- lookupSigOccRn mb_names sig v ; new_ty <- rnHsSigType (quotes (ppr v)) ty ; return (TypeSig new_v new_ty) } @@ -714,68 +730,17 @@ renameSig _ (SpecInstSig ty) ; return (SpecInstSig new_ty) } renameSig mb_names sig@(SpecSig v ty inl) - = do { new_v <- lookupSigLocOccRn mb_names sig v + = do { new_v <- lookupSigOccRn 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 <- lookupSigLocOccRn mb_names sig v + = do { new_v <- lookupSigOccRn mb_names sig v ; return (InlineSig new_v s) } renameSig mb_names sig@(FixSig (FixitySig v f)) - = do { new_v <- lookupSigLocOccRn mb_names sig v + = do { new_v <- lookupSigOccRn mb_names sig v ; return (FixSig (FixitySig new_v f)) } - --- lookupSigOccRn is used for type signatures and pragmas --- Is this valid? --- module A --- import M( f ) --- f :: Int -> Int --- f x = x --- It's clear that the 'f' in the signature must refer to A.f --- The Haskell98 report does not stipulate this, but it will! --- So we must treat the 'f' in the signature in the same way --- as the binding occurrence of 'f', using lookupBndrRn --- --- However, consider this case: --- import M( f ) --- f :: Int -> Int --- g x = x --- We don't want to say 'f' is out of scope; instead, we want to --- return the imported 'f', so that later on the reanamer will --- correctly report "misplaced type sig". - -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 n ; - Just ns | n `elemNameSet` ns -> return n - | otherwise -> bale_out_with local_msg } ; - - Nothing -> do - { mb_n <- lookupGreRn_maybe v - ; case mb_n of - Just _ -> bale_out_with import_msg - Nothing -> bale_out_with empty - } }} - where - bale_out_with msg - = do { addErr (sep [ ptext (sLit "The") <+> hsSigDoc sig - <+> ptext (sLit "for") <+> quotes (ppr v) - , nest 2 $ ptext (sLit "lacks an accompanying binding")] - $$ nest 2 msg) - ; return (mkUnboundName v) } - - local_msg = parens $ ptext (sLit "The") <+> hsSigDoc sig <+> ptext (sLit "must be given where") - <+> quotes (ppr v) <+> ptext (sLit "is declared") - - import_msg = parens $ ptext (sLit "You cannot give a") <+> hsSigDoc sig - <+> ptext (sLit "an imported value") \end{code} @@ -787,9 +752,9 @@ lookupSigOccRn mb_names sig 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)