summaryrefslogtreecommitdiff
path: root/compiler/iface/TcIface.hs
diff options
context:
space:
mode:
authorKavon Farvardin <kavon@farvard.in>2018-09-23 15:29:37 -0500
committerKavon Farvardin <kavon@farvard.in>2018-09-23 15:29:37 -0500
commit84c2ad99582391005b5e873198b15e9e9eb4f78d (patch)
treecaa8c2f2ec7e97fbb4977263c6817c9af5025cf4 /compiler/iface/TcIface.hs
parent8ddb47cfcf5776e9a3c55fd37947c8a95e00fa12 (diff)
parente68b439fe5de61b9a2ca51af472185c62ccb8b46 (diff)
downloadhaskell-wip/T13904.tar.gz
update to current master againwip/T13904
Diffstat (limited to 'compiler/iface/TcIface.hs')
-rw-r--r--compiler/iface/TcIface.hs379
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)