diff options
author | Kavon Farvardin <kavon@farvard.in> | 2018-09-23 15:29:37 -0500 |
---|---|---|
committer | Kavon Farvardin <kavon@farvard.in> | 2018-09-23 15:29:37 -0500 |
commit | 84c2ad99582391005b5e873198b15e9e9eb4f78d (patch) | |
tree | caa8c2f2ec7e97fbb4977263c6817c9af5025cf4 /compiler/iface/TcIface.hs | |
parent | 8ddb47cfcf5776e9a3c55fd37947c8a95e00fa12 (diff) | |
parent | e68b439fe5de61b9a2ca51af472185c62ccb8b46 (diff) | |
download | haskell-wip/T13904.tar.gz |
update to current master againwip/T13904
Diffstat (limited to 'compiler/iface/TcIface.hs')
-rw-r--r-- | compiler/iface/TcIface.hs | 379 |
1 files changed, 156 insertions, 223 deletions
diff --git a/compiler/iface/TcIface.hs b/compiler/iface/TcIface.hs index 1477f462fc..248f7d3c38 100644 --- a/compiler/iface/TcIface.hs +++ b/compiler/iface/TcIface.hs @@ -15,13 +15,15 @@ module TcIface ( typecheckIfacesForMerging, typecheckIfaceForInstantiate, tcIfaceDecl, tcIfaceInst, tcIfaceFamInst, tcIfaceRules, - tcIfaceVectInfo, tcIfaceAnnotations, tcIfaceCompleteSigs, + tcIfaceAnnotations, tcIfaceCompleteSigs, tcIfaceExpr, -- Desired by HERMIT (Trac #7683) tcIfaceGlobal ) where #include "HsVersions.h" +import GhcPrelude + import TcTypeNats(typeNatCoAxiomRules) import IfaceSyn import LoadIface @@ -53,7 +55,6 @@ import PrelNames import TysWiredIn import Literal import Var -import VarEnv import VarSet import Name import NameEnv @@ -74,7 +75,6 @@ import ListSetOps import GHC.Fingerprint import qualified BooleanFormula as BF -import Data.List import Control.Monad import qualified Data.Map as Map @@ -171,9 +171,6 @@ typecheckIface iface ; rules <- tcIfaceRules ignore_prags (mi_rules iface) ; anns <- tcIfaceAnnotations (mi_anns iface) - -- Vectorisation information - ; vect_info <- tcIfaceVectInfo (mi_semantic_module iface) type_env (mi_vect_info iface) - -- Exports ; exports <- ifaceExportNames (mi_exports iface) @@ -191,7 +188,6 @@ typecheckIface iface , md_fam_insts = fam_insts , md_rules = rules , md_anns = anns - , md_vect_info = vect_info , md_exports = exports , md_complete_sigs = complete_sigs } @@ -391,7 +387,6 @@ typecheckIfacesForMerging mod ifaces tc_env_var = fam_insts <- mapM tcIfaceFamInst (mi_fam_insts iface) rules <- tcIfaceRules ignore_prags (mi_rules iface) anns <- tcIfaceAnnotations (mi_anns iface) - vect_info <- tcIfaceVectInfo (mi_semantic_module iface) type_env (mi_vect_info iface) exports <- ifaceExportNames (mi_exports iface) complete_sigs <- tcIfaceCompleteSigs (mi_complete_sigs iface) return $ ModDetails { md_types = type_env @@ -399,7 +394,6 @@ typecheckIfacesForMerging mod ifaces tc_env_var = , md_fam_insts = fam_insts , md_rules = rules , md_anns = anns - , md_vect_info = vect_info , md_exports = exports , md_complete_sigs = complete_sigs } @@ -432,7 +426,6 @@ typecheckIfaceForInstantiate nsubst iface = fam_insts <- mapM tcIfaceFamInst (mi_fam_insts iface) rules <- tcIfaceRules ignore_prags (mi_rules iface) anns <- tcIfaceAnnotations (mi_anns iface) - vect_info <- tcIfaceVectInfo (mi_semantic_module iface) type_env (mi_vect_info iface) exports <- ifaceExportNames (mi_exports iface) complete_sigs <- tcIfaceCompleteSigs (mi_complete_sigs iface) return $ ModDetails { md_types = type_env @@ -440,7 +433,6 @@ typecheckIfaceForInstantiate nsubst iface = , md_fam_insts = fam_insts , md_rules = rules , md_anns = anns - , md_vect_info = vect_info , md_exports = exports , md_complete_sigs = complete_sigs } @@ -645,7 +637,7 @@ tc_iface_decl _ ignore_prags (IfaceId {ifName = name, ifType = iface_type, ifIdDetails = details, ifIdInfo = info}) = do { ty <- tcIfaceType iface_type ; details <- tcIdDetails ty details - ; info <- tcIdInfo ignore_prags name ty info + ; info <- tcIdInfo ignore_prags TopLevel name ty info ; return (AnId (mkGlobalId details name ty info)) } tc_iface_decl _ _ (IfaceData {ifName = tc_name, @@ -677,7 +669,7 @@ tc_iface_decl _ _ (IfaceData {ifName = tc_name, = do { ax <- tcIfaceCoAxiom ax_name ; let fam_tc = coAxiomTyCon ax ax_unbr = toUnbranchedAxiom ax - ; lhs_tys <- tcIfaceTcArgs arg_tys + ; lhs_tys <- tcIfaceAppArgs arg_tys ; return (DataFamInstTyCon ax_unbr fam_tc lhs_tys) } tc_iface_decl _ _ (IfaceSynonym {ifName = tc_name, @@ -869,10 +861,10 @@ tc_ax_branch prev_branches , ifaxbLHS = lhs, ifaxbRHS = rhs , ifaxbRoles = roles, ifaxbIncomps = incomps }) = bindIfaceTyConBinders_AT - (map (\b -> TvBndr b (NamedTCB Inferred)) tv_bndrs) $ \ tvs -> + (map (\b -> Bndr (IfaceTvBndr b) (NamedTCB Inferred)) tv_bndrs) $ \ tvs -> -- The _AT variant is needed here; see Note [CoAxBranch type variables] in CoAxiom bindIfaceIds cv_bndrs $ \ cvs -> do - { tc_lhs <- tcIfaceTcArgs lhs + { tc_lhs <- tcIfaceAppArgs lhs ; tc_rhs <- tcIfaceType rhs ; let br = CoAxBranch { cab_loc = noSrcSpan , cab_tvs = binderVars tvs @@ -892,11 +884,15 @@ tcIfaceDataCons tycon_name tycon tc_tybinders if_cons IfNewTyCon con -> do { data_con <- tc_con_decl con ; mkNewTyConRhs tycon_name tycon data_con } where - univ_tv_bndrs :: [TyVarBinder] - univ_tv_bndrs = mkDataConUnivTyVarBinders tc_tybinders + univ_tvs :: [TyVar] + univ_tvs = binderVars (tyConTyVarBinders tc_tybinders) + + tag_map :: NameEnv ConTag + tag_map = mkTyConTagMap tycon tc_con_decl (IfCon { ifConInfix = is_infix, - ifConExTvs = ex_bndrs, + ifConExTCvs = ex_bndrs, + ifConUserTvBinders = user_bndrs, ifConName = dc_name, ifConCtxt = ctxt, ifConEqSpec = spec, ifConArgTys = args, ifConFields = lbl_names, @@ -904,9 +900,23 @@ tcIfaceDataCons tycon_name tycon tc_tybinders if_cons ifConSrcStricts = if_src_stricts}) = -- Universally-quantified tyvars are shared with -- parent TyCon, and are already in scope - bindIfaceForAllBndrs ex_bndrs $ \ ex_tv_bndrs -> do + bindIfaceBndrs ex_bndrs $ \ ex_tvs -> do { traceIf (text "Start interface-file tc_con_decl" <+> ppr dc_name) + -- By this point, we have bound every universal and existential + -- tyvar. Because of the dcUserTyVarBinders invariant + -- (see Note [DataCon user type variable binders]), *every* tyvar in + -- ifConUserTvBinders has a matching counterpart somewhere in the + -- bound universals/existentials. As a result, calling tcIfaceTyVar + -- below is always guaranteed to succeed. + ; user_tv_bndrs <- mapM (\(Bndr bd vis) -> + case bd of + IfaceIdBndr (name, _) -> + Bndr <$> tcIfaceLclId name <*> pure vis + IfaceTvBndr (name, _) -> + Bndr <$> tcIfaceTyVar name <*> pure vis) + user_bndrs + -- Read the context and argument types, but lazily for two reasons -- (a) to avoid looking tugging on a recursive use of -- the type itself, which is knot-tied @@ -915,7 +925,14 @@ tcIfaceDataCons tycon_name tycon tc_tybinders if_cons ; ~(eq_spec, theta, arg_tys, stricts) <- forkM (mk_doc dc_name) $ do { eq_spec <- tcIfaceEqSpec spec ; theta <- tcIfaceCtxt ctxt - ; arg_tys <- mapM tcIfaceType args + -- This fixes #13710. The enclosing lazy thunk gets + -- forced when typechecking record wildcard pattern + -- matching (it's not completely clear why this + -- tuple is needed), which causes trouble if one of + -- the argument types was recursively defined. + -- See also Note [Tying the knot] + ; arg_tys <- forkM (mk_doc dc_name <+> text "arg_tys") + $ mapM tcIfaceType args ; stricts <- mapM tc_strict if_stricts -- The IfBang field can mention -- the type itself; hence inside forkM @@ -923,7 +940,7 @@ tcIfaceDataCons tycon_name tycon tc_tybinders if_cons -- Remember, tycon is the representation tycon ; let orig_res_ty = mkFamilyTyConApp tycon - (substTyVars (mkTvSubstPrs (map eqSpecPair eq_spec)) + (substTyCoVars (mkTvSubstPrs (map eqSpecPair eq_spec)) (binderVars tc_tybinders)) ; prom_rep_name <- newTyConRepName dc_name @@ -938,9 +955,9 @@ tcIfaceDataCons tycon_name tycon tc_tybinders if_cons -- worker. -- See Note [Bangs on imported data constructors] in MkId lbl_names - univ_tv_bndrs ex_tv_bndrs + univ_tvs ex_tvs user_tv_bndrs eq_spec theta - arg_tys orig_res_ty tycon + arg_tys orig_res_ty tycon tag_map ; traceIf (text "Done interface-file tc_con_decl" <+> ppr dc_name) ; return con } mk_doc con_name = text "Constructor" <+> ppr con_name @@ -1060,7 +1077,7 @@ tcIfaceRule (IfaceRule {ifRuleName = name, ifActivation = act, ifRuleBndrs = bnd -- to write them out in coreRuleToIfaceRule ifTopFreeName :: IfaceExpr -> Maybe Name ifTopFreeName (IfaceType (IfaceTyConApp tc _ )) = Just (ifaceTyConName tc) - ifTopFreeName (IfaceType (IfaceTupleTy s _ ts)) = Just (tupleTyConName s (length (tcArgsIfaceTypes ts))) + ifTopFreeName (IfaceType (IfaceTupleTy s _ ts)) = Just (tupleTyConName s (length (appArgsIfaceTypes ts))) ifTopFreeName (IfaceApp f _) = ifTopFreeName f ifTopFreeName (IfaceExt n) = Just n ifTopFreeName _ = Nothing @@ -1108,134 +1125,6 @@ tcIfaceCompleteSig (IfaceCompleteMatch ms t) = return (CompleteMatch ms t) {- ************************************************************************ * * - Vectorisation information -* * -************************************************************************ --} - --- We need access to the type environment as we need to look up information about type constructors --- (i.e., their data constructors and whether they are class type constructors). If a vectorised --- type constructor or class is defined in the same module as where it is vectorised, we cannot --- look that information up from the type constructor that we obtained via a 'forkM'ed --- 'tcIfaceTyCon' without recursively loading the interface that we are already type checking again --- and again and again... --- -tcIfaceVectInfo :: Module -> TypeEnv -> IfaceVectInfo -> IfL VectInfo -tcIfaceVectInfo mod typeEnv (IfaceVectInfo - { ifaceVectInfoVar = vars - , ifaceVectInfoTyCon = tycons - , ifaceVectInfoTyConReuse = tyconsReuse - , ifaceVectInfoParallelVars = parallelVars - , ifaceVectInfoParallelTyCons = parallelTyCons - }) - = do { let parallelTyConsSet = mkNameSet parallelTyCons - ; vVars <- mapM vectVarMapping vars - ; let varsSet = mkVarSet (map fst vVars) - ; tyConRes1 <- mapM (vectTyConVectMapping varsSet) tycons - ; tyConRes2 <- mapM (vectTyConReuseMapping varsSet) tyconsReuse - ; vParallelVars <- mapM vectVar parallelVars - ; let (vTyCons, vDataCons, vScSels) = unzip3 (tyConRes1 ++ tyConRes2) - ; return $ VectInfo - { vectInfoVar = mkDVarEnv vVars `extendDVarEnvList` concat vScSels - , vectInfoTyCon = mkNameEnv vTyCons - , vectInfoDataCon = mkNameEnv (concat vDataCons) - , vectInfoParallelVars = mkDVarSet vParallelVars - , vectInfoParallelTyCons = parallelTyConsSet - } - } - where - vectVarMapping name - = do { vName <- lookupIfaceTop (mkLocalisedOccName mod mkVectOcc name) - ; var <- forkM (text "vect var" <+> ppr name) $ - tcIfaceExtId name - ; vVar <- forkM (text "vect vVar [mod =" <+> - ppr mod <> text "; nameModule =" <+> - ppr (nameModule name) <> text "]" <+> ppr vName) $ - tcIfaceExtId vName - ; return (var, (var, vVar)) - } - -- where - -- lookupLocalOrExternalId name - -- = do { let mb_id = lookupTypeEnv typeEnv name - -- ; case mb_id of - -- -- id is local - -- Just (AnId id) -> return id - -- -- name is not an Id => internal inconsistency - -- Just _ -> notAnIdErr - -- -- Id is external - -- Nothing -> tcIfaceExtId name - -- } - -- - -- notAnIdErr = pprPanic "TcIface.tcIfaceVectInfo: not an id" (ppr name) - - vectVar name - = forkM (text "vect scalar var" <+> ppr name) $ - tcIfaceExtId name - - vectTyConVectMapping vars name - = do { vName <- lookupIfaceTop (mkLocalisedOccName mod mkVectTyConOcc name) - ; vectTyConMapping vars name vName - } - - vectTyConReuseMapping vars name - = vectTyConMapping vars name name - - vectTyConMapping vars name vName - = do { tycon <- lookupLocalOrExternalTyCon name - ; vTycon <- forkM (text "vTycon of" <+> ppr vName) $ - lookupLocalOrExternalTyCon vName - - -- Map the data constructors of the original type constructor to those of the - -- vectorised type constructor /unless/ the type constructor was vectorised - -- abstractly; if it was vectorised abstractly, the workers of its data constructors - -- do not appear in the set of vectorised variables. - -- - -- NB: This is lazy! We don't pull at the type constructors before we actually use - -- the data constructor mapping. - ; let isAbstract | isClassTyCon tycon = False - | datacon:_ <- tyConDataCons tycon - = not $ dataConWrapId datacon `elemVarSet` vars - | otherwise = True - vDataCons | isAbstract = [] - | otherwise = [ (dataConName datacon, (datacon, vDatacon)) - | (datacon, vDatacon) <- zip (tyConDataCons tycon) - (tyConDataCons vTycon) - ] - - -- Map the (implicit) superclass and methods selectors as they don't occur in - -- the var map. - vScSels | Just cls <- tyConClass_maybe tycon - , Just vCls <- tyConClass_maybe vTycon - = [ (sel, (sel, vSel)) - | (sel, vSel) <- zip (classAllSelIds cls) (classAllSelIds vCls) - ] - | otherwise - = [] - - ; return ( (name, (tycon, vTycon)) -- (T, T_v) - , vDataCons -- list of (Ci, Ci_v) - , vScSels -- list of (seli, seli_v) - ) - } - where - -- we need a fully defined version of the type constructor to be able to extract - -- its data constructors etc. - lookupLocalOrExternalTyCon name - = do { let mb_tycon = lookupTypeEnv typeEnv name - ; case mb_tycon of - -- tycon is local - Just (ATyCon tycon) -> return tycon - -- name is not a tycon => internal inconsistency - Just _ -> notATyConErr - -- tycon is external - Nothing -> tcIfaceTyConByName name - } - - notATyConErr = pprPanic "TcIface.tcIfaceVectInfo: not a tycon" (ppr name) - -{- -************************************************************************ -* * Types * * ************************************************************************ @@ -1246,24 +1135,27 @@ tcIfaceType = go where go (IfaceTyVar n) = TyVarTy <$> tcIfaceTyVar n go (IfaceFreeTyVar n) = pprPanic "tcIfaceType:IfaceFreeTyVar" (ppr n) - go (IfaceAppTy t1 t2) = AppTy <$> go t1 <*> go t2 go (IfaceLitTy l) = LitTy <$> tcIfaceTyLit l go (IfaceFunTy t1 t2) = FunTy <$> go t1 <*> go t2 go (IfaceDFunTy t1 t2) = FunTy <$> go t1 <*> go t2 go (IfaceTupleTy s i tks) = tcIfaceTupleTy s i tks + go (IfaceAppTy t ts) + = do { t' <- go t + ; ts' <- traverse go (appArgsIfaceTypes ts) + ; pure (foldl' AppTy t' ts') } go (IfaceTyConApp tc tks) = do { tc' <- tcIfaceTyCon tc - ; tks' <- mapM go (tcArgsIfaceTypes tks) + ; tks' <- mapM go (appArgsIfaceTypes tks) ; return (mkTyConApp tc' tks') } go (IfaceForAllTy bndr t) = bindIfaceForAllBndr bndr $ \ tv' vis -> - ForAllTy (TvBndr tv' vis) <$> go t + ForAllTy (Bndr tv' vis) <$> go t go (IfaceCastTy ty co) = CastTy <$> go ty <*> tcIfaceCo co go (IfaceCoercionTy co) = CoercionTy <$> tcIfaceCo co -tcIfaceTupleTy :: TupleSort -> IsPromoted -> IfaceTcArgs -> IfL Type +tcIfaceTupleTy :: TupleSort -> IsPromoted -> IfaceAppArgs -> IfL Type tcIfaceTupleTy sort is_promoted args - = do { args' <- tcIfaceTcArgs args + = do { args' <- tcIfaceAppArgs args ; let arity = length args' ; base_tc <- tcTupleTyCon True sort arity ; case is_promoted of @@ -1290,8 +1182,8 @@ tcTupleTyCon in_type sort arity | otherwise = arity -- in expressions, we only have term args -tcIfaceTcArgs :: IfaceTcArgs -> IfL [Type] -tcIfaceTcArgs = mapM tcIfaceType . tcArgsIfaceTypes +tcIfaceAppArgs :: IfaceAppArgs -> IfL [Type] +tcIfaceAppArgs = mapM tcIfaceType . appArgsIfaceTypes ----------------------------------------- tcIfaceCtxt :: IfaceContext -> IfL ThetaType @@ -1313,13 +1205,17 @@ tcIfaceTyLit (IfaceStrTyLit n) = return (StrTyLit n) tcIfaceCo :: IfaceCoercion -> IfL Coercion tcIfaceCo = go where - go (IfaceReflCo r t) = Refl r <$> tcIfaceType t + go_mco IfaceMRefl = pure MRefl + go_mco (IfaceMCo co) = MCo <$> (go co) + + go (IfaceReflCo t) = Refl <$> tcIfaceType t + go (IfaceGReflCo r t mco) = GRefl r <$> tcIfaceType t <*> go_mco mco go (IfaceFunCo r c1 c2) = mkFunCo r <$> go c1 <*> go c2 go (IfaceTyConAppCo r tc cs) = TyConAppCo r <$> tcIfaceTyCon tc <*> mapM go cs go (IfaceAppCo c1 c2) = AppCo <$> go c1 <*> go c2 go (IfaceForAllCo tv k c) = do { k' <- go k - ; bindIfaceTyVar tv $ \ tv' -> + ; bindIfaceBndr tv $ \ tv' -> ForAllCo tv' k' <$> go c } go (IfaceCoVarCo n) = CoVarCo <$> go_var n go (IfaceAxiomInstCo n i cs) = AxiomInstCo <$> tcIfaceCoAxiom n <*> pure i <*> mapM go cs @@ -1330,31 +1226,24 @@ tcIfaceCo = go <*> go c2 go (IfaceInstCo c1 t2) = InstCo <$> go c1 <*> go t2 - go (IfaceNthCo d c) = NthCo d <$> go c + go (IfaceNthCo d c) = do { c' <- go c + ; return $ mkNthCo (nthCoRole d c') d c' } go (IfaceLRCo lr c) = LRCo lr <$> go c - go (IfaceCoherenceCo c1 c2) = CoherenceCo <$> go c1 - <*> go c2 go (IfaceKindCo c) = KindCo <$> go c go (IfaceSubCo c) = SubCo <$> go c - go (IfaceAxiomRuleCo ax cos) = AxiomRuleCo <$> go_axiom_rule ax + go (IfaceAxiomRuleCo ax cos) = AxiomRuleCo <$> tcIfaceCoAxiomRule ax <*> mapM go cos + go (IfaceFreeCoVar c) = pprPanic "tcIfaceCo:IfaceFreeCoVar" (ppr c) + go (IfaceHoleCo c) = pprPanic "tcIfaceCo:IfaceHoleCo" (ppr c) go_var :: FastString -> IfL CoVar go_var = tcIfaceLclId - go_axiom_rule :: FastString -> IfL CoAxiomRule - go_axiom_rule n = - case Map.lookup n typeNatCoAxiomRules of - Just ax -> return ax - _ -> pprPanic "go_axiom_rule" (ppr n) - tcIfaceUnivCoProv :: IfaceUnivCoProv -> IfL UnivCoProvenance tcIfaceUnivCoProv IfaceUnsafeCoerceProv = return UnsafeCoerceProv tcIfaceUnivCoProv (IfacePhantomProv kco) = PhantomProv <$> tcIfaceCo kco tcIfaceUnivCoProv (IfaceProofIrrelProv kco) = ProofIrrelProv <$> tcIfaceCo kco tcIfaceUnivCoProv (IfacePluginProv str) = return $ PluginProv str -tcIfaceUnivCoProv (IfaceHoleProv _) = - pprPanic "tcIfaceUnivCoProv" (text "holes can't occur in interface files") {- ************************************************************************ @@ -1396,7 +1285,7 @@ tcIfaceExpr (IfaceTuple sort args) ; let con_tys = map exprType args' some_con_args = map Type con_tys ++ args' con_args = case sort of - UnboxedTuple -> map (Type . getRuntimeRep "tcIfaceExpr") con_tys ++ some_con_args + UnboxedTuple -> map (Type . getRuntimeRep) con_tys ++ some_con_args _ -> some_con_args -- Put the missing type arguments back in con_id = dataConWorkId (tyConSingleDataCon tc) @@ -1440,7 +1329,7 @@ tcIfaceExpr (IfaceLet (IfaceNonRec (IfLetBndr fs ty info ji) rhs) body) = do { name <- newIfaceName (mkVarOccFS fs) ; ty' <- tcIfaceType ty ; id_info <- tcIdInfo False {- Don't ignore prags; we are inside one! -} - name ty' info + NotTopLevel name ty' info ; let id = mkLocalIdOrCoVarWithInfo name ty' id_info `asJoinId_maybe` tcJoinInfo ji ; rhs' <- tcIfaceExpr rhs @@ -1461,7 +1350,7 @@ tcIfaceExpr (IfaceLet (IfaceRec pairs) body) tc_pair (IfLetBndr _ _ info _, rhs) id = do { rhs' <- tcIfaceExpr rhs ; id_info <- tcIdInfo False {- Don't ignore prags; we are inside one! -} - (idName id) (idType id) info + NotTopLevel (idName id) (idType id) info ; return (setIdInfo id id_info, rhs') } tcIfaceExpr (IfaceTick tickish expr) = do @@ -1486,9 +1375,15 @@ tcIfaceLit :: Literal -> IfL Literal -- Integer literals deserialise to (LitInteger i <error thunk>) -- so tcIfaceLit just fills in the type. -- See Note [Integer literals] in Literal -tcIfaceLit (LitInteger i _) +tcIfaceLit (LitNumber LitNumInteger i _) = do t <- tcIfaceTyConByName integerTyConName return (mkLitInteger i (mkTyConTy t)) +-- Natural literals deserialise to (LitNatural i <error thunk>) +-- so tcIfaceLit just fills in the type. +-- See Note [Natural literals] in Literal +tcIfaceLit (LitNumber LitNumNatural i _) + = do t <- tcIfaceTyConByName naturalTyConName + return (mkLitNatural i (mkTyConTy t)) tcIfaceLit lit = return lit ------------------------- @@ -1552,8 +1447,8 @@ tcIdDetails _ (IfRecSelId tc naughty) tyThingPatSyn (AConLike (PatSynCon ps)) = ps tyThingPatSyn _ = panic "tcIdDetails: expecting patsyn" -tcIdInfo :: Bool -> Name -> Type -> IfaceIdInfo -> IfL IdInfo -tcIdInfo ignore_prags name ty info = do +tcIdInfo :: Bool -> TopLevelFlag -> Name -> Type -> IfaceIdInfo -> IfL IdInfo +tcIdInfo ignore_prags toplvl name ty info = do lcl_env <- getLclEnv -- Set the CgInfo to something sensible but uninformative before -- we start; default assumption is that it has CAFs @@ -1574,7 +1469,7 @@ tcIdInfo ignore_prags name ty info = do -- The next two are lazy, so they don't transitively suck stuff in tcPrag info (HsUnfold lb if_unf) - = do { unf <- tcUnfolding name ty info if_unf + = do { unf <- tcUnfolding toplvl name ty info if_unf ; let info1 | lb = info `setOccInfo` strongLoopBreaker | otherwise = info ; return (info1 `setUnfoldingInfo` unf) } @@ -1583,10 +1478,10 @@ tcJoinInfo :: IfaceJoinInfo -> Maybe JoinArity tcJoinInfo (IfaceJoinPoint ar) = Just ar tcJoinInfo IfaceNotJoinPoint = Nothing -tcUnfolding :: Name -> Type -> IdInfo -> IfaceUnfolding -> IfL Unfolding -tcUnfolding name _ info (IfCoreUnfold stable if_expr) +tcUnfolding :: TopLevelFlag -> Name -> Type -> IdInfo -> IfaceUnfolding -> IfL Unfolding +tcUnfolding toplvl name _ info (IfCoreUnfold stable if_expr) = do { dflags <- getDynFlags - ; mb_expr <- tcPragExpr name if_expr + ; mb_expr <- tcPragExpr toplvl name if_expr ; let unf_src | stable = InlineStable | otherwise = InlineRhs ; return $ case mb_expr of @@ -1599,21 +1494,21 @@ tcUnfolding name _ info (IfCoreUnfold stable if_expr) where -- Strictness should occur before unfolding! strict_sig = strictnessInfo info -tcUnfolding name _ _ (IfCompulsory if_expr) - = do { mb_expr <- tcPragExpr name if_expr +tcUnfolding toplvl name _ _ (IfCompulsory if_expr) + = do { mb_expr <- tcPragExpr toplvl name if_expr ; return (case mb_expr of Nothing -> NoUnfolding Just expr -> mkCompulsoryUnfolding expr) } -tcUnfolding name _ _ (IfInlineRule arity unsat_ok boring_ok if_expr) - = do { mb_expr <- tcPragExpr name if_expr +tcUnfolding toplvl name _ _ (IfInlineRule arity unsat_ok boring_ok if_expr) + = do { mb_expr <- tcPragExpr toplvl name if_expr ; return (case mb_expr of Nothing -> NoUnfolding Just expr -> mkCoreUnfolding InlineStable True expr guidance )} where guidance = UnfWhen { ug_arity = arity, ug_unsat_ok = unsat_ok, ug_boring_ok = boring_ok } -tcUnfolding name dfun_ty _ (IfDFunUnfold bs ops) +tcUnfolding _toplvl name dfun_ty _ (IfDFunUnfold bs ops) = bindIfaceBndrs bs $ \ bs' -> do { mb_ops1 <- forkM_maybe doc $ mapM tcIfaceExpr ops ; return (case mb_ops1 of @@ -1628,13 +1523,14 @@ For unfoldings we try to do the job lazily, so that we never type check an unfolding that isn't going to be looked at. -} -tcPragExpr :: Name -> IfaceExpr -> IfL (Maybe CoreExpr) -tcPragExpr name expr +tcPragExpr :: TopLevelFlag -> Name -> IfaceExpr -> IfL (Maybe CoreExpr) +tcPragExpr toplvl name expr = forkM_maybe doc $ do core_expr' <- tcIfaceExpr expr - -- Check for type consistency in the unfolding - whenGOptM Opt_DoCoreLinting $ do + -- Check for type consistency in the unfolding + -- See Note [Linting Unfoldings from Interfaces] + when (isTopLevel toplvl) $ whenGOptM Opt_DoCoreLinting $ do in_scope <- get_in_scope dflags <- getDynFlags case lintUnfolding dflags noSrcLoc in_scope core_expr' of @@ -1692,13 +1588,13 @@ tcIfaceGlobal name { type_env <- setLclEnv () get_type_env -- yuk ; case lookupNameEnv type_env name of Just thing -> return thing - Nothing -> - pprPanic "tcIfaceGlobal (local): not found" - (ifKnotErr name (if_doc env) type_env) + -- See Note [Knot-tying fallback on boot] + Nothing -> via_external } - ; _ -> do - + ; _ -> via_external }} + where + via_external = do { hsc_env <- getTopEnv ; mb_thing <- liftIO (lookupTypeHscEnv hsc_env name) ; case mb_thing of { @@ -1709,21 +1605,7 @@ tcIfaceGlobal name ; case mb_thing of Failed err -> failIfM err Succeeded thing -> return thing - }}}}} - -ifKnotErr :: Name -> SDoc -> TypeEnv -> SDoc -ifKnotErr name env_doc type_env = vcat - [ text "You are in a maze of twisty little passages, all alike." - , text "While forcing the thunk for TyThing" <+> ppr name - , text "which was lazily initialized by" <+> env_doc <> text "," - , text "I tried to tie the knot, but I couldn't find" <+> ppr name - , text "in the current type environment." - , text "If you are developing GHC, please read Note [Tying the knot]" - , text "and Note [Type-checking inside the knot]." - , text "Consider rebuilding GHC with profiling for a better stack trace." - , hang (text "Contents of current type environment:") - 2 (ppr type_env) - ] + }}} -- Note [Tying the knot] -- ~~~~~~~~~~~~~~~~~~~~~ @@ -1738,11 +1620,50 @@ ifKnotErr name env_doc type_env = vcat -- * Note [Knot-tying typecheckIface] -- * Note [DFun knot-tying] -- * Note [hsc_type_env_var hack] +-- * Note [Knot-tying fallback on boot] -- -- There is also a wiki page on the subject, see: -- -- https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/TyingTheKnot +-- Note [Knot-tying fallback on boot] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- Suppose that you are typechecking A.hs, which transitively imports, +-- via B.hs, A.hs-boot. When we poke on B.hs and discover that it +-- has a reference to a type T from A, what TyThing should we wire +-- it up with? Clearly, if we have already typechecked T and +-- added it into the type environment, we should go ahead and use that +-- type. But what if we haven't typechecked it yet? +-- +-- For the longest time, GHC adopted the policy that this was +-- *an error condition*; that you MUST NEVER poke on B.hs's reference +-- to a T defined in A.hs until A.hs has gotten around to kind-checking +-- T and adding it to the env. However, actually ensuring this is the +-- case has proven to be a bug farm, because it's really difficult to +-- actually ensure this never happens. The problem was especially poignant +-- with type family consistency checks, which eagerly happen before any +-- typechecking takes place. +-- +-- Today, we take a different strategy: if we ever try to access +-- an entity from A which doesn't exist, we just fall back on the +-- definition of A from the hs-boot file. This is complicated in +-- its own way: it means that you may end up with a mix of A.hs and +-- A.hs-boot TyThings during the course of typechecking. We don't +-- think (and have not observed) any cases where this would cause +-- problems, but the hypothetical situation one might worry about +-- is something along these lines in Core: +-- +-- case x of +-- A -> e1 +-- B -> e2 +-- +-- If, when typechecking this, we find x :: T, and the T we are hooked +-- up with is the abstract one from the hs-boot file, rather than the +-- one defined in this module with constructors A and B. But it's hard +-- to see how this could happen, especially because the reference to +-- the constructor (A and B) means that GHC will always typecheck +-- this expression *after* typechecking T. + tcIfaceTyConByName :: IfExtName -> IfL TyCon tcIfaceTyConByName name = do { thing <- tcIfaceGlobal name @@ -1759,6 +1680,16 @@ tcIfaceCoAxiom :: Name -> IfL (CoAxiom Branched) tcIfaceCoAxiom name = do { thing <- tcIfaceImplicit name ; return (tyThingCoAxiom thing) } + +tcIfaceCoAxiomRule :: IfLclName -> IfL CoAxiomRule +-- Unlike CoAxioms, which arise form user 'type instance' declarations, +-- there are a fixed set of CoAxiomRules, +-- currently enumerated in typeNatCoAxiomRules +tcIfaceCoAxiomRule n + = case Map.lookup n typeNatCoAxiomRules of + Just ax -> return ax + _ -> pprPanic "tcIfaceCoAxiomRule" (ppr n) + tcIfaceDataCon :: Name -> IfL DataCon tcIfaceDataCon name = do { thing <- tcIfaceGlobal name ; case thing of @@ -1818,16 +1749,18 @@ bindIfaceBndrs (b:bs) thing_inside thing_inside (b':bs') ----------------------- -bindIfaceForAllBndrs :: [IfaceForAllBndr] -> ([TyVarBinder] -> IfL a) -> IfL a +bindIfaceForAllBndrs :: [IfaceForAllBndr] -> ([TyCoVarBinder] -> IfL a) -> IfL a bindIfaceForAllBndrs [] thing_inside = thing_inside [] bindIfaceForAllBndrs (bndr:bndrs) thing_inside = bindIfaceForAllBndr bndr $ \tv vis -> bindIfaceForAllBndrs bndrs $ \bndrs' -> - thing_inside (mkTyVarBinder vis tv : bndrs') + thing_inside (mkTyCoVarBinder vis tv : bndrs') -bindIfaceForAllBndr :: IfaceForAllBndr -> (TyVar -> ArgFlag -> IfL a) -> IfL a -bindIfaceForAllBndr (TvBndr tv vis) thing_inside +bindIfaceForAllBndr :: IfaceForAllBndr -> (TyCoVar -> ArgFlag -> IfL a) -> IfL a +bindIfaceForAllBndr (Bndr (IfaceTvBndr tv) vis) thing_inside = bindIfaceTyVar tv $ \tv' -> thing_inside tv' vis +bindIfaceForAllBndr (Bndr (IfaceIdBndr tv) vis) thing_inside + = bindIfaceId tv $ \tv' -> thing_inside tv' vis bindIfaceTyVar :: IfaceTvBndr -> (TyVar -> IfL a) -> IfL a bindIfaceTyVar (occ,kind) thing_inside @@ -1844,8 +1777,8 @@ bindIfaceTyConBinders :: [IfaceTyConBinder] -> ([TyConBinder] -> IfL a) -> IfL a bindIfaceTyConBinders [] thing_inside = thing_inside [] bindIfaceTyConBinders (b:bs) thing_inside - = bindIfaceTyConBinderX bindIfaceTyVar b $ \ b' -> - bindIfaceTyConBinders bs $ \ bs' -> + = bindIfaceTyConBinderX bindIfaceBndr b $ \ b' -> + bindIfaceTyConBinders bs $ \ bs' -> thing_inside (b':bs') bindIfaceTyConBinders_AT :: [IfaceTyConBinder] @@ -1862,14 +1795,14 @@ bindIfaceTyConBinders_AT (b : bs) thing_inside thing_inside (b':bs') where bind_tv tv thing - = do { mb_tv <- lookupIfaceTyVar tv + = do { mb_tv <- lookupIfaceVar tv ; case mb_tv of Just b' -> thing b' - Nothing -> bindIfaceTyVar tv thing } + Nothing -> bindIfaceBndr tv thing } -bindIfaceTyConBinderX :: (IfaceTvBndr -> (TyVar -> IfL a) -> IfL a) +bindIfaceTyConBinderX :: (IfaceBndr -> (TyCoVar -> IfL a) -> IfL a) -> IfaceTyConBinder -> (TyConBinder -> IfL a) -> IfL a -bindIfaceTyConBinderX bind_tv (TvBndr tv vis) thing_inside +bindIfaceTyConBinderX bind_tv (Bndr tv vis) thing_inside = bind_tv tv $ \tv' -> - thing_inside (TvBndr tv' vis) + thing_inside (Bndr tv' vis) |