X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcBinds.lhs;h=a3b17a600ce1f278676154dd45b18e67ac2ad775;hp=e71d920bf0833ffece3b680e136de0a442230432;hb=9da4639011348fb6c318e3cba4b08622f811d9c4;hpb=ab4bc0f16200a9d26272a9fcf21e669d6d19761d diff --git a/compiler/typecheck/TcBinds.lhs b/compiler/typecheck/TcBinds.lhs index e71d920..a3b17a6 100644 --- a/compiler/typecheck/TcBinds.lhs +++ b/compiler/typecheck/TcBinds.lhs @@ -6,8 +6,8 @@ \begin{code} module TcBinds ( tcLocalBinds, tcTopBinds, tcHsBootSigs, tcMonoBinds, - TcPragFun, tcSpecPrag, tcPrags, mkPragFun, - TcSigInfo(..), + TcPragFun, tcSpecPrag, tcPrags, mkPragFun, + TcSigInfo(..), TcSigFun, mkTcSigFun, badBootDeclErr ) where #include "HsVersions.h" @@ -15,41 +15,40 @@ module TcBinds ( tcLocalBinds, tcTopBinds, import {-# SOURCE #-} TcMatches ( tcGRHSsPat, tcMatchesFun ) import {-# SOURCE #-} TcExpr ( tcMonoExpr ) -import DynFlags ( DynFlag(Opt_MonomorphismRestriction, Opt_GlasgowExts) ) +import DynFlags ( dopt, DynFlags, + DynFlag(Opt_MonomorphismRestriction, Opt_MonoPatBinds, Opt_GlasgowExts) ) import HsSyn ( HsExpr(..), HsBind(..), LHsBinds, LHsBind, Sig(..), HsLocalBinds(..), HsValBinds(..), HsIPBinds(..), - LSig, Match(..), IPBind(..), Prag(..), - HsType(..), LHsType, HsExplicitForAll(..), hsLTyVarNames, + LSig, Match(..), IPBind(..), Prag(..), LHsType, isVanillaLSig, sigName, placeHolderNames, isPragLSig, - LPat, GRHSs, MatchGroup(..), pprLHsBinds, mkHsCoerce, + LPat, GRHSs, MatchGroup(..), pprLHsBinds, mkHsWrap, hsExplicitTvs, collectHsBindBinders, collectPatBinders, pprPatBind, isBangHsBind ) import TcHsSyn ( zonkId ) import TcRnMonad -import Inst ( newDictsAtLoc, newIPDict, instToId ) +import Inst ( newDictBndrs, newIPDict, instToId ) import TcEnv ( tcExtendIdEnv, tcExtendIdEnv2, tcExtendTyVarEnv2, - pprBinders, tcLookupLocalId_maybe, tcLookupId, + pprBinders, tcLookupId, tcGetGlobalTyVars ) import TcUnify ( tcInfer, tcSubExp, unifyTheta, bleatEscapedTvs, sigCtxt ) import TcSimplify ( tcSimplifyInfer, tcSimplifyInferCheck, tcSimplifyRestricted, tcSimplifyIPs ) import TcHsType ( tcHsSigType, UserTypeCtxt(..) ) -import TcPat ( tcPat, PatCtxt(..) ) +import TcPat ( tcLetPat ) import TcSimplify ( bindInstsOfLocalFuns ) import TcMType ( newFlexiTyVarTy, zonkQuantifiedTyVar, zonkSigTyVar, tcInstSigTyVars, tcInstSkolTyVars, tcInstType, - zonkTcType, zonkTcTypes, zonkTcTyVars ) + zonkTcType, zonkTcTypes, zonkTcTyVar ) import TcType ( TcType, TcTyVar, TcThetaType, SkolemInfo(SigSkol), UserTypeCtxt(FunSigCtxt), TcTauType, TcSigmaType, isUnboxedTupleType, mkTyVarTy, mkForAllTys, mkFunTys, exactTyVarsOfType, mkForAllTy, isUnLiftedType, tcGetTyVar, mkTyVarTys, tidyOpenTyVar ) -import Kind ( argTypeKind ) +import {- Kind parts of -} Type ( argTypeKind ) import VarEnv ( TyVarEnv, emptyVarEnv, lookupVarEnv, extendVarEnv ) -import TysWiredIn ( unitTy ) import TysPrim ( alphaTyVar ) import Id ( Id, mkLocalId, mkVanillaGlobal ) import IdInfo ( vanillaIdInfo ) @@ -170,7 +169,7 @@ tcValBinds top_lvl (ValBindsOut binds sigs) thing_inside = do { -- Typecheck the signature ; let { prag_fn = mkPragFun sigs ; ty_sigs = filter isVanillaLSig sigs - ; sig_fn = mkSigFun ty_sigs } + ; sig_fn = mkTcSigFun ty_sigs } ; poly_ids <- mapM tcTySig ty_sigs -- No recovery from bad signatures, because the type sigs @@ -181,31 +180,32 @@ tcValBinds top_lvl (ValBindsOut binds sigs) thing_inside -- Extend the envt right away with all -- the Ids declared with type signatures + ; gla_exts <- doptM Opt_GlasgowExts ; (binds', thing) <- tcExtendIdEnv poly_ids $ - tc_val_binds top_lvl sig_fn prag_fn + tc_val_binds gla_exts top_lvl sig_fn prag_fn binds thing_inside ; return (ValBindsOut binds' sigs, thing) } ------------------------ -tc_val_binds :: TopLevelFlag -> TcSigFun -> TcPragFun +tc_val_binds :: Bool -> TopLevelFlag -> TcSigFun -> TcPragFun -> [(RecFlag, LHsBinds Name)] -> TcM thing -> TcM ([(RecFlag, LHsBinds TcId)], thing) -- Typecheck a whole lot of value bindings, -- one strongly-connected component at a time -tc_val_binds top_lvl sig_fn prag_fn [] thing_inside +tc_val_binds gla_exts top_lvl sig_fn prag_fn [] thing_inside = do { thing <- thing_inside ; return ([], thing) } -tc_val_binds top_lvl sig_fn prag_fn (group : groups) thing_inside +tc_val_binds gla_exts top_lvl sig_fn prag_fn (group : groups) thing_inside = do { (group', (groups', thing)) - <- tc_group top_lvl sig_fn prag_fn group $ - tc_val_binds top_lvl sig_fn prag_fn groups thing_inside + <- tc_group gla_exts top_lvl sig_fn prag_fn group $ + tc_val_binds gla_exts top_lvl sig_fn prag_fn groups thing_inside ; return (group' ++ groups', thing) } ------------------------ -tc_group :: TopLevelFlag -> TcSigFun -> TcPragFun +tc_group :: Bool -> TopLevelFlag -> TcSigFun -> TcPragFun -> (RecFlag, LHsBinds Name) -> TcM thing -> TcM ([(RecFlag, LHsBinds TcId)], thing) @@ -213,41 +213,60 @@ tc_group :: TopLevelFlag -> TcSigFun -> TcPragFun -- We get a list of groups back, because there may -- be specialisations etc as well -tc_group top_lvl sig_fn prag_fn (NonRecursive, binds) thing_inside - = -- A single non-recursive binding +tc_group gla_exts top_lvl sig_fn prag_fn (NonRecursive, binds) thing_inside + -- A single non-recursive binding -- We want to keep non-recursive things non-recursive -- so that we desugar unlifted bindings correctly - do { (binds, thing) <- tcPolyBinds top_lvl NonRecursive NonRecursive - sig_fn prag_fn binds thing_inside + = do { (binds, thing) <- tc_haskell98 top_lvl sig_fn prag_fn NonRecursive binds thing_inside ; return ([(NonRecursive, b) | b <- binds], thing) } -tc_group top_lvl sig_fn prag_fn (Recursive, binds) thing_inside - = -- A recursive strongly-connected component - -- To maximise polymorphism (with -fglasgow-exts), we do a new +tc_group gla_exts top_lvl sig_fn prag_fn (Recursive, binds) thing_inside + | not gla_exts -- Recursive group, normal Haskell 98 route + = do { (binds1, thing) <- tc_haskell98 top_lvl sig_fn prag_fn Recursive binds thing_inside + ; return ([(Recursive, unionManyBags binds1)], thing) } + + | otherwise -- Recursive group, with gla-exts + = -- To maximise polymorphism (with -fglasgow-exts), we do a new -- strongly-connected-component analysis, this time omitting -- any references to variables with type signatures. -- - -- Then we bring into scope all the variables with type signatures + -- Notice that the bindInsts thing covers *all* the bindings in the original + -- group at once; an earlier one may use a later one! do { traceTc (text "tc_group rec" <+> pprLHsBinds binds) - ; gla_exts <- doptM Opt_GlasgowExts - ; (binds,thing) <- if gla_exts - then go new_sccs - else tc_binds Recursive binds thing_inside - ; return ([(Recursive, unionManyBags binds)], thing) } + ; (binds1,thing) <- bindLocalInsts top_lvl $ + go (stronglyConnComp (mkEdges sig_fn binds)) + ; return ([(Recursive, unionManyBags binds1)], thing) } -- Rec them all together where - new_sccs :: [SCC (LHsBind Name)] - new_sccs = stronglyConnComp (mkEdges sig_fn binds) +-- go :: SCC (LHsBind Name) -> TcM ([LHsBind TcId], [TcId], thing) + go (scc:sccs) = do { (binds1, ids1) <- tc_scc scc + ; (binds2, ids2, thing) <- tcExtendIdEnv ids1 $ go sccs + ; return (binds1 ++ binds2, ids1 ++ ids2, thing) } + go [] = do { thing <- thing_inside; return ([], [], thing) } --- go :: SCC (LHsBind Name) -> TcM ([LHsBind TcId], thing) - go (scc:sccs) = do { (binds1, (binds2, thing)) <- go1 scc (go sccs) - ; return (binds1 ++ binds2, thing) } - go [] = do { thing <- thing_inside; return ([], thing) } + tc_scc (AcyclicSCC bind) = tc_sub_group NonRecursive (unitBag bind) + tc_scc (CyclicSCC binds) = tc_sub_group Recursive (listToBag binds) - go1 (AcyclicSCC bind) = tc_binds NonRecursive (unitBag bind) - go1 (CyclicSCC binds) = tc_binds Recursive (listToBag binds) + tc_sub_group = tcPolyBinds top_lvl sig_fn prag_fn Recursive - tc_binds rec_tc binds = tcPolyBinds top_lvl Recursive rec_tc sig_fn prag_fn binds +tc_haskell98 top_lvl sig_fn prag_fn rec_flag binds thing_inside + = bindLocalInsts top_lvl $ do + { (binds1, ids) <- tcPolyBinds top_lvl sig_fn prag_fn rec_flag rec_flag binds + ; thing <- tcExtendIdEnv ids thing_inside + ; return (binds1, ids, thing) } + +------------------------ +bindLocalInsts :: TopLevelFlag -> TcM ([LHsBinds TcId], [TcId], a) -> TcM ([LHsBinds TcId], a) +bindLocalInsts top_lvl thing_inside + | isTopLevel top_lvl = do { (binds, ids, thing) <- thing_inside; return (binds, thing) } + -- For the top level don't bother will all this bindInstsOfLocalFuns stuff. + -- All the top level things are rec'd together anyway, so it's fine to + -- leave them to the tcSimplifyTop, and quite a bit faster too + + | otherwise -- Nested case + = do { ((binds, ids, thing), lie) <- getLIE thing_inside + ; lie_binds <- bindInstsOfLocalFuns lie ids + ; return (binds ++ [lie_binds], thing) } ------------------------ mkEdges :: TcSigFun -> LHsBinds Name @@ -275,69 +294,34 @@ bindersOfHsBind (PatBind { pat_lhs = pat }) = collectPatBinders pat bindersOfHsBind (FunBind { fun_id = L _ f }) = [f] ------------------------ -tcPolyBinds :: TopLevelFlag +tcPolyBinds :: TopLevelFlag -> TcSigFun -> TcPragFun -> RecFlag -- Whether the group is really recursive - -> RecFlag -- Whether it's recursive for typechecking purposes - -> TcSigFun -> TcPragFun + -> RecFlag -- Whether it's recursive after breaking + -- dependencies based on type signatures -> LHsBinds Name - -> TcM thing - -> TcM ([LHsBinds TcId], thing) + -> TcM ([LHsBinds TcId], [TcId]) -- Typechecks a single bunch of bindings all together, -- and generalises them. The bunch may be only part of a recursive -- group, because we use type signatures to maximise polymorphism -- --- Deals with the bindInstsOfLocalFuns thing too --- -- Returns a list because the input may be a single non-recursive binding, -- in which case the dependency order of the resulting bindings is -- important. - -tcPolyBinds top_lvl rec_group rec_tc sig_fn prag_fn scc thing_inside - = -- NB: polymorphic recursion means that a function - -- may use an instance of itself, we must look at the LIE arising - -- from the function's own right hand side. Hence the getLIE - -- encloses the tc_poly_binds. - do { traceTc (text "tcPolyBinds" <+> ppr scc) - ; ((binds1, poly_ids, thing), lie) <- getLIE $ - do { (binds1, poly_ids) <- tc_poly_binds top_lvl rec_group rec_tc - sig_fn prag_fn scc - ; thing <- tcExtendIdEnv poly_ids thing_inside - ; return (binds1, poly_ids, thing) } - - ; if isTopLevel top_lvl - then -- For the top level don't bother will all this - -- bindInstsOfLocalFuns stuff. All the top level - -- things are rec'd together anyway, so it's fine to - -- leave them to the tcSimplifyTop, - -- and quite a bit faster too - do { extendLIEs lie; return (binds1, thing) } - - else do -- Nested case - { lie_binds <- bindInstsOfLocalFuns lie poly_ids - ; return (binds1 ++ [lie_binds], thing) }} - ------------------------- -tc_poly_binds :: TopLevelFlag -- See comments on tcPolyBinds - -> RecFlag -> RecFlag - -> TcSigFun -> TcPragFun - -> LHsBinds Name - -> TcM ([LHsBinds TcId], [TcId]) --- Typechecks the bindings themselves +-- -- Knows nothing about the scope of the bindings -tc_poly_binds top_lvl rec_group rec_tc sig_fn prag_fn binds +tcPolyBinds top_lvl sig_fn prag_fn rec_group rec_tc binds = let - binder_names = collectHsBindBinders binds bind_list = bagToList binds - - loc = getLoc (head bind_list) + binder_names = collectHsBindBinders binds + loc = getLoc (head bind_list) -- TODO: location a bit awkward, but the mbinds have been -- dependency analysed and may no longer be adjacent in -- SET UP THE MAIN RECOVERY; take advantage of any type sigs setSrcSpan loc $ - recoverM (recoveryCode binder_names) $ do + recoverM (recoveryCode binder_names sig_fn) $ do { traceTc (ptext SLIT("------------------------------------------------")) ; traceTc (ptext SLIT("Bindings for") <+> ppr binder_names) @@ -363,10 +347,10 @@ tc_poly_binds top_lvl rec_group rec_tc sig_fn prag_fn binds [poly_id | (_, poly_id, _, _) <- exports]) } -- Guaranteed zonked else do -- The normal lifted case: GENERALISE - { is_unres <- isUnRestrictedGroup bind_list sig_fn + { dflags <- getDOpts ; (tyvars_to_gen, dict_binds, dict_ids) <- addErrCtxt (genCtxt (bndrNames mono_bind_infos)) $ - generalise top_lvl is_unres mono_bind_infos lie_req + generalise dflags top_lvl bind_list sig_fn mono_bind_infos lie_req -- FINALISE THE QUANTIFIED TYPE VARIABLES -- The quantified type variables often include meta type variables @@ -378,43 +362,47 @@ tc_poly_binds top_lvl rec_group rec_tc sig_fn prag_fn binds ; exports <- mapM (mkExport prag_fn tyvars_to_gen' (map idType dict_ids)) mono_bind_infos - -- ZONK THE poly_ids, because they are used to extend the type - -- environment; see the invariant on TcEnv.tcExtendIdEnv ; let poly_ids = [poly_id | (_, poly_id, _, _) <- exports] - ; zonked_poly_ids <- mappM zonkId poly_ids - - ; traceTc (text "binding:" <+> ppr (zonked_poly_ids `zip` map idType zonked_poly_ids)) + ; traceTc (text "binding:" <+> ppr (poly_ids `zip` map idType poly_ids)) ; let abs_bind = L loc $ AbsBinds tyvars_to_gen' dict_ids exports (dict_binds `unionBags` binds') - ; return ([unitBag abs_bind], zonked_poly_ids) + ; return ([unitBag abs_bind], poly_ids) -- poly_ids are guaranteed zonked by mkExport } } -------------- mkExport :: TcPragFun -> [TyVar] -> [TcType] -> MonoBindInfo -> TcM ([TyVar], Id, Id, [Prag]) +-- mkExport generates exports with +-- zonked type variables, +-- zonked poly_ids +-- The former is just because no further unifications will change +-- the quantified type variables, so we can fix their final form +-- right now. +-- The latter is needed because the poly_ids are used to extend the +-- type environment; see the invariant on TcEnv.tcExtendIdEnv + +-- Pre-condition: the inferred_tvs are already zonked + mkExport prag_fn inferred_tvs dict_tys (poly_name, mb_sig, mono_id) - = case mb_sig of - Nothing -> do { prags <- tcPrags poly_id (prag_fn poly_name) - ; return (inferred_tvs, poly_id, mono_id, prags) } - where - poly_id = mkLocalId poly_name poly_ty - poly_ty = mkForAllTys inferred_tvs - $ mkFunTys dict_tys - $ idType mono_id - - Just sig -> do { let poly_id = sig_id sig - ; prags <- tcPrags poly_id (prag_fn poly_name) - ; sig_tys <- zonkTcTyVars (sig_tvs sig) - ; let sig_tvs' = map (tcGetTyVar "mkExport") sig_tys - ; return (sig_tvs', poly_id, mono_id, prags) } - -- We zonk the sig_tvs here so that the export triple - -- always has zonked type variables; - -- a convenient invariant + = do { (tvs, poly_id) <- mk_poly_id mb_sig + + ; poly_id' <- zonkId poly_id + ; prags <- tcPrags poly_id' (prag_fn poly_name) + -- tcPrags requires a zonked poly_id + ; return (tvs, poly_id', mono_id, prags) } + where + poly_ty = mkForAllTys inferred_tvs (mkFunTys dict_tys (idType mono_id)) + + mk_poly_id Nothing = return (inferred_tvs, mkLocalId poly_name poly_ty) + mk_poly_id (Just sig) = do { tvs <- mapM zonk_tv (sig_tvs sig) + ; return (tvs, sig_id sig) } + + zonk_tv tv = do { ty <- zonkTcTyVar tv; return (tcGetTyVar "mkExport" ty) } ------------------------ type TcPragFun = Name -> [LSig Name] @@ -437,6 +425,8 @@ tcPrags poly_id prags = mapM tc_prag prags pragSigCtxt prag = hang (ptext SLIT("In the pragma")) 2 (ppr prag) tcPrag :: TcId -> Sig Name -> TcM Prag +-- Pre-condition: the poly_id is zonked +-- Reason: required by tcSubExp tcPrag poly_id (SpecSig orig_name hs_ty inl) = tcSpecPrag poly_id hs_ty inl tcPrag poly_id (SpecInstSig hs_ty) = tcSpecPrag poly_id hs_ty defaultInlineSpec tcPrag poly_id (InlineSig v inl) = return (InlinePrag inl) @@ -448,21 +438,22 @@ tcSpecPrag poly_id hs_ty inl ; (co_fn, lie) <- getLIE (tcSubExp (idType poly_id) spec_ty) ; extendLIEs lie ; let const_dicts = map instToId lie - ; return (SpecPrag (mkHsCoerce co_fn (HsVar poly_id)) spec_ty const_dicts inl) } + ; return (SpecPrag (mkHsWrap co_fn (HsVar poly_id)) spec_ty const_dicts inl) } + -- Most of the work of specialisation is done by + -- the desugarer, guided by the SpecPrag -------------- -- If typechecking the binds fails, then return with each -- signature-less binder given type (forall a.a), to minimise -- subsequent error messages -recoveryCode binder_names +recoveryCode binder_names sig_fn = do { traceTc (text "tcBindsWithSigs: error recovery" <+> ppr binder_names) ; poly_ids <- mapM mk_dummy binder_names ; return ([], poly_ids) } where - mk_dummy name = do { mb_id <- tcLookupLocalId_maybe name - ; case mb_id of - Just id -> return id -- Had signature, was in envt - Nothing -> return (mkLocalId name forall_a_a) } -- No signature + mk_dummy name + | isJust (sig_fn name) = tcLookupId name -- Had signature; look it up + | otherwise = return (mkLocalId name forall_a_a) -- No signature forall_a_a :: TcType forall_a_a = mkForAllTy alphaTyVar (mkTyVarTy alphaTyVar) @@ -496,7 +487,8 @@ checkStrictBinds top_lvl rec_group mbind mono_tys infos check_sig other = return () strictBindErr flavour unlifted mbind - = hang (text flavour <+> msg <+> ptext SLIT("aren't allowed:")) 4 (ppr mbind) + = hang (text flavour <+> msg <+> ptext SLIT("aren't allowed:")) + 4 (pprLHsBinds mbind) where msg | unlifted = ptext SLIT("bindings for unlifted types") | otherwise = ptext SLIT("bang-pattern bindings") @@ -560,12 +552,12 @@ tcMonoBinds [L b_loc (FunBind { fun_id = L nm_loc name, fun_infix = inf, fun_matches = matches, bind_fvs = fvs })] sig_fn -- Single function binding non_rec - | Just sig <- sig_fn name -- ...with a type signature + | Just scoped_tvs <- sig_fn name -- ...with a type signature = -- When we have a single function binding, with a type signature -- we can (a) use genuine, rigid skolem constants for the type variables -- (b) bring (rigid) scoped type variables into scope setSrcSpan b_loc $ - do { tc_sig <- tcInstSig True sig + do { tc_sig <- tcInstSig True name scoped_tvs ; mono_name <- newLocalName name ; let mono_ty = sig_tau tc_sig mono_id = mkLocalId mono_name mono_ty @@ -628,7 +620,7 @@ getMonoType (_,_,mono_id) = idType mono_id tcLhs :: TcSigFun -> HsBind Name -> TcM TcMonoBind tcLhs sig_fn (FunBind { fun_id = L nm_loc name, fun_infix = inf, fun_matches = matches }) - = do { mb_sig <- tcInstSig_maybe (sig_fn name) + = do { mb_sig <- tcInstSig_maybe sig_fn name ; mono_name <- newLocalName name ; mono_ty <- mk_mono_ty mb_sig ; let mono_id = mkLocalId mono_name mono_ty @@ -638,15 +630,26 @@ tcLhs sig_fn (FunBind { fun_id = L nm_loc name, fun_infix = inf, fun_matches = m mk_mono_ty Nothing = newFlexiTyVarTy argTypeKind tcLhs sig_fn bind@(PatBind { pat_lhs = pat, pat_rhs = grhss }) - = do { mb_sigs <- mapM (tcInstSig_maybe . sig_fn) names + = do { mb_sigs <- mapM (tcInstSig_maybe sig_fn) names + ; mono_pat_binds <- doptM Opt_MonoPatBinds + -- With -fmono-pat-binds, we do no generalisation of pattern bindings + -- But the signature can still be polymoprhic! + -- data T = MkT (forall a. a->a) + -- x :: forall a. a->a + -- MkT x = + -- The function get_sig_ty decides whether the pattern-bound variables + -- should have exactly the type in the type signature (-fmono-pat-binds), + -- or the instantiated version (-fmono-pat-binds) ; let nm_sig_prs = names `zip` mb_sigs - tau_sig_env = mkNameEnv [ (name, sig_tau sig) | (name, Just sig) <- nm_sig_prs] + get_sig_ty | mono_pat_binds = idType . sig_id + | otherwise = sig_tau + tau_sig_env = mkNameEnv [ (name, get_sig_ty sig) + | (name, Just sig) <- nm_sig_prs] sig_tau_fn = lookupNameEnv tau_sig_env - tc_pat exp_ty = tcPat (LetPat sig_tau_fn) pat exp_ty unitTy $ \ _ -> + tc_pat exp_ty = tcLetPat sig_tau_fn pat exp_ty $ mapM lookup_info nm_sig_prs - -- The unitTy is a bit bogus; it's the "result type" for lookup_info. -- After typechecking the pattern, look up the binder -- names, which the pattern has brought into scope. @@ -697,11 +700,15 @@ getMonoBindInfo tc_binds %************************************************************************ \begin{code} -generalise :: TopLevelFlag -> Bool +generalise :: DynFlags -> TopLevelFlag + -> [LHsBind Name] -> TcSigFun -> [MonoBindInfo] -> [Inst] -> TcM ([TcTyVar], TcDictBinds, [TcId]) -generalise top_lvl is_unrestricted mono_infos lie_req - | not is_unrestricted -- RESTRICTED CASE +generalise dflags top_lvl bind_list sig_fn mono_infos lie_req + | isMonoGroup dflags bind_list + = do { extendLIEs lie_req; return ([], emptyBag, []) } + + | isRestrictedGroup dflags bind_list sig_fn -- RESTRICTED CASE = -- Check signature contexts are empty do { checkTc (all is_mono_sig sigs) (restrictedBindCtxtErr bndrs) @@ -765,7 +772,7 @@ might not otherwise be related. This is a rather subtle issue. unifyCtxts :: [TcSigInfo] -> TcM [Inst] unifyCtxts (sig1 : sigs) -- Argument is always non-empty = do { mapM unify_ctxt sigs - ; newDictsAtLoc (sig_loc sig1) (sig_theta sig1) } + ; newDictBndrs (sig_loc sig1) (sig_theta sig1) } where theta1 = sig_theta sig1 unify_ctxt :: TcSigInfo -> TcM () @@ -954,15 +961,23 @@ the variable's type, and after that checked to see whether they've been instantiated. \begin{code} -type TcSigFun = Name -> Maybe (LSig Name) +type TcSigFun = Name -> Maybe [Name] -- Maps a let-binder to the list of + -- type variables brought into scope + -- by its type signature. + -- Nothing => no type signature -mkSigFun :: [LSig Name] -> TcSigFun +mkTcSigFun :: [LSig Name] -> TcSigFun -- Search for a particular type signature -- Precondition: the sigs are all type sigs -- Precondition: no duplicates -mkSigFun sigs = lookupNameEnv env +mkTcSigFun sigs = lookupNameEnv env where - env = mkNameEnv [(expectJust "mkSigFun" (sigName sig), sig) | sig <- sigs] + env = mkNameEnv [(name, hsExplicitTvs lhs_ty) + | L span (TypeSig (L _ name) lhs_ty) <- sigs] + -- The scoped names are the ones explicitly mentioned + -- in the HsForAll. (There may be more in sigma_ty, because + -- of nested type synonyms. See Note [Scoped] with TcSigInfo.) + -- See Note [Only scoped tyvars are in the TyVarEnv] --------------- data TcSigInfo @@ -981,6 +996,19 @@ data TcSigInfo sig_loc :: InstLoc -- The location of the signature } + +-- Note [Only scoped tyvars are in the TyVarEnv] +-- We are careful to keep only the *lexically scoped* type variables in +-- the type environment. Why? After all, the renamer has ensured +-- that only legal occurrences occur, so we could put all type variables +-- into the type env. +-- +-- But we want to check that two distinct lexically scoped type variables +-- do not map to the same internal type variable. So we need to know which +-- the lexically-scoped ones are... and at the moment we do that by putting +-- only the lexically scoped ones into the environment. + + -- Note [Scoped] -- There may be more instantiated type variables than scoped -- ones. For example: @@ -993,7 +1021,7 @@ data TcSigInfo -- and remember the names from the original HsForAllTy in sig_scoped -- Note [Instantiate sig] --- It's vital to instantiate a type signature with fresh variable. +-- It's vital to instantiate a type signature with fresh variables. -- For example: -- type S = forall a. a->a -- f,g :: S @@ -1016,18 +1044,26 @@ tcTySig (L span (TypeSig (L _ name) ty)) ; return (mkLocalId name sigma_ty) } ------------------- -tcInstSig_maybe :: Maybe (LSig Name) -> TcM (Maybe TcSigInfo) +tcInstSig_maybe :: TcSigFun -> Name -> TcM (Maybe TcSigInfo) -- Instantiate with *meta* type variables; -- this signature is part of a multi-signature group -tcInstSig_maybe Nothing = return Nothing -tcInstSig_maybe (Just sig) = do { tc_sig <- tcInstSig False sig - ; return (Just tc_sig) } +tcInstSig_maybe sig_fn name + = case sig_fn name of + Nothing -> return Nothing + Just tvs -> do { tc_sig <- tcInstSig False name tvs + ; return (Just tc_sig) } -tcInstSig :: Bool -> LSig Name -> TcM TcSigInfo +tcInstSig :: Bool -> Name -> [Name] -> TcM TcSigInfo -- Instantiate the signature, with either skolems or meta-type variables --- depending on the use_skols boolean +-- depending on the use_skols boolean. This variable is set True +-- when we are typechecking a single function binding; and False for +-- pattern bindings and a group of several function bindings. +-- Reason: in the latter cases, the "skolems" can be unified together, +-- so they aren't properly rigid in the type-refinement sense. +-- NB: unless we are doing H98, each function with a sig will be done +-- separately, even if it's mutually recursive, so use_skols will be True -- --- We always instantiate with freshs uniques, +-- We always instantiate with fresh uniques, -- although we keep the same print-name -- -- type T = forall a. [a] -> [a] @@ -1036,9 +1072,8 @@ tcInstSig :: Bool -> LSig Name -> TcM TcSigInfo -- -- We must not use the same 'a' from the defn of T at both places!! -tcInstSig use_skols (L loc (TypeSig (L _ name) hs_ty)) - = setSrcSpan loc $ - do { poly_id <- tcLookupId name -- Cannot fail; the poly ids are put into +tcInstSig use_skols name scoped_names + = do { poly_id <- tcLookupId name -- Cannot fail; the poly ids are put into -- scope when starting the binding group ; let skol_info = SigSkol (FunSigCtxt name) inst_tyvars | use_skols = tcInstSkolTyVars skol_info @@ -1047,26 +1082,31 @@ tcInstSig use_skols (L loc (TypeSig (L _ name) hs_ty)) ; loc <- getInstLoc (SigOrigin skol_info) ; return (TcSigInfo { sig_id = poly_id, sig_tvs = tvs, sig_theta = theta, sig_tau = tau, - sig_scoped = scoped_names, sig_loc = loc }) } + sig_scoped = final_scoped_names, sig_loc = loc }) } -- Note that the scoped_names and the sig_tvs will have -- different Names. That's quite ok; when we bring the -- scoped_names into scope, we just bind them to the sig_tvs where - -- The scoped names are the ones explicitly mentioned - -- in the HsForAll. (There may be more in sigma_ty, because - -- of nested type synonyms. See Note [Scoped] with TcSigInfo.) -- We also only have scoped type variables when we are instantiating -- with true skolems - scoped_names = case (use_skols, hs_ty) of - (True, L _ (HsForAllTy Explicit tvs _ _)) -> hsLTyVarNames tvs - other -> [] + final_scoped_names | use_skols = scoped_names + | otherwise = [] + +------------------- +isMonoGroup :: DynFlags -> [LHsBind Name] -> Bool +-- No generalisation at all +isMonoGroup dflags binds + = dopt Opt_MonoPatBinds dflags && any is_pat_bind binds + where + is_pat_bind (L _ (PatBind {})) = True + is_pat_bind other = False ------------------- -isUnRestrictedGroup :: [LHsBind Name] -> TcSigFun -> TcM Bool -isUnRestrictedGroup binds sig_fn - = do { mono_restriction <- doptM Opt_MonomorphismRestriction - ; return (not mono_restriction || all_unrestricted) } +isRestrictedGroup :: DynFlags -> [LHsBind Name] -> TcSigFun -> Bool +isRestrictedGroup dflags binds sig_fn + = mono_restriction && not all_unrestricted where + mono_restriction = dopt Opt_MonomorphismRestriction dflags all_unrestricted = all (unrestricted . unLoc) binds has_sig n = isJust (sig_fn n)