summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2012-10-26 11:14:02 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2012-10-26 11:14:02 +0100
commitec0d62c59755e232be7b91eea713d35ccaa145ee (patch)
tree849a16d6d9e48d4fc900ceada2b3f3935d710bb4
parent3406c0603e9689c0bd7d7b4b074055f0e2f29b84 (diff)
parent66ec09b7398291670914723b745fd5749eeeb15a (diff)
downloadhaskell-ec0d62c59755e232be7b91eea713d35ccaa145ee.tar.gz
Merge branch 'master' of darcs.haskell.org:/home/darcs/ghc
Conflicts: compiler/coreSyn/CoreLint.lhs
-rw-r--r--compiler/basicTypes/DataCon.lhs69
-rw-r--r--compiler/basicTypes/OccName.lhs55
-rw-r--r--compiler/coreSyn/CoreLint.lhs3
-rw-r--r--compiler/coreSyn/CoreUtils.lhs40
-rw-r--r--compiler/deSugar/DsMeta.hs132
-rw-r--r--compiler/hsSyn/HsBinds.lhs16
-rw-r--r--compiler/iface/TcIface.lhs4
-rw-r--r--compiler/main/DynFlags.hs11
-rw-r--r--compiler/prelude/PrelRules.lhs2
-rw-r--r--compiler/prelude/TysWiredIn.lhs6
-rw-r--r--compiler/rename/RnBinds.lhs49
-rw-r--r--compiler/simplCore/OccurAnal.lhs2
-rw-r--r--compiler/simplCore/Simplify.lhs2
-rw-r--r--compiler/typecheck/Inst.lhs30
-rw-r--r--compiler/typecheck/TcCanonical.lhs78
-rw-r--r--compiler/typecheck/TcErrors.lhs28
-rw-r--r--compiler/typecheck/TcExpr.lhs3
-rw-r--r--compiler/typecheck/TcHsType.lhs155
-rw-r--r--compiler/typecheck/TcInteract.lhs80
-rw-r--r--compiler/typecheck/TcMType.lhs13
-rw-r--r--compiler/typecheck/TcRnDriver.lhs10
-rw-r--r--compiler/typecheck/TcRnTypes.lhs16
-rw-r--r--compiler/typecheck/TcSMonad.lhs4
-rw-r--r--compiler/typecheck/TcSimplify.lhs293
-rw-r--r--compiler/typecheck/TcSplice.lhs16
-rw-r--r--compiler/typecheck/TcSplice.lhs-boot2
-rw-r--r--compiler/typecheck/TcTyClsDecls.lhs34
-rw-r--r--compiler/typecheck/TcType.lhs110
-rw-r--r--compiler/typecheck/TcUnify.lhs148
-rw-r--r--compiler/types/Kind.lhs2
-rw-r--r--compiler/types/TyCon.lhs2
-rw-r--r--mk/validate-settings.mk10
32 files changed, 787 insertions, 638 deletions
diff --git a/compiler/basicTypes/DataCon.lhs b/compiler/basicTypes/DataCon.lhs
index a504c5bbe7..6b918dbc08 100644
--- a/compiler/basicTypes/DataCon.lhs
+++ b/compiler/basicTypes/DataCon.lhs
@@ -45,8 +45,8 @@ module DataCon (
deepSplitProductType_maybe,
-- ** Promotion related functions
- promoteType, isPromotableType, isPromotableTyCon,
- buildPromotedTyCon, buildPromotedDataCon,
+ isPromotableTyCon, promoteTyCon,
+ promoteDataCon, promoteDataCon_maybe
) where
#include "HsVersions.h"
@@ -386,9 +386,11 @@ data DataCon
-- An entirely separate wrapper function is built in TcTyDecls
dcIds :: DataConIds,
- dcInfix :: Bool -- True <=> declared infix
+ dcInfix :: Bool, -- True <=> declared infix
-- Used for Template Haskell and 'deriving' only
-- The actual fixity is stored elsewhere
+
+ dcPromoted :: Maybe TyCon -- The promoted TyCon if this DataCon is promotable
}
deriving Data.Typeable.Typeable
@@ -519,10 +521,7 @@ mkDataCon name declared_infix
-- so the error is detected properly... it's just that asaertions here
-- are a little dodgy.
- = -- ASSERT( not (any isEqPred theta) )
- -- We don't currently allow any equality predicates on
- -- a data constructor (apart from the GADT ones in eq_spec)
- con
+ = con
where
is_vanilla = null ex_tvs && null eq_spec && null theta
con = MkData {dcName = name, dcUnique = nameUnique name,
@@ -537,7 +536,8 @@ mkDataCon name declared_infix
dcStrictMarks = arg_stricts,
dcRepStrictness = rep_arg_stricts,
dcFields = fields, dcTag = tag, dcRepType = ty,
- dcIds = ids }
+ dcIds = ids,
+ dcPromoted = mb_promoted }
-- Strictness marks for source-args
-- *after unboxing choices*,
@@ -559,6 +559,16 @@ mkDataCon name declared_infix
mkFunTys rep_arg_tys $
mkTyConApp rep_tycon (mkTyVarTys univ_tvs)
+ mb_promoted
+ | is_vanilla -- No existentials or context
+ , all (isLiftedTypeKind . tyVarKind) univ_tvs
+ , all isPromotableType orig_arg_tys
+ = Just (mkPromotedDataCon con name (getUnique name) prom_kind arity)
+ | otherwise
+ = Nothing
+ prom_kind = promoteType (dataConUserType con)
+ arity = dataConSourceArity con
+
eqSpecPreds :: [(TyVar,Type)] -> ThetaType
eqSpecPreds spec = [ mkEqPred (mkTyVarTy tv) ty | (tv,ty) <- spec ]
@@ -978,24 +988,22 @@ computeRep stricts tys
%* *
%************************************************************************
-These two 'buildPromoted..' functions are here because
+These two 'promoted..' functions are here because
* They belong together
- * 'buildPromotedTyCon' is used by promoteType
- * 'buildPromotedTyCon' depends on DataCon stuff
+ * 'promoteTyCon' is used by promoteType
+ * 'prmoteDataCon' depends on DataCon stuff
\begin{code}
-buildPromotedTyCon :: TyCon -> TyCon
-buildPromotedTyCon tc
- = mkPromotedTyCon tc (promoteKind (tyConKind tc))
+promoteDataCon :: DataCon -> TyCon
+promoteDataCon (MkData { dcPromoted = Just tc }) = tc
+promoteDataCon dc = pprPanic "promoteDataCon" (ppr dc)
+
+promoteDataCon_maybe :: DataCon -> Maybe TyCon
+promoteDataCon_maybe (MkData { dcPromoted = mb_tc }) = mb_tc
-buildPromotedDataCon :: DataCon -> TyCon
-buildPromotedDataCon dc
- = ASSERT ( isPromotableType ty )
- mkPromotedDataCon dc (getName dc) (getUnique dc) kind arity
- where
- ty = dataConUserType dc
- kind = promoteType ty
- arity = dataConSourceArity dc
+promoteTyCon :: TyCon -> TyCon
+promoteTyCon tc
+ = mkPromotedTyCon tc (promoteKind (tyConKind tc))
\end{code}
Note [Promoting a Type to a Kind]
@@ -1017,16 +1025,11 @@ The transformation from type to kind is done by promoteType
\begin{code}
isPromotableType :: Type -> Bool
-isPromotableType ty
- = all (isLiftedTypeKind . tyVarKind) tvs
- && go rho
- where
- (tvs, rho) = splitForAllTys ty
- go (TyConApp tc tys) | Just n <- isPromotableTyCon tc
- = tys `lengthIs` n && all go tys
- go (FunTy arg res) = go arg && go res
- go (TyVarTy tvar) = tvar `elem` tvs
- go _ = False
+isPromotableType (TyConApp tc tys)
+ | Just n <- isPromotableTyCon tc = tys `lengthIs` n && all isPromotableType tys
+isPromotableType (FunTy arg res) = isPromotableType arg && isPromotableType res
+isPromotableType (TyVarTy {}) = True
+isPromotableType _ = False
-- If tc's kind is [ *^n -> * ] returns [ Just n ], else returns [ Nothing ]
isPromotableTyCon :: TyCon -> Maybe Int
@@ -1048,7 +1051,7 @@ promoteType ty
kvs = [ mkKindVar (tyVarName tv) superKind | tv <- tvs ]
env = zipVarEnv tvs kvs
- go (TyConApp tc tys) = mkTyConApp (buildPromotedTyCon tc) (map go tys)
+ go (TyConApp tc tys) = mkTyConApp (promoteTyCon tc) (map go tys)
go (FunTy arg res) = mkArrowKind (go arg) (go res)
go (TyVarTy tv) | Just kv <- lookupVarEnv env tv
= TyVarTy kv
diff --git a/compiler/basicTypes/OccName.lhs b/compiler/basicTypes/OccName.lhs
index 6c70dc597a..afdde7c996 100644
--- a/compiler/basicTypes/OccName.lhs
+++ b/compiler/basicTypes/OccName.lhs
@@ -758,29 +758,54 @@ There's a wrinkle for operators. Consider '>>='. We can't use '>>=1'
because that isn't a single lexeme. So we encode it to 'lle' and *then*
tack on the '1', if necessary.
+Note [TidyOccEnv]
+~~~~~~~~~~~~~~~~~
+type TidyOccEnv = UniqFM Int
+
+* Domain = The OccName's FastString. These FastStrings are "taken";
+ make sure that we don't re-use
+
+* Int, n = A plausible starting point for new guesses
+ There is no guarantee that "FSn" is available;
+ you must look that up in the TidyOccEnv. But
+ it's a good place to start looking.
+
+* When looking for a renaming for "foo2" we strip off the "2" and start
+ with "foo". Otherwise if we tidy twice we get silly names like foo23.
+
\begin{code}
-type TidyOccEnv = OccEnv Int -- The in-scope OccNames
- -- Range gives a plausible starting point for new guesses
+type TidyOccEnv = UniqFM Int -- The in-scope OccNames
+ -- See Note [TidyOccEnv]
emptyTidyOccEnv :: TidyOccEnv
-emptyTidyOccEnv = emptyOccEnv
+emptyTidyOccEnv = emptyUFM
initTidyOccEnv :: [OccName] -> TidyOccEnv -- Initialise with names to avoid!
-initTidyOccEnv = foldl (\env occ -> extendOccEnv env occ 1) emptyTidyOccEnv
+initTidyOccEnv = foldl add emptyUFM
+ where
+ add env (OccName _ fs) = addToUFM env fs 1
tidyOccName :: TidyOccEnv -> OccName -> (TidyOccEnv, OccName)
-
-tidyOccName in_scope occ@(OccName occ_sp fs)
- = case lookupOccEnv in_scope occ of
- Nothing -> -- Not already used: make it used
- (extendOccEnv in_scope occ 1, occ)
-
- Just n -> -- Already used: make a new guess,
- -- change the guess base, and try again
- tidyOccName (extendOccEnv in_scope occ (n+1))
- (mkOccName occ_sp (base_occ ++ show n))
+tidyOccName env occ@(OccName occ_sp fs)
+ = case lookupUFM env fs of
+ Just n -> find n
+ Nothing -> (addToUFM env fs 1, occ)
where
- base_occ = reverse (dropWhile isDigit (reverse (unpackFS fs)))
+ base :: String -- Drop trailing digits (see Note [TidyOccEnv])
+ base = reverse (dropWhile isDigit (reverse (unpackFS fs)))
+
+ find n
+ = case lookupUFM env new_fs of
+ Just n' -> find (n1 `max` n')
+ -- The max ensures that n increases, avoiding loops
+ Nothing -> (addToUFM (addToUFM env fs n1) new_fs n1,
+ OccName occ_sp new_fs)
+ -- We update only the beginning and end of the
+ -- chain that find explores; it's a little harder to
+ -- update the middle and there's no real need.
+ where
+ n1 = n+1
+ new_fs = mkFastString (base ++ show n)
\end{code}
%************************************************************************
diff --git a/compiler/coreSyn/CoreLint.lhs b/compiler/coreSyn/CoreLint.lhs
index 144e25b4c8..afd7e05913 100644
--- a/compiler/coreSyn/CoreLint.lhs
+++ b/compiler/coreSyn/CoreLint.lhs
@@ -886,7 +886,8 @@ lintCoercion co@(AxiomInstCo (CoAxiom { co_ax_tvs = ktvs
; let ktv_kind = Type.substTy subst_l (tyVarKind ktv)
-- Using subst_l is ok, because subst_l and subst_r
-- must agree on kind equalities
- ; unless (k `isSubKind` ktv_kind) (bad_ax (ptext (sLit "check_ki2") $$ ppr k $$ ppr ktv_kind $$ ppr ktv $$ ppr co))
+ ; unless (k `isSubKind` ktv_kind)
+ (bad_ax (ptext (sLit "check_ki2") <+> vcat [ ppr co, ppr k, ppr ktv, ppr ktv_kind ] ))
; return (Type.extendTvSubst subst_l ktv t1,
Type.extendTvSubst subst_r ktv t2) }
\end{code}
diff --git a/compiler/coreSyn/CoreUtils.lhs b/compiler/coreSyn/CoreUtils.lhs
index cad80128b9..33c7a9debb 100644
--- a/compiler/coreSyn/CoreUtils.lhs
+++ b/compiler/coreSyn/CoreUtils.lhs
@@ -675,7 +675,7 @@ exprIsWorkFree e = go 0 e
[ go n rhs | (_,_,rhs) <- alts ]
-- See Note [Case expressions are work-free]
go _ (Let {}) = False
- go n (Var v) = n==0 || n < idArity v
+ go n (Var v) = isCheapApp v n
go n (Tick t e) | tickishCounts t = False
| otherwise = go n e
go n (Lam x e) | isRuntimeVar x = n==0 || go (n-1) e
@@ -740,7 +740,6 @@ exprIsCheap = exprIsCheap' isCheapApp
exprIsExpandable :: CoreExpr -> Bool
exprIsExpandable = exprIsCheap' isExpandableApp -- See Note [CONLIKE pragma] in BasicTypes
-type CheapAppFun = Id -> Int -> Bool
exprIsCheap' :: CheapAppFun -> CoreExpr -> Bool
exprIsCheap' _ (Lit _) = True
exprIsCheap' _ (Type _) = True
@@ -779,16 +778,26 @@ exprIsCheap' good_app other_expr -- Applications and variables
go (App f a) val_args | isRuntimeArg a = go f (a:val_args)
| otherwise = go f val_args
- go (Var _) [] = True -- Just a type application of a variable
- -- (f t1 t2 t3) counts as WHNF
+ go (Var _) [] = True
+ -- Just a type application of a variable
+ -- (f t1 t2 t3) counts as WHNF
+ -- This case is probably handeld by the good_app case
+ -- below, which should have a case for n=0, but putting
+ -- it here too is belt and braces; and it's such a common
+ -- case that checking for null directly seems like a
+ -- good plan
+
go (Var f) args
+ | good_app f (length args)
+ = go_pap args
+
+ | otherwise
= case idDetails f of
- RecSelId {} -> go_sel args
- ClassOpId {} -> go_sel args
- PrimOpId op -> go_primop op args
- _ | good_app f (length args) -> go_pap args
- | isBottomingId f -> True
- | otherwise -> False
+ RecSelId {} -> go_sel args
+ ClassOpId {} -> go_sel args
+ PrimOpId op -> go_primop op args
+ _ | isBottomingId f -> True
+ | otherwise -> False
-- Application of a function which
-- always gives bottom; we treat this as cheap
-- because it certainly doesn't need to be shared!
@@ -820,9 +829,17 @@ exprIsCheap' good_app other_expr -- Applications and variables
-- BUT: Take care with (sel d x)! The (sel d) might be cheap, but
-- there's no guarantee that (sel d x) will be too. Hence (n_val_args == 1)
+-------------------------------------
+type CheapAppFun = Id -> Int -> Bool
+ -- Is an application of this function to n *value* args
+ -- always cheap, assuming the arguments are cheap?
+ -- Mainly true of partial applications, data constructors,
+ -- and of course true if the number of args is zero
+
isCheapApp :: CheapAppFun
isCheapApp fn n_val_args
- = isDataConWorkId fn
+ = isDataConWorkId fn
+ || n_val_args == 0
|| n_val_args < idArity fn
isExpandableApp :: CheapAppFun
@@ -833,6 +850,7 @@ isExpandableApp fn n_val_args
where
-- See if all the arguments are PredTys (implicit params or classes)
-- If so we'll regard it as expandable; see Note [Expandable overloadings]
+ -- This incidentally picks up the (n_val_args = 0) case
go 0 _ = True
go n_val_args ty
| Just (_, ty) <- splitForAllTy_maybe ty = go n_val_args ty
diff --git a/compiler/deSugar/DsMeta.hs b/compiler/deSugar/DsMeta.hs
index d9e851ae62..405b7687a5 100644
--- a/compiler/deSugar/DsMeta.hs
+++ b/compiler/deSugar/DsMeta.hs
@@ -265,9 +265,8 @@ repTyDefn tc bndrs opt_tys tv_names
; case new_or_data of
NewType -> do { con1 <- repC tv_names (head cons)
; repNewtype cxt1 tc bndrs opt_tys con1 derivs1 }
- DataType -> do { cons1 <- mapM (repC tv_names) cons
- ; cons2 <- coreList conQTyConName cons1
- ; repData cxt1 tc bndrs opt_tys cons2 derivs1 } }
+ DataType -> do { cons1 <- repList conQTyConName (repC tv_names) cons
+ ; repData cxt1 tc bndrs opt_tys cons1 derivs1 } }
repTyDefn tc bndrs opt_tys _ (TySynonym { td_synRhs = ty })
= do { ty1 <- repLTy ty
@@ -305,16 +304,12 @@ mk_extra_tvs tc tvs defn
-- represent fundeps
--
repLFunDeps :: [Located (FunDep Name)] -> DsM (Core [TH.FunDep])
-repLFunDeps fds = do fds' <- mapM repLFunDep fds
- fdList <- coreList funDepTyConName fds'
- return fdList
+repLFunDeps fds = repList funDepTyConName repLFunDep fds
repLFunDep :: Located (FunDep Name) -> DsM (Core TH.FunDep)
-repLFunDep (L _ (xs, ys)) = do xs' <- mapM lookupBinder xs
- ys' <- mapM lookupBinder ys
- xs_list <- coreList nameTyConName xs'
- ys_list <- coreList nameTyConName ys'
- repFunDep xs_list ys_list
+repLFunDep (L _ (xs, ys)) = do xs' <- repList nameTyConName lookupBinder xs
+ ys' <- repList nameTyConName lookupBinder ys
+ repFunDep xs' ys'
-- represent family declaration flavours
--
@@ -364,9 +359,8 @@ repFamInstD (FamInstDecl { fid_tycon = tc_name
; let loc = getLoc tc_name
hs_tvs = HsQTvs { hsq_kvs = kv_names, hsq_tvs = userHsTyVarBndrs loc tv_names } -- Yuk
; addTyClTyVarBinds hs_tvs $ \ bndrs ->
- do { tys1 <- repLTys tys
- ; tys2 <- coreList typeQTyConName tys1
- ; repTyDefn tc bndrs (Just tys2) tv_names defn } }
+ do { tys1 <- repList typeQTyConName repLTy tys
+ ; repTyDefn tc bndrs (Just tys1) tv_names defn } }
repForD :: Located (ForeignDecl Name) -> DsM (SrcSpan, Core TH.DecQ)
repForD (L loc (ForeignImport name typ _ (CImport cc s mch cis)))
@@ -415,20 +409,29 @@ repFixD (L loc (FixitySig name (Fixity prec dir)))
repRuleD :: LRuleDecl Name -> DsM (SrcSpan, Core TH.DecQ)
repRuleD (L loc (HsRule n act bndrs lhs _ rhs _))
- = do { n' <- coreStringLit $ unpackFS n
- ; phases <- repPhases act
- ; bndrs' <- mapM repRuleBndr bndrs >>= coreList ruleBndrQTyConName
- ; lhs' <- repLE lhs
- ; rhs' <- repLE rhs
- ; pragma <- repPragRule n' bndrs' lhs' rhs' phases
- ; return (loc, pragma) }
+ = do { let bndr_names = concatMap ruleBndrNames bndrs
+ ; ss <- mkGenSyms bndr_names
+ ; rule1 <- addBinds ss $
+ do { bndrs' <- repList ruleBndrQTyConName repRuleBndr bndrs
+ ; n' <- coreStringLit $ unpackFS n
+ ; act' <- repPhases act
+ ; lhs' <- repLE lhs
+ ; rhs' <- repLE rhs
+ ; repPragRule n' bndrs' lhs' rhs' act' }
+ ; rule2 <- wrapGenSyms ss rule1
+ ; return (loc, rule2) }
+
+ruleBndrNames :: RuleBndr Name -> [Name]
+ruleBndrNames (RuleBndr n) = [unLoc n]
+ruleBndrNames (RuleBndrSig n (HsWB { hswb_kvs = kvs, hswb_tvs = tvs }))
+ = unLoc n : kvs ++ tvs
repRuleBndr :: RuleBndr Name -> DsM (Core TH.RuleBndrQ)
repRuleBndr (RuleBndr n)
- = do { MkC n' <- lookupLOcc n
+ = do { MkC n' <- lookupLBinder n
; rep2 ruleVarName [n'] }
repRuleBndr (RuleBndrSig n (HsWB { hswb_cts = ty }))
- = do { MkC n' <- lookupLOcc n
+ = do { MkC n' <- lookupLBinder n
; MkC ty' <- repLTy ty
; rep2 typedRuleVarName [n', ty'] }
@@ -527,8 +530,7 @@ repBangTy ty= do
repDerivs :: Maybe [LHsType Name] -> DsM (Core [TH.Name])
repDerivs Nothing = coreList nameTyConName []
repDerivs (Just ctxt)
- = do { strs <- mapM rep_deriv ctxt ;
- coreList nameTyConName strs }
+ = repList nameTyConName rep_deriv ctxt
where
rep_deriv :: LHsType Name -> DsM (Core TH.Name)
-- Deriving clauses must have the simple H98 form
@@ -578,11 +580,10 @@ rep_ty_sig loc (L _ ty) nm
rep_ty (HsForAllTy Explicit tvs ctxt ty)
= do { let rep_in_scope_tv tv = do { name <- lookupBinder (hsLTyVarName tv)
; repTyVarBndrWithKind tv name }
- ; bndrs1 <- mapM rep_in_scope_tv (hsQTvBndrs tvs)
- ; bndrs2 <- coreList tyVarBndrTyConName bndrs1
+ ; bndrs1 <- repList tyVarBndrTyConName rep_in_scope_tv (hsQTvBndrs tvs)
; ctxt1 <- repLContext ctxt
; ty1 <- repLTy ty
- ; repTForall bndrs2 ctxt1 ty1 }
+ ; repTForall bndrs1 ctxt1 ty1 }
rep_ty ty = repTy ty
@@ -653,9 +654,8 @@ addTyVarBinds :: LHsTyVarBndrs Name -- the binders to be
addTyVarBinds tvs m
= do { freshNames <- mkGenSyms (hsLKiTyVarNames tvs)
; term <- addBinds freshNames $
- do { kbs1 <- mapM mk_tv_bndr (hsQTvBndrs tvs `zip` freshNames)
- ; kbs2 <- coreList tyVarBndrTyConName kbs1
- ; m kbs2 }
+ do { kbs <- repList tyVarBndrTyConName mk_tv_bndr (hsQTvBndrs tvs `zip` freshNames)
+ ; m kbs }
; wrapGenSyms freshNames term }
where
mk_tv_bndr (tv, (_,v)) = repTyVarBndrWithKind tv (coreVar v)
@@ -677,13 +677,12 @@ addTyClTyVarBinds tvs m
-- This makes things work for family declarations
; term <- addBinds freshNames $
- do { kbs1 <- mapM mk_tv_bndr (hsQTvBndrs tvs)
- ; kbs2 <- coreList tyVarBndrTyConName kbs1
- ; m kbs2 }
+ do { kbs <- repList tyVarBndrTyConName mk_tv_bndr (hsQTvBndrs tvs)
+ ; m kbs }
; wrapGenSyms freshNames term }
where
- mk_tv_bndr tv = do { v <- lookupOcc (hsLTyVarName tv)
+ mk_tv_bndr tv = do { v <- lookupBinder (hsLTyVarName tv)
; repTyVarBndrWithKind tv v }
-- Produce kinded binder constructors from the Haskell tyvar binders
@@ -701,10 +700,8 @@ repLContext :: LHsContext Name -> DsM (Core TH.CxtQ)
repLContext (L _ ctxt) = repContext ctxt
repContext :: HsContext Name -> DsM (Core TH.CxtQ)
-repContext ctxt = do
- preds <- mapM repLPred ctxt
- predList <- coreList predQTyConName preds
- repCtxt predList
+repContext ctxt = do preds <- repList predQTyConName repLPred ctxt
+ repCtxt preds
-- represent a type predicate
--
@@ -716,9 +713,8 @@ repPred ty
| Just (cls, tys) <- splitHsClassTy_maybe ty
= do
cls1 <- lookupOcc cls
- tys1 <- repLTys tys
- tys2 <- coreList typeQTyConName tys1
- repClassP cls1 tys2
+ tys1 <- repList typeQTyConName repLTy tys
+ repClassP cls1 tys1
repPred (HsEqTy tyleft tyright)
= do
tyleft1 <- repLTy tyleft
@@ -860,8 +856,7 @@ repSplice (HsSplice n _)
-----------------------------------------------------------------------------
repLEs :: [LHsExpr Name] -> DsM (Core [TH.ExpQ])
-repLEs es = do { es' <- mapM repLE es ;
- coreList expQTyConName es' }
+repLEs es = repList expQTyConName repLE es
-- FIXME: some of these panics should be converted into proper error messages
-- unless we can make sure that constructs, which are plainly not
@@ -1024,10 +1019,11 @@ repLGRHS (L _ (GRHS ss rhs))
repFields :: HsRecordBinds Name -> DsM (Core [TH.Q TH.FieldExp])
repFields (HsRecFields { rec_flds = flds })
- = do { fnames <- mapM lookupLOcc (map hsRecFieldId flds)
- ; es <- mapM repLE (map hsRecFieldArg flds)
- ; fs <- zipWithM repFieldExp fnames es
- ; coreList fieldExpQTyConName fs }
+ = repList fieldExpQTyConName rep_fld flds
+ where
+ rep_fld fld = do { fn <- lookupLOcc (hsRecFieldId fld)
+ ; e <- repLE (hsRecFieldArg fld)
+ ; repFieldExp fn e }
-----------------------------------------------------------------------------
@@ -1210,8 +1206,7 @@ repLambda (L _ m) = notHandled "Guarded labmdas" (pprMatch (LambdaExpr :: HsMatc
-- Process a list of patterns
repLPs :: [LPat Name] -> DsM (Core [TH.PatQ])
-repLPs ps = do { ps' <- mapM repLP ps ;
- coreList patQTyConName ps' }
+repLPs ps = repList patQTyConName repLP ps
repLP :: LPat Name -> DsM (Core TH.PatQ)
repLP (L _ p) = repP p
@@ -1232,16 +1227,17 @@ repP (ConPatIn dc details)
= do { con_str <- lookupLOcc dc
; case details of
PrefixCon ps -> do { qs <- repLPs ps; repPcon con_str qs }
- RecCon rec -> do { let flds = rec_flds rec
- ; vs <- sequence $ map lookupLOcc (map hsRecFieldId flds)
- ; ps <- sequence $ map repLP (map hsRecFieldArg flds)
- ; fps <- zipWithM (\x y -> rep2 fieldPatName [unC x,unC y]) vs ps
- ; fps' <- coreList fieldPatQTyConName fps
- ; repPrec con_str fps' }
+ RecCon rec -> do { fps <- repList fieldPatQTyConName rep_fld (rec_flds rec)
+ ; repPrec con_str fps }
InfixCon p1 p2 -> do { p1' <- repLP p1;
p2' <- repLP p2;
repPinfix p1' con_str p2' }
}
+ where
+ rep_fld fld = do { MkC v <- lookupLOcc (hsRecFieldId fld)
+ ; MkC p <- repLP (hsRecFieldArg fld)
+ ; rep2 fieldPatName [v,p] }
+
repP (NPat l Nothing _) = do { a <- repOverloadedLiteral l; repPlit a }
repP (ViewPat e p _) = do { e' <- repLE e; p' <- repLP p; repPview e' p' }
repP p@(NPat _ (Just _) _) = notHandled "Negative overloaded patterns" (ppr p)
@@ -1679,16 +1675,16 @@ repEqualP (MkC ty1) (MkC ty2) = rep2 equalPName [ty1, ty2]
repConstr :: Core TH.Name -> HsConDeclDetails Name
-> DsM (Core TH.ConQ)
repConstr con (PrefixCon ps)
- = do arg_tys <- mapM repBangTy ps
- arg_tys1 <- coreList strictTypeQTyConName arg_tys
- rep2 normalCName [unC con, unC arg_tys1]
+ = do arg_tys <- repList strictTypeQTyConName repBangTy ps
+ rep2 normalCName [unC con, unC arg_tys]
repConstr con (RecCon ips)
- = do arg_vs <- mapM lookupLOcc (map cd_fld_name ips)
- arg_tys <- mapM repBangTy (map cd_fld_type ips)
- arg_vtys <- zipWithM (\x y -> rep2 varStrictTypeName [unC x, unC y])
- arg_vs arg_tys
- arg_vtys' <- coreList varStrictTypeQTyConName arg_vtys
- rep2 recCName [unC con, unC arg_vtys']
+ = do { arg_vtys <- repList varStrictTypeQTyConName rep_ip ips
+ ; rep2 recCName [unC con, unC arg_vtys] }
+ where
+ rep_ip ip = do { MkC v <- lookupLOcc (cd_fld_name ip)
+ ; MkC ty <- repBangTy (cd_fld_type ip)
+ ; rep2 varStrictTypeName [v,ty] }
+
repConstr con (InfixCon st1 st2)
= do arg1 <- repBangTy st1
arg2 <- repBangTy st2
@@ -1863,6 +1859,12 @@ repSequenceQ ty_a (MkC list)
------------ Lists and Tuples -------------------
-- turn a list of patterns into a single pattern matching a list
+repList :: Name -> (a -> DsM (Core b))
+ -> [a] -> DsM (Core [b])
+repList tc_name f args
+ = do { args1 <- mapM f args
+ ; coreList tc_name args1 }
+
coreList :: Name -- Of the TyCon of the element type
-> [Core a] -> DsM (Core [a])
coreList tc_name es
diff --git a/compiler/hsSyn/HsBinds.lhs b/compiler/hsSyn/HsBinds.lhs
index f15ef5d3cc..24ed16f1c9 100644
--- a/compiler/hsSyn/HsBinds.lhs
+++ b/compiler/hsSyn/HsBinds.lhs
@@ -574,22 +574,6 @@ signatures. Since some of the signatures contain a list of names, testing for
equality is not enough -- we have to check if they overlap.
\begin{code}
-overlapHsSig :: Eq a => LSig a -> LSig a -> Bool
-overlapHsSig sig1 sig2 = case (unLoc sig1, unLoc sig2) of
- (FixSig (FixitySig n1 _), FixSig (FixitySig n2 _)) -> unLoc n1 == unLoc n2
- (IdSig n1, IdSig n2) -> n1 == n2
- (TypeSig ns1 _, TypeSig ns2 _) -> ns1 `overlaps_with` ns2
- (GenericSig ns1 _, GenericSig ns2 _) -> ns1 `overlaps_with` ns2
- (InlineSig n1 _, InlineSig n2 _) -> unLoc n1 == unLoc n2
- -- For specialisations, we don't have equality over HsType, so it's not
- -- convenient to spot duplicate specialisations here. Check for this later,
- -- when we're in Type land
- (_other1, _other2) -> False
- where
- ns1 `overlaps_with` ns2 = not (null (intersect (map unLoc ns1) (map unLoc ns2)))
-\end{code}
-
-\begin{code}
instance (OutputableBndr name) => Outputable (Sig name) where
ppr sig = ppr_sig sig
diff --git a/compiler/iface/TcIface.lhs b/compiler/iface/TcIface.lhs
index 37965185cf..652eb0ad11 100644
--- a/compiler/iface/TcIface.lhs
+++ b/compiler/iface/TcIface.lhs
@@ -1364,7 +1364,7 @@ tcIfaceTyCon (IfaceTc name)
; case thing of -- A "type constructor" can be a promoted data constructor
-- c.f. Trac #5881
ATyCon tc -> return tc
- ADataCon dc -> return (buildPromotedDataCon dc)
+ ADataCon dc -> return (promoteDataCon dc)
_ -> pprPanic "tcIfaceTyCon" (ppr name $$ ppr thing) }
tcIfaceKindCon :: IfaceTyCon -> IfL TyCon
@@ -1374,7 +1374,7 @@ tcIfaceKindCon (IfaceTc name)
-- c.f. Trac #5881
ATyCon tc
| isSuperKind (tyConKind tc) -> return tc -- Mainly just '*' or 'AnyK'
- | otherwise -> return (buildPromotedTyCon tc)
+ | otherwise -> return (promoteTyCon tc)
_ -> pprPanic "tcIfaceKindCon" (ppr name $$ ppr thing) }
diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs
index 47756c5ea1..ac1fe9ac4f 100644
--- a/compiler/main/DynFlags.hs
+++ b/compiler/main/DynFlags.hs
@@ -495,7 +495,6 @@ data ExtensionFlag
| Opt_MultiParamTypeClasses
| Opt_FunctionalDependencies
| Opt_UnicodeSyntax
- | Opt_PolymorphicComponents
| Opt_ExistentialQuantification
| Opt_MagicHash
| Opt_EmptyDataDecls
@@ -509,7 +508,6 @@ data ExtensionFlag
| Opt_TupleSections
| Opt_PatternGuards
| Opt_LiberalTypeSynonyms
- | Opt_Rank2Types
| Opt_RankNTypes
| Opt_ImpredicativeTypes
| Opt_TypeOperators
@@ -2447,7 +2445,6 @@ xFlags = [
( "PatternGuards", Opt_PatternGuards, nop ),
( "UnicodeSyntax", Opt_UnicodeSyntax, nop ),
( "MagicHash", Opt_MagicHash, nop ),
- ( "PolymorphicComponents", Opt_PolymorphicComponents, nop ),
( "ExistentialQuantification", Opt_ExistentialQuantification, nop ),
( "KindSignatures", Opt_KindSignatures, nop ),
( "EmptyDataDecls", Opt_EmptyDataDecls, nop ),
@@ -2460,7 +2457,10 @@ xFlags = [
( "CApiFFI", Opt_CApiFFI, nop ),
( "GHCForeignImportPrim", Opt_GHCForeignImportPrim, nop ),
( "LiberalTypeSynonyms", Opt_LiberalTypeSynonyms, nop ),
- ( "Rank2Types", Opt_Rank2Types, nop ),
+ ( "PolymorphicComponents", Opt_RankNTypes,
+ deprecatedForExtension "RankNTypes" ),
+ ( "Rank2Types", Opt_RankNTypes,
+ deprecatedForExtension "RankNTypes" ),
( "RankNTypes", Opt_RankNTypes, nop ),
( "ImpredicativeTypes", Opt_ImpredicativeTypes, nop),
( "TypeOperators", Opt_TypeOperators, nop ),
@@ -2576,11 +2576,9 @@ default_PIC platform =
impliedFlags :: [(ExtensionFlag, TurnOnFlag, ExtensionFlag)]
impliedFlags
= [ (Opt_RankNTypes, turnOn, Opt_ExplicitForAll)
- , (Opt_Rank2Types, turnOn, Opt_ExplicitForAll)
, (Opt_ScopedTypeVariables, turnOn, Opt_ExplicitForAll)
, (Opt_LiberalTypeSynonyms, turnOn, Opt_ExplicitForAll)
, (Opt_ExistentialQuantification, turnOn, Opt_ExplicitForAll)
- , (Opt_PolymorphicComponents, turnOn, Opt_ExplicitForAll)
, (Opt_FlexibleInstances, turnOn, Opt_TypeSynonymInstances)
, (Opt_FunctionalDependencies, turnOn, Opt_MultiParamTypeClasses)
@@ -2729,7 +2727,6 @@ glasgowExtsFlags = [
, Opt_MultiParamTypeClasses
, Opt_FunctionalDependencies
, Opt_MagicHash
- , Opt_PolymorphicComponents
, Opt_ExistentialQuantification
, Opt_UnicodeSyntax
, Opt_PostfixOperators
diff --git a/compiler/prelude/PrelRules.lhs b/compiler/prelude/PrelRules.lhs
index 72cb8780a7..2ee14679b2 100644
--- a/compiler/prelude/PrelRules.lhs
+++ b/compiler/prelude/PrelRules.lhs
@@ -12,7 +12,7 @@ ToDo:
(i1 + i2) only if it results in a valid Float.
\begin{code}
-{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE RankNTypes #-}
{-# OPTIONS -optc-DNON_POSIX_SOURCE #-}
module PrelRules ( primOpRules, builtinRules ) where
diff --git a/compiler/prelude/TysWiredIn.lhs b/compiler/prelude/TysWiredIn.lhs
index 78e1f74b4d..5071b33e9a 100644
--- a/compiler/prelude/TysWiredIn.lhs
+++ b/compiler/prelude/TysWiredIn.lhs
@@ -322,10 +322,10 @@ tupleTyCon UnboxedTuple i = fst (unboxedTupleArr ! i)
tupleTyCon ConstraintTuple i = fst (factTupleArr ! i)
promotedTupleTyCon :: TupleSort -> Arity -> TyCon
-promotedTupleTyCon sort i = buildPromotedTyCon (tupleTyCon sort i)
+promotedTupleTyCon sort i = promoteTyCon (tupleTyCon sort i)
promotedTupleDataCon :: TupleSort -> Arity -> TyCon
-promotedTupleDataCon sort i = buildPromotedDataCon (tupleCon sort i)
+promotedTupleDataCon sort i = promoteDataCon (tupleCon sort i)
tupleCon :: TupleSort -> Arity -> DataCon
tupleCon sort i | i > mAX_TUPLE_SIZE = snd (mk_tuple sort i) -- Build one specially
@@ -605,7 +605,7 @@ mkPromotedListTy :: Type -> Type
mkPromotedListTy ty = mkTyConApp promotedListTyCon [ty]
promotedListTyCon :: TyCon
-promotedListTyCon = buildPromotedTyCon listTyCon
+promotedListTyCon = promoteTyCon listTyCon
nilDataCon :: DataCon
nilDataCon = pcDataCon nilDataConName alpha_tyvar [] listTyCon
diff --git a/compiler/rename/RnBinds.lhs b/compiler/rename/RnBinds.lhs
index dfead07797..fbbaf65819 100644
--- a/compiler/rename/RnBinds.lhs
+++ b/compiler/rename/RnBinds.lhs
@@ -50,7 +50,7 @@ import Digraph ( SCC(..) )
import Bag
import Outputable
import FastString
-import Data.List ( partition )
+import Data.List ( partition, sort )
import Maybes ( orElse )
import Control.Monad
\end{code}
@@ -653,15 +653,7 @@ renameSigs :: HsSigCtxt
-> RnM ([LSig Name], FreeVars)
-- Renames the signatures and performs error checks
renameSigs ctxt sigs
- = do { mapM_ dupSigDeclErr (findDupsEq overlapHsSig sigs) -- Duplicate
- -- Check for duplicates on RdrName version,
- -- because renamed version has unboundName for
- -- not-in-scope binders, which gives bogus dup-sig errors
- -- NB: in a class decl, a 'generic' sig is not considered
- -- equal to an ordinary sig, so we allow, say
- -- class C a where
- -- op :: a -> a
- -- default op :: Eq a => a -> a
+ = do { mapM_ dupSigDeclErr (findDupSigs sigs)
; (sigs', sig_fvs) <- mapFvRn (wrapLocFstM (renameSig ctxt)) sigs
@@ -748,6 +740,32 @@ okHsSig ctxt (L _ sig)
(SpecInstSig {}, InstDeclCtxt {}) -> True
(SpecInstSig {}, _) -> False
+
+-------------------
+findDupSigs :: [LSig RdrName] -> [[(Located RdrName, Sig RdrName)]]
+-- Check for duplicates on RdrName version,
+-- because renamed version has unboundName for
+-- not-in-scope binders, which gives bogus dup-sig errors
+-- NB: in a class decl, a 'generic' sig is not considered
+-- equal to an ordinary sig, so we allow, say
+-- class C a where
+-- op :: a -> a
+-- default op :: Eq a => a -> a
+findDupSigs sigs
+ = findDupsEq matching_sig (concatMap (expand_sig . unLoc) sigs)
+ where
+ expand_sig sig@(FixSig (FixitySig n _)) = [(n,sig)]
+ expand_sig sig@(InlineSig n _) = [(n,sig)]
+ expand_sig sig@(TypeSig ns _) = [(n,sig) | n <- ns]
+ expand_sig sig@(GenericSig ns _) = [(n,sig) | n <- ns]
+ expand_sig _ = []
+
+ matching_sig (L _ n1,sig1) (L _ n2,sig2) = n1 == n2 && mtch sig1 sig2
+ mtch (FixSig {}) (FixSig {}) = True
+ mtch (InlineSig {}) (InlineSig {}) = True
+ mtch (TypeSig {}) (TypeSig {}) = True
+ mtch (GenericSig {}) (GenericSig {}) = True
+ mtch _ _ = False
\end{code}
@@ -848,14 +866,15 @@ rnGRHS' ctxt rnBody (GRHS guards rhs)
%************************************************************************
\begin{code}
-dupSigDeclErr :: [LSig RdrName] -> RnM ()
-dupSigDeclErr sigs@(L loc sig : _)
+dupSigDeclErr :: [(Located RdrName, Sig RdrName)] -> RnM ()
+dupSigDeclErr pairs@((L loc name, sig) : _)
= addErrAt loc $
- vcat [ptext (sLit "Duplicate") <+> what_it_is <> colon,
- nest 2 (vcat (map ppr_sig sigs))]
+ vcat [ ptext (sLit "Duplicate") <+> what_it_is
+ <> ptext (sLit "s for") <+> quotes (ppr name)
+ , ptext (sLit "at") <+> vcat (map ppr $ sort $ map (getLoc . fst) pairs) ]
where
what_it_is = hsSigDoc sig
- ppr_sig (L loc sig) = ppr loc <> colon <+> ppr sig
+
dupSigDeclErr [] = panic "dupSigDeclErr"
misplacedSigErr :: LSig Name -> RnM ()
diff --git a/compiler/simplCore/OccurAnal.lhs b/compiler/simplCore/OccurAnal.lhs
index 4705f6b694..d75a224bb8 100644
--- a/compiler/simplCore/OccurAnal.lhs
+++ b/compiler/simplCore/OccurAnal.lhs
@@ -429,7 +429,7 @@ We are in an infinite loop.
A more elaborate example (that I actually saw in practice when I went to
mark GHC.List.filter as INLINABLE) is as follows. Say I have this module:
- {-# LANGUAGE Rank2Types #-}
+ {-# LANGUAGE RankNTypes #-}
module GHCList where
import Prelude hiding (filter)
diff --git a/compiler/simplCore/Simplify.lhs b/compiler/simplCore/Simplify.lhs
index f794b88114..1c50c6b4c8 100644
--- a/compiler/simplCore/Simplify.lhs
+++ b/compiler/simplCore/Simplify.lhs
@@ -1796,7 +1796,7 @@ rebuildCase env scrut case_bndr [(_, bndrs, rhs)] cont
-- ppr scrut]) $
tick (CaseElim case_bndr)
; env' <- simplNonRecX env case_bndr scrut
- -- If case_bndr is deads, simplNonRecX will discard
+ -- If case_bndr is dead, simplNonRecX will discard
; simplExprF env' rhs cont }
where
elim_lifted -- See Note [Case elimination: lifted case]
diff --git a/compiler/typecheck/Inst.lhs b/compiler/typecheck/Inst.lhs
index dac8fd1367..5b6364b196 100644
--- a/compiler/typecheck/Inst.lhs
+++ b/compiler/typecheck/Inst.lhs
@@ -212,19 +212,21 @@ instCallConstraints :: CtOrigin -> TcThetaType -> TcM HsWrapper
-- Instantiates the TcTheta, puts all constraints thereby generated
-- into the LIE, and returns a HsWrapper to enclose the call site.
-instCallConstraints _ [] = return idHsWrapper
-
-instCallConstraints origin (pred : preds)
- | Just (ty1, ty2) <- getEqPredTys_maybe pred -- Try short-cut
- = do { traceTc "instCallConstraints" $ ppr (mkEqPred ty1 ty2)
- ; co <- unifyType ty1 ty2
- ; co_fn <- instCallConstraints origin preds
- ; return (co_fn <.> WpEvApp (EvCoercion co)) }
-
+instCallConstraints orig preds
+ | null preds
+ = return idHsWrapper
| otherwise
- = do { ev_var <- emitWanted origin pred
- ; co_fn <- instCallConstraints origin preds
- ; return (co_fn <.> WpEvApp (EvId ev_var)) }
+ = do { evs <- mapM go preds
+ ; traceTc "instCallConstraints" (ppr evs)
+ ; return (mkWpEvApps evs) }
+ where
+ go pred
+ | Just (ty1, ty2) <- getEqPredTys_maybe pred -- Try short-cut
+ = do { co <- unifyType ty1 ty2
+ ; return (EvCoercion co) }
+ | otherwise
+ = do { ev_var <- emitWanted orig pred
+ ; return (EvId ev_var) }
----------------
instStupidTheta :: CtOrigin -> TcThetaType -> TcM ()
@@ -522,6 +524,10 @@ hasEqualities givens = any (has_eq . evVarPred) givens
has_eq' (ClassPred cls _tys) = any has_eq (classSCTheta cls)
has_eq' (TuplePred ts) = any has_eq ts
has_eq' (IrredPred _) = True -- Might have equalities in it after reduction?
+ -- This is conservative. e.g. if there's a constraint function FC with
+ -- type instance FC Int = Show
+ -- then we won't float from inside a given constraint (FC Int a), even though
+ -- it's really the innocuous (Show a). Too bad! Add a type signature
---------------- Getting free tyvars -------------------------
tyVarsOfCt :: Ct -> TcTyVarSet
diff --git a/compiler/typecheck/TcCanonical.lhs b/compiler/typecheck/TcCanonical.lhs
index 33c62dcc15..3309e12a33 100644
--- a/compiler/typecheck/TcCanonical.lhs
+++ b/compiler/typecheck/TcCanonical.lhs
@@ -7,7 +7,7 @@
-- for details
module TcCanonical(
- canonicalize, occurCheckExpand, emitWorkNC,
+ canonicalize, emitWorkNC,
StopOrContinue (..)
) where
@@ -25,8 +25,6 @@ import Var
import VarEnv
import Outputable
import Control.Monad ( when )
-import MonadUtils
-import Control.Applicative ( (<|>) )
import TysWiredIn ( eqTyCon )
import VarSet
@@ -1112,7 +1110,7 @@ canEqLeafFunEq loc ev fn tys1 ty2 -- ev :: F tys1 ~ ty2
; (xi2, co2) <- flatten loc FMFullFlatten flav ty2
-- Fancy higher-dimensional coercion between equalities!
- -- SPJ asks why? Why not just co : F xis1 ~ F tys1?
+ -- SPJ asks why? Why not just co : F xis1 ~ F tys1?
; let fam_head = mkTyConApp fn xis1
xco = mkHdEqPred ty2 (mkTcTyConAppCo fn cos1) co2
-- xco :: (F xis1 ~ xi2) ~ (F tys1 ~ ty2)
@@ -1181,78 +1179,6 @@ mkHdEqPred t2 co1 co2 = mkTcTyConAppCo eqTyCon [mkTcReflCo (defaultKind (typeKin
-- Why defaultKind? Same reason as the comment on TcType/mkTcEqPred. I truly hate this (DV)
\end{code}
-Note [Occurs check expansion]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-@occurCheckExpand tv xi@ expands synonyms in xi just enough to get rid
-of occurrences of tv outside type function arguments, if that is
-possible; otherwise, it returns Nothing.
-
-For example, suppose we have
- type F a b = [a]
-Then
- occurCheckExpand b (F Int b) = Just [Int]
-but
- occurCheckExpand a (F a Int) = Nothing
-
-We don't promise to do the absolute minimum amount of expanding
-necessary, but we try not to do expansions we don't need to. We
-prefer doing inner expansions first. For example,
- type F a b = (a, Int, a, [a])
- type G b = Char
-We have
- occurCheckExpand b (F (G b)) = F Char
-even though we could also expand F to get rid of b.
-
-See also Note [Type synonyms and canonicalization].
-
-\begin{code}
-occurCheckExpand :: TcTyVar -> Type -> Maybe Type
--- Check whether the given variable occurs in the given type. We may
--- have needed to do some type synonym unfolding in order to get rid
--- of the variable, so we also return the unfolded version of the
--- type, which is guaranteed to be syntactically free of the given
--- type variable. If the type is already syntactically free of the
--- variable, then the same type is returned.
-
-occurCheckExpand tv ty
- | not (tv `elemVarSet` tyVarsOfType ty) = Just ty
- | otherwise = go ty
- where
- go t@(TyVarTy tv') | tv == tv' = Nothing
- | otherwise = Just t
- go ty@(LitTy {}) = return ty
- go (AppTy ty1 ty2) = do { ty1' <- go ty1
- ; ty2' <- go ty2
- ; return (mkAppTy ty1' ty2') }
- -- mkAppTy <$> go ty1 <*> go ty2
- go (FunTy ty1 ty2) = do { ty1' <- go ty1
- ; ty2' <- go ty2
- ; return (mkFunTy ty1' ty2') }
- -- mkFunTy <$> go ty1 <*> go ty2
- go ty@(ForAllTy {})
- | tv `elemVarSet` tyVarsOfTypes tvs_knds = Nothing
- -- Can't expand away the kinds unless we create
- -- fresh variables which we don't want to do at this point.
- | otherwise = do { rho' <- go rho
- ; return (mkForAllTys tvs rho') }
- where
- (tvs,rho) = splitForAllTys ty
- tvs_knds = map tyVarKind tvs
-
- -- For a type constructor application, first try expanding away the
- -- offending variable from the arguments. If that doesn't work, next
- -- see if the type constructor is a type synonym, and if so, expand
- -- it and try again.
- go ty@(TyConApp tc tys)
- | isSynFamilyTyCon tc -- It's ok for tv to occur under a type family application
- = return ty -- Eg. (a ~ F a) is not an occur-check error
- -- NB This case can't occur during canonicalisation,
- -- because the arg is a Xi-type, but can occur in the
- -- call from TcErrors
- | otherwise
- = (mkTyConApp tc <$> mapM go tys) <|> (tcView ty >>= go)
-\end{code}
-
Note [Type synonyms and canonicalization]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We treat type synonym applications as xi types, that is, they do not
diff --git a/compiler/typecheck/TcErrors.lhs b/compiler/typecheck/TcErrors.lhs
index 74a687f409..6ac8793f6c 100644
--- a/compiler/typecheck/TcErrors.lhs
+++ b/compiler/typecheck/TcErrors.lhs
@@ -16,7 +16,6 @@ module TcErrors(
#include "HsVersions.h"
-import TcCanonical( occurCheckExpand )
import TcRnTypes
import TcRnMonad
import TcMType
@@ -576,7 +575,6 @@ mkEqErr1 ctxt ct
mk_wanted_extra orig@(TypeEqOrigin {})
= mkExpectedActualMsg ty1 ty2 orig
-
mk_wanted_extra (KindEqOrigin cty1 cty2 sub_o)
= (Nothing, msg1 $$ msg2)
where
@@ -596,8 +594,10 @@ mkEqErr_help, reportEqErr
-> TcType -> TcType -> TcM ErrMsg
mkEqErr_help ctxt extra ct oriented ty1 ty2
| Just tv1 <- tcGetTyVar_maybe ty1 = mkTyVarEqErr ctxt extra ct oriented tv1 ty2
- | Just tv2 <- tcGetTyVar_maybe ty2 = mkTyVarEqErr ctxt extra ct oriented tv2 ty1
+ | Just tv2 <- tcGetTyVar_maybe ty2 = mkTyVarEqErr ctxt extra ct swapped tv2 ty1
| otherwise = reportEqErr ctxt extra ct oriented ty1 ty2
+ where
+ swapped = fmap flipSwap oriented
reportEqErr ctxt extra1 ct oriented ty1 ty2
= do { (ctxt', extra2) <- mkEqInfoMsg ctxt ct ty1 ty2
@@ -621,9 +621,10 @@ mkTyVarEqErr ctxt extra ct oriented tv1 ty2
= mkErrorMsg ctxt ct $ (kindErrorMsg (mkTyVarTy tv1) ty2 $$ extra)
| isNothing (occurCheckExpand tv1 ty2)
- = let occCheckMsg = hang (text "Occurs check: cannot construct the infinite type:") 2
- (sep [ppr ty1, char '~', ppr ty2])
- in mkErrorMsg ctxt ct (occCheckMsg $$ extra)
+ = do { let occCheckMsg = hang (text "Occurs check: cannot construct the infinite type:")
+ 2 (sep [ppr ty1, char '~', ppr ty2])
+ ; (ctxt', extra2) <- mkEqInfoMsg ctxt ct ty1 ty2
+ ; mkErrorMsg ctxt' ct (occCheckMsg $$ extra2 $$ extra) }
-- Check for skolem escape
| (implic:_) <- cec_encl ctxt -- Get the innermost context
@@ -701,7 +702,7 @@ isUserSkolem ctxt tv
is_user_skol_info _ = True
misMatchOrCND :: ReportErrCtxt -> Ct -> Maybe SwapFlag -> TcType -> TcType -> SDoc
--- If oriented then ty1 is expected, ty2 is actual
+-- If oriented then ty1 is actual, ty2 is expected
misMatchOrCND ctxt ct oriented ty1 ty2
| null givens ||
(isRigid ty1 && isRigid ty2) ||
@@ -713,7 +714,7 @@ misMatchOrCND ctxt ct oriented ty1 ty2
= couldNotDeduce givens ([mkEqPred ty1 ty2], orig)
where
givens = getUserGivens ctxt
- orig = TypeEqOrigin ty1 ty2
+ orig = TypeEqOrigin { uo_actual = ty1, uo_expected = ty2 }
couldNotDeduce :: [UserGiven] -> (ThetaType, CtOrigin) -> SDoc
couldNotDeduce givens (wanteds, orig)
@@ -767,13 +768,13 @@ kindErrorMsg ty1 ty2
--------------------
misMatchMsg :: Maybe SwapFlag -> TcType -> TcType -> SDoc -- Types are already tidy
--- If oriented then ty1 is expected, ty2 is actual
+-- If oriented then ty1 is actual, ty2 is expected
misMatchMsg oriented ty1 ty2
| Just IsSwapped <- oriented
= misMatchMsg (Just NotSwapped) ty2 ty1
| Just NotSwapped <- oriented
- = sep [ ptext (sLit "Couldn't match expected") <+> what <+> quotes (ppr ty1)
- , nest 12 $ ptext (sLit "with actual") <+> what <+> quotes (ppr ty2) ]
+ = sep [ ptext (sLit "Couldn't match expected") <+> what <+> quotes (ppr ty2)
+ , nest 12 $ ptext (sLit "with actual") <+> what <+> quotes (ppr ty1) ]
| otherwise
= sep [ ptext (sLit "Couldn't match") <+> what <+> quotes (ppr ty1)
, nest 14 $ ptext (sLit "with") <+> quotes (ppr ty2) ]
@@ -782,9 +783,10 @@ misMatchMsg oriented ty1 ty2
| otherwise = ptext (sLit "type")
mkExpectedActualMsg :: Type -> Type -> CtOrigin -> (Maybe SwapFlag, SDoc)
+-- NotSwapped means (actual, expected), IsSwapped is the reverse
mkExpectedActualMsg ty1 ty2 (TypeEqOrigin { uo_actual = act, uo_expected = exp })
- | act `pickyEqType` ty1, exp `pickyEqType` ty2 = (Just IsSwapped, empty)
- | exp `pickyEqType` ty1, act `pickyEqType` ty2 = (Just NotSwapped, empty)
+ | act `pickyEqType` ty1, exp `pickyEqType` ty2 = (Just NotSwapped, empty)
+ | exp `pickyEqType` ty1, act `pickyEqType` ty2 = (Just IsSwapped, empty)
| otherwise = (Nothing, msg)
where
msg = vcat [ text "Expected type:" <+> ppr exp
diff --git a/compiler/typecheck/TcExpr.lhs b/compiler/typecheck/TcExpr.lhs
index e21eb4e4da..9075033ff2 100644
--- a/compiler/typecheck/TcExpr.lhs
+++ b/compiler/typecheck/TcExpr.lhs
@@ -823,8 +823,7 @@ tcExpr (PArrSeq _ _) _
#ifdef GHCI /* Only if bootstrapped */
-- Rename excludes these cases otherwise
tcExpr (HsSpliceE splice) res_ty = tcSpliceExpr splice res_ty
-tcExpr (HsBracket brack) res_ty = do { e <- tcBracket brack res_ty
- ; return (unLoc e) }
+tcExpr (HsBracket brack) res_ty = tcBracket brack res_ty
tcExpr e@(HsQuasiQuoteE _) _ =
pprPanic "Should never see HsQuasiQuoteE in type checker" (ppr e)
#endif /* GHCI */
diff --git a/compiler/typecheck/TcHsType.lhs b/compiler/typecheck/TcHsType.lhs
index 122e510c6b..70559f7e7c 100644
--- a/compiler/typecheck/TcHsType.lhs
+++ b/compiler/typecheck/TcHsType.lhs
@@ -74,6 +74,7 @@ import Outputable
import FastString
import Util
+import Data.Maybe
import Control.Monad ( unless, when, zipWithM )
import PrelNames( ipClassName, funTyConKey )
\end{code}
@@ -278,7 +279,7 @@ tcHsLiftedType ty = addTypeCtxt ty $ tc_lhs_type ty ekLifted
tcCheckLHsType :: LHsType Name -> Kind -> TcM Type
tcCheckLHsType hs_ty exp_kind
= addTypeCtxt hs_ty $
- tc_lhs_type hs_ty (EK exp_kind (ptext (sLit "Expected")))
+ tc_lhs_type hs_ty (EK exp_kind expectedKindMsg)
tcLHsType :: LHsType Name -> TcM (TcType, TcKind)
-- Called from outside: set the context
@@ -290,7 +291,7 @@ tcCheckHsTypeAndGen :: HsType Name -> Kind -> TcM Type
-- Typecheck a type signature, and kind-generalise it
-- The result is not necessarily zonked, and has not been checked for validity
tcCheckHsTypeAndGen hs_ty kind
- = do { ty <- tc_hs_type hs_ty (EK kind (ptext (sLit "Expected")))
+ = do { ty <- tc_hs_type hs_ty (EK kind expectedKindMsg)
; kvs <- kindGeneralize (tyVarsOfType ty) []
; return (mkForAllTys kvs ty) }
\end{code}
@@ -304,7 +305,7 @@ the expected kind.
tc_infer_lhs_type :: LHsType Name -> TcM (TcType, TcKind)
tc_infer_lhs_type ty =
do { kv <- newMetaKindVar
- ; r <- tc_lhs_type ty (EK kv (ptext (sLit "Expected")))
+ ; r <- tc_lhs_type ty (EK kv expectedKindMsg)
; return (r, kv) }
tc_lhs_type :: LHsType Name -> ExpKind -> TcM TcType
@@ -426,8 +427,8 @@ tc_hs_type hs_ty@(HsExplicitListTy _k tys) exp_kind
; checkExpectedKind hs_ty (mkPromotedListTy kind) exp_kind
; return (foldr (mk_cons kind) (mk_nil kind) taus) }
where
- mk_cons k a b = mkTyConApp (buildPromotedDataCon consDataCon) [k, a, b]
- mk_nil k = mkTyConApp (buildPromotedDataCon nilDataCon) [k]
+ mk_cons k a b = mkTyConApp (promoteDataCon consDataCon) [k, a, b]
+ mk_nil k = mkTyConApp (promoteDataCon nilDataCon) [k]
tc_hs_type hs_ty@(HsExplicitTupleTy _ tys) exp_kind
= do { tks <- mapM tc_infer_lhs_type tys
@@ -441,8 +442,7 @@ tc_hs_type hs_ty@(HsExplicitTupleTy _ tys) exp_kind
--------- Constraint types
tc_hs_type ipTy@(HsIParamTy n ty) exp_kind
- = do { ty' <- tc_lhs_type ty
- (EK liftedTypeKind (ptext (sLit "The type argument of the implicit parameter had")))
+ = do { ty' <- tc_lhs_type ty ekLifted
; checkExpectedKind ipTy constraintKind exp_kind
; ipClass <- tcLookupClass ipClassName
; let n' = mkStrLitTy $ hsIPNameFS n
@@ -453,16 +453,21 @@ tc_hs_type ty@(HsEqTy ty1 ty2) exp_kind
= do { (ty1', kind1) <- tc_infer_lhs_type ty1
; (ty2', kind2) <- tc_infer_lhs_type ty2
; checkExpectedKind ty2 kind2
- (EK kind1 (ptext (sLit "The left argument of the equality predicate had")))
+ (EK kind1 msg_fn)
; checkExpectedKind ty constraintKind exp_kind
; return (mkNakedTyConApp eqTyCon [kind1, ty1', ty2']) }
+ where
+ msg_fn pkind = ptext (sLit "The left argument of the equality had kind")
+ <+> quotes (pprKind pkind)
--------- Misc
tc_hs_type (HsKindSig ty sig_k) exp_kind
= do { sig_k' <- tcLHsKind sig_k
; checkExpectedKind ty sig_k' exp_kind
- ; tc_lhs_type ty
- (EK sig_k' (ptext (sLit "An enclosing kind signature specified"))) }
+ ; tc_lhs_type ty (EK sig_k' msg_fn) }
+ where
+ msg_fn pkind = ptext (sLit "The signature specified kind")
+ <+> quotes (pprKind pkind)
tc_hs_type (HsCoreTy ty) exp_kind
= do { checkExpectedKind ty (typeKind ty) exp_kind
@@ -602,12 +607,10 @@ tcTyVar name -- Could be a tyvar, a tycon, or a datacon
AGlobal (ATyCon tc) -> inst_tycon (mkTyConApp tc) (tyConKind tc)
AGlobal (ADataCon dc)
- | isPromotableType ty -> inst_tycon (mkTyConApp tc) (tyConKind tc)
+ | Just tc <- promoteDataCon_maybe dc
+ -> inst_tycon (mkTyConApp tc) (tyConKind tc)
| otherwise -> failWithTc (quotes (ppr dc) <+> ptext (sLit "of type")
- <+> quotes (ppr ty) <+> ptext (sLit "is not promotable"))
- where
- ty = dataConUserType dc
- tc = buildPromotedDataCon dc
+ <+> quotes (ppr (dataConUserType dc)) <+> ptext (sLit "is not promotable"))
APromotionErr err -> promotionErr name err
@@ -822,11 +825,13 @@ kcScopedKindVars kv_ns thing_inside
-- NB: use mutable signature variables
; tcExtendTyVarEnv2 (kv_ns `zip` kvs) thing_inside }
-kcHsTyVarBndrs :: Bool -- Default UserTyVar to *
+kcHsTyVarBndrs :: Bool -- True <=> full kind signature provided
+ -- Default UserTyVar to *
-- and use KindVars not meta kind vars
-> LHsTyVarBndrs Name
-> ([TcKind] -> TcM r)
-> TcM r
+-- Used in getInitialKind
kcHsTyVarBndrs full_kind_sig (HsQTvs { hsq_kvs = kv_ns, hsq_tvs = hs_tvs }) thing_inside
= do { kvs <- if full_kind_sig
then return (map mkKindSigVar kv_ns)
@@ -845,6 +850,14 @@ kcHsTyVarBndrs full_kind_sig (HsQTvs { hsq_kvs = kv_ns, hsq_tvs = hs_tvs }) thin
; return (n, kind) }
kc_hs_tv (KindedTyVar n k)
= do { kind <- tcLHsKind k
+ -- In an associated type decl, the type variable may already
+ -- be in scope; in that case we want to make sure its kind
+ -- matches the one declared here
+ ; mb_thing <- tcLookupLcl_maybe n
+ ; case mb_thing of
+ Nothing -> return ()
+ Just (AThing ks) -> checkKind kind ks
+ Just thing -> pprPanic "check_in_scope" (ppr thing)
; return (n, kind) }
tcScopedKindVars :: [Name] -> TcM a -> TcM a
@@ -967,38 +980,29 @@ kcLookupKind nm
AGlobal (ATyCon tc) -> return (tyConKind tc)
_ -> pprPanic "kcLookupKind" (ppr tc_ty_thing) }
-kcTyClTyVars :: Name -> LHsTyVarBndrs Name -> (TcKind -> TcM a) -> TcM a
+kcTyClTyVars :: Name -> LHsTyVarBndrs Name -> TcM a -> TcM a
-- Used for the type variables of a type or class decl,
-- when doing the initial kind-check.
kcTyClTyVars name (HsQTvs { hsq_kvs = kvs, hsq_tvs = hs_tvs }) thing_inside
= kcScopedKindVars kvs $
do { tc_kind <- kcLookupKind name
- ; let (arg_ks, res_k) = splitKindFunTysN (length hs_tvs) tc_kind
+ ; let (arg_ks, _res_k) = splitKindFunTysN (length hs_tvs) tc_kind
-- There should be enough arrows, because
-- getInitialKinds used the tcdTyVars
; name_ks <- zipWithM kc_tv hs_tvs arg_ks
- ; tcExtendKindEnv name_ks (thing_inside res_k) }
+ ; tcExtendKindEnv name_ks thing_inside }
where
+ -- getInitialKind has already gotten the kinds of these type
+ -- variables, but tiresomely we need to check them *again*
+ -- to match the kind variables they mention against the ones
+ -- we've freshly brought into scope
kc_tv :: LHsTyVarBndr Name -> Kind -> TcM (Name, Kind)
kc_tv (L _ (UserTyVar n)) exp_k
- = do { check_in_scope n exp_k
- ; return (n, exp_k) }
+ = return (n, exp_k)
kc_tv (L _ (KindedTyVar n hs_k)) exp_k
= do { k <- tcLHsKind hs_k
; checkKind k exp_k
- ; check_in_scope n exp_k
- ; return (n, k) }
-
- check_in_scope :: Name -> Kind -> TcM ()
- -- In an associated type decl, the type variable may already
- -- be in scope; in that case we want to make sure it matches
- -- any signature etc here
- check_in_scope n exp_k
- = do { mb_thing <- tcLookupLcl_maybe n
- ; case mb_thing of
- Nothing -> return ()
- Just (AThing k) -> checkKind k exp_k
- Just thing -> pprPanic "check_in_scope" (ppr thing) }
+ ; return (n, exp_k) }
-----------------------
tcTyClTyVars :: Name -> LHsTyVarBndrs Name -- LHS of the type or class decl
@@ -1268,21 +1272,36 @@ We would like to get a decent error message from
-- The ExpKind datatype means "expected kind" and contains
-- some info about just why that kind is expected, to improve
-- the error message on a mis-match
-data ExpKind = EK TcKind SDoc
+data ExpKind = EK TcKind (TcKind -> SDoc)
+ -- The second arg is function that takes a *tidied* version
+ -- of the first arg, and produces something like
+ -- "Expected kind k"
+ -- "Expected a constraint"
+ -- "The argument of Maybe should have kind k"
instance Outputable ExpKind where
- ppr (EK k _) = ptext (sLit "Expected kind:") <+> ppr k
+ ppr (EK k f) = f k
ekLifted, ekOpen, ekConstraint :: ExpKind
-ekLifted = EK liftedTypeKind (ptext (sLit "Expected"))
-ekOpen = EK openTypeKind (ptext (sLit "Expected"))
-ekConstraint = EK constraintKind (ptext (sLit "Expected"))
+ekLifted = EK liftedTypeKind expectedKindMsg
+ekOpen = EK openTypeKind expectedKindMsg
+ekConstraint = EK constraintKind expectedKindMsg
+
+expectedKindMsg :: TcKind -> SDoc
+expectedKindMsg pkind
+ | isConstraintKind pkind = ptext (sLit "Expected a constraint")
+ | isOpenTypeKind pkind = ptext (sLit "Expected a type")
+ | otherwise = ptext (sLit "Expected kind") <+> quotes (pprKind pkind)
-- Build an ExpKind for arguments
expArgKind :: SDoc -> TcKind -> Int -> ExpKind
-expArgKind exp kind arg_no = EK kind (ptext (sLit "The") <+> speakNth arg_no
- <+> ptext (sLit "argument of") <+> exp
- <+> ptext (sLit "should have"))
+expArgKind exp kind arg_no = EK kind msg_fn
+ where
+ msg_fn pkind
+ = sep [ ptext (sLit "The") <+> speakNth arg_no
+ <+> ptext (sLit "argument of") <+> exp
+ , nest 2 $ ptext (sLit "should have kind")
+ <+> quotes (pprKind pkind) ]
unifyKinds :: SDoc -> [(TcType, TcKind)] -> TcM TcKind
unifyKinds fun act_kinds
@@ -1306,9 +1325,8 @@ checkExpectedKind :: Outputable a => a -> TcKind -> ExpKind -> TcM ()
-- checks that the actual kind act_kind is compatible
-- with the expected kind exp_kind
-- The first argument, ty, is used only in the error message generation
-checkExpectedKind ty act_kind ek@(EK exp_kind ek_ctxt)
- = do { traceTc "checkExpectedKind" (ppr ty $$ ppr act_kind $$ ppr ek)
- ; mb_subk <- unifyKindX act_kind exp_kind
+checkExpectedKind ty act_kind (EK exp_kind ek_ctxt)
+ = do { mb_subk <- unifyKindX act_kind exp_kind
-- Kind unification only generates definite errors
; case mb_subk of {
@@ -1320,6 +1338,7 @@ checkExpectedKind ty act_kind ek@(EK exp_kind ek_ctxt)
-- Now to find out what sort
exp_kind <- zonkTcKind exp_kind
; act_kind <- zonkTcKind act_kind
+ ; traceTc "checkExpectedKind" (ppr ty $$ ppr act_kind $$ ppr exp_kind)
; env0 <- tcInitTidyEnv
; let (exp_as, _) = splitKindFunTys exp_kind
(act_as, _) = splitKindFunTys act_kind
@@ -1330,21 +1349,15 @@ checkExpectedKind ty act_kind ek@(EK exp_kind ek_ctxt)
(env1, tidy_exp_kind) = tidyOpenKind env0 exp_kind
(env2, tidy_act_kind) = tidyOpenKind env1 act_kind
- err | n_exp_as < n_act_as -- E.g. [Maybe]
- = ptext (sLit "Expecting") <+>
- speakN n_diff_as <+> ptext (sLit "more argument") <>
- (if n_diff_as > 1 then char 's' else empty) <+>
- ptext (sLit "to") <+> quotes (ppr ty)
+ occurs_check
+ | Just act_tv <- tcGetTyVar_maybe act_kind
+ = isNothing (occurCheckExpand act_tv exp_kind)
+ | Just exp_tv <- tcGetTyVar_maybe exp_kind
+ = isNothing (occurCheckExpand exp_tv act_kind)
+ | otherwise
+ = False
- -- Now n_exp_as >= n_act_as. In the next two cases,
- -- n_exp_as == 0, and hence so is n_act_as
- | isConstraintKind tidy_act_kind
- = text "Predicate" <+> quotes (ppr ty) <+> text "used as a type"
-
- | isConstraintKind tidy_exp_kind
- = text "Type of kind" <+> ppr tidy_act_kind <+> text "used as a constraint"
-
- | isLiftedTypeKind exp_kind && isUnliftedTypeKind act_kind
+ err | isLiftedTypeKind exp_kind && isUnliftedTypeKind act_kind
= ptext (sLit "Expecting a lifted type, but") <+> quotes (ppr ty)
<+> ptext (sLit "is unlifted")
@@ -1352,14 +1365,26 @@ checkExpectedKind ty act_kind ek@(EK exp_kind ek_ctxt)
= ptext (sLit "Expecting an unlifted type, but") <+> quotes (ppr ty)
<+> ptext (sLit "is lifted")
+ | occurs_check -- Must precede the "more args expected" check
+ = ptext (sLit "Kind occurs check") $$ more_info
+
+ | n_exp_as < n_act_as -- E.g. [Maybe]
+ = vcat [ ptext (sLit "Expecting") <+>
+ speakN n_diff_as <+> ptext (sLit "more argument")
+ <> (if n_diff_as > 1 then char 's' else empty)
+ <+> ptext (sLit "to") <+> quotes (ppr ty)
+ , more_info ]
+
+ -- Now n_exp_as >= n_act_as. In the next two cases,
+ -- n_exp_as == 0, and hence so is n_act_as
| otherwise -- E.g. Monad [Int]
- = ptext (sLit "Kind mis-match") $$ more_info
+ = more_info
- more_info = sep [ ek_ctxt <+> ptext (sLit "kind")
- <+> quotes (pprKind tidy_exp_kind) <> comma,
- ptext (sLit "but") <+> quotes (ppr ty) <+>
- ptext (sLit "has kind") <+> quotes (pprKind tidy_act_kind)]
+ more_info = sep [ ek_ctxt tidy_exp_kind <> comma
+ , nest 2 $ ptext (sLit "but") <+> quotes (ppr ty)
+ <+> ptext (sLit "has kind") <+> quotes (pprKind tidy_act_kind)]
+ ; traceTc "checkExpectedKind 1" (ppr ty $$ ppr tidy_act_kind $$ ppr tidy_exp_kind $$ ppr env1 $$ ppr env2)
; failWithTcM (env2, err) } } }
\end{code}
@@ -1439,7 +1464,7 @@ tc_kind_var_app name arg_kis
; unless data_kinds $ addErr (dataKindsErr name)
; case isPromotableTyCon tc of
Just n | n == length arg_kis ->
- return (mkTyConApp (buildPromotedTyCon tc) arg_kis)
+ return (mkTyConApp (promoteTyCon tc) arg_kis)
Just _ -> tycon_err tc "is not fully applied"
Nothing -> tycon_err tc "is not promotable" }
diff --git a/compiler/typecheck/TcInteract.lhs b/compiler/typecheck/TcInteract.lhs
index db7f36297f..a75890f70a 100644
--- a/compiler/typecheck/TcInteract.lhs
+++ b/compiler/typecheck/TcInteract.lhs
@@ -182,6 +182,7 @@ runSolverPipeline pipeline workItem
ContinueWith ct -> do { traceFireTcS ct (ptext (sLit "Kept as inert:") <+> ppr ct)
; traceTcS "End solver pipeline (not discharged) }" $
vcat [ ptext (sLit "final_item = ") <+> ppr ct
+ , pprTvBndrs (varSetElems $ tyVarsOfCt ct)
, ptext (sLit "inerts = ") <+> ppr final_is]
; insertInertItemTcS ct }
}
@@ -235,26 +236,6 @@ thePipeline = [ ("canonicalization", TcCanonical.canonicalize)
* *
*********************************************************************************
-Note [Efficient Orientation]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-There are two cases where we have to be careful about
-orienting equalities to get better efficiency.
-
-Case 1: In Rewriting Equalities (function rewriteEqLHS)
-
- When rewriting two equalities with the same LHS:
- (a) (tv ~ xi1)
- (b) (tv ~ xi2)
- We have a choice of producing work (xi1 ~ xi2) (up-to the
- canonicalization invariants) However, to prevent the inert items
- from getting kicked out of the inerts first, we prefer to
- canonicalize (xi1 ~ xi2) if (b) comes from the inert set, or (xi2
- ~ xi1) if (a) comes from the inert set.
-
-Case 2: Functional Dependencies
- Again, we should prefer, if possible, the inert variables on the RHS
-
\begin{code}
spontaneousSolveStage :: SimplifierStage
spontaneousSolveStage workItem
@@ -707,7 +688,8 @@ doInteractWithInert ii@(CFunEqCan { cc_ev = ev1, cc_fun = tc1
, cc_tyargs = args1, cc_rhs = xi1, cc_loc = d1 })
wi@(CFunEqCan { cc_ev = ev2, cc_fun = tc2
, cc_tyargs = args2, cc_rhs = xi2, cc_loc = d2 })
- | fl1 `canSolve` fl2
+ | i_solves_w && (not (w_solves_i && isMetaTyVarTy xi1))
+ -- See Note [Carefully solve the right CFunEqCan]
= ASSERT( lhss_match ) -- extractRelevantInerts ensures this
do { traceTcS "interact with inerts: FunEq/FunEq" $
vcat [ text "workItem =" <+> ppr wi
@@ -721,8 +703,8 @@ doInteractWithInert ii@(CFunEqCan { cc_ev = ev1, cc_fun = tc1
xdecomp x = [EvCoercion (mk_sym_co x `mkTcTransCo` co1)]
; ctevs <- xCtFlavor ev2 [mkTcEqPred xi2 xi1] xev
- -- No caching! See Note [Cache-caused loops]
- -- Why not (mkTcEqPred xi1 xi2)? See Note [Efficient orientation]
+ -- No caching! See Note [Cache-caused loops]
+ -- Why not (mkTcEqPred xi1 xi2)? See Note [Efficient orientation]
; emitWorkNC d2 ctevs
; return (IRWorkItemConsumed "FunEq/FunEq") }
@@ -740,7 +722,7 @@ doInteractWithInert ii@(CFunEqCan { cc_ev = ev1, cc_fun = tc1
xdecomp x = [EvCoercion (mkTcSymCo co2 `mkTcTransCo` evTermCoercion x)]
; ctevs <- xCtFlavor ev1 [mkTcEqPred xi2 xi1] xev
- -- Why not (mkTcEqPred xi1 xi2)? See Note [Efficient orientation]
+ -- Why not (mkTcEqPred xi1 xi2)? See Note [Efficient orientation]
; emitWorkNC d1 ctevs
; return (IRInertConsumed "FunEq/FunEq") }
@@ -751,11 +733,59 @@ doInteractWithInert ii@(CFunEqCan { cc_ev = ev1, cc_fun = tc1
mk_sym_co x = mkTcSymCo (evTermCoercion x)
fl1 = ctEvFlavour ev1
fl2 = ctEvFlavour ev2
+
+ i_solves_w = fl1 `canSolve` fl2
+ w_solves_i = fl2 `canSolve` fl1
-doInteractWithInert _ _ = return (IRKeepGoing "NOP")
+doInteractWithInert _ _ = return (IRKeepGoing "NOP")
\end{code}
+Note [Efficient Orientation]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Suppose we are interacting two FunEqCans with the same LHS:
+ (inert) ci :: (F ty ~ xi_i)
+ (work) cw :: (F ty ~ xi_w)
+We prefer to keep the inert (else we pass the work item on down
+the pipeline, which is a bit silly). If we keep the inert, we
+will (a) discharge 'cw'
+ (b) produce a new equality work-item (xi_w ~ xi_i)
+Notice the orientation (xi_w ~ xi_i) NOT (xi_i ~ xi_w):
+ new_work :: xi_w ~ xi_i
+ cw := ci ; sym new_work
+Why? Consider the simplest case when xi1 is a type variable. If
+we generate xi1~xi2, porcessing that constraint will kick out 'ci'.
+If we generate xi2~xi1, there is less chance of that happening.
+Of course it can and should still happen if xi1=a, xi1=Int, say.
+But we want to avoid it happening needlessly.
+
+Similarly, if we *can't* keep the inert item (because inert is Wanted,
+and work is Given, say), we prefer to orient the new equality (xi_i ~
+xi_w).
+
+Note [Carefully solve the right CFunEqCan]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider the constraints
+ c1 :: F Int ~ a -- Arising from an application line 5
+ c2 :: F Int ~ Bool -- Arising from an application line 10
+Suppose that 'a' is a unification variable, arising only from
+flattening. So there is no error on line 5; it's just a flattening
+variable. But there is (or might be) an error on line 10.
+
+Two ways to combine them, leaving either (Plan A)
+ c1 :: F Int ~ a -- Arising from an application line 5
+ c3 :: a ~ Bool -- Arising from an application line 10
+or (Plan B)
+ c2 :: F Int ~ Bool -- Arising from an application line 10
+ c4 :: a ~ Bool -- Arising from an application line 5
+
+Plan A will unify c3, leaving c1 :: F Int ~ Bool as an error
+on the *totally innocent* line 5. An example is test SimpleFail16
+where the expected/actual message comes out backwards if we use
+the wrong plan.
+
+The second is the right thing to do. Hence the isMetaTyVarTy
+test when solving pairwise CFunEqCan.
Note [Shadowing of Implicit Parameters]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/compiler/typecheck/TcMType.lhs b/compiler/typecheck/TcMType.lhs
index 7a3db58e7c..afc575caf7 100644
--- a/compiler/typecheck/TcMType.lhs
+++ b/compiler/typecheck/TcMType.lhs
@@ -993,21 +993,16 @@ checkValidType :: UserTypeCtxt -> Type -> TcM ()
-- Not used for instance decls; checkValidInstance instead
checkValidType ctxt ty
= do { traceTc "checkValidType" (ppr ty <+> text "::" <+> ppr (typeKind ty))
- ; rank2_flag <- xoptM Opt_Rank2Types
- ; rankn_flag <- xoptM Opt_RankNTypes
- ; polycomp <- xoptM Opt_PolymorphicComponents
+ ; rankn_flag <- xoptM Opt_RankNTypes
; let gen_rank :: Rank -> Rank
gen_rank r | rankn_flag = ArbitraryRank
- | rank2_flag = r2
| otherwise = r
- rank2 = gen_rank r2
rank1 = gen_rank r1
rank0 = gen_rank r0
r0 = rankZeroMonoType
r1 = LimitedRank True r0
- r2 = LimitedRank True r1
rank
= case ctxt of
@@ -1021,10 +1016,8 @@ checkValidType ctxt ty
ExprSigCtxt -> rank1
FunSigCtxt _ -> rank1
InfSigCtxt _ -> ArbitraryRank -- Inferred type
- ConArgCtxt _ | polycomp -> rank2
- -- We are given the type of the entire
- -- constructor, hence rank 1
- | otherwise -> rank1
+ ConArgCtxt _ -> rank1 -- We are given the type of the entire
+ -- constructor, hence rank 1
ForSigCtxt _ -> rank1
SpecInstCtxt -> rank1
diff --git a/compiler/typecheck/TcRnDriver.lhs b/compiler/typecheck/TcRnDriver.lhs
index 6aab6af632..66791b5170 100644
--- a/compiler/typecheck/TcRnDriver.lhs
+++ b/compiler/typecheck/TcRnDriver.lhs
@@ -1701,15 +1701,9 @@ tcRnGetInfo :: HscEnv
-- *and* as a type or class constructor;
-- hence the call to dataTcOccs, and we return up to two results
tcRnGetInfo hsc_env name
- = initTcPrintErrors hsc_env iNTERACTIVE $
- tcRnGetInfo' hsc_env name
-
-tcRnGetInfo' :: HscEnv
- -> Name
- -> TcRn (TyThing, Fixity, [ClsInst])
-tcRnGetInfo' hsc_env name
= let ictxt = hsc_IC hsc_env in
- setInteractiveContext hsc_env ictxt $ do
+ initTcPrintErrors hsc_env iNTERACTIVE $
+ setInteractiveContext hsc_env ictxt $ do
-- Load the interface for all unqualified types and classes
-- That way we will find all the instance declarations
diff --git a/compiler/typecheck/TcRnTypes.lhs b/compiler/typecheck/TcRnTypes.lhs
index 42e9d556ff..9c5249a615 100644
--- a/compiler/typecheck/TcRnTypes.lhs
+++ b/compiler/typecheck/TcRnTypes.lhs
@@ -909,10 +909,14 @@ data Ct
Note [Ct/evidence invariant]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If ct :: Ct, then extra fields of 'ct' cache precisely the ctev_pred field
-of (cc_ev ct). Eg for CDictCan,
+of (cc_ev ct), and is fully rewritten wrt the substitution. Eg for CDictCan,
ctev_pred (cc_ev ct) = (cc_class ct) (cc_tyargs ct)
This holds by construction; look at the unique place where CDictCan is
-built (in TcCanonical)
+built (in TcCanonical).
+
+In contrast, the type of the evidence *term* (ccev_evtm or ctev_evar) in
+the evidence may *not* be fully zonked; we are careful not to look at it
+during constraint solving. Seee Note [Evidence field of CtEvidence]
\begin{code}
mkNonCanonical :: CtLoc -> CtEvidence -> Ct
@@ -1228,13 +1232,13 @@ may be un-zonked.
\begin{code}
data CtEvidence
- = CtGiven { ctev_pred :: TcPredType
- , ctev_evtm :: EvTerm } -- See Note [Evidence field of CtEvidence]
+ = CtGiven { ctev_pred :: TcPredType -- See Note [Ct/evidence invariant]
+ , ctev_evtm :: EvTerm } -- See Note [Evidence field of CtEvidence]
-- Truly given, not depending on subgoals
-- NB: Spontaneous unifications belong here
- | CtWanted { ctev_pred :: TcPredType
- , ctev_evar :: EvVar } -- See Note [Evidence field of CtEvidence]
+ | CtWanted { ctev_pred :: TcPredType -- See Note [Ct/evidence invariant]
+ , ctev_evar :: EvVar } -- See Note [Evidence field of CtEvidence]
-- Wanted goal
| CtDerived { ctev_pred :: TcPredType }
diff --git a/compiler/typecheck/TcSMonad.lhs b/compiler/typecheck/TcSMonad.lhs
index 576df104a9..78fb0bf7e3 100644
--- a/compiler/typecheck/TcSMonad.lhs
+++ b/compiler/typecheck/TcSMonad.lhs
@@ -876,8 +876,8 @@ lookupFlatEqn fam_ty
, inert_flat_cache = flat_cache
, inert_cans = IC { inert_funeqs = inert_funeqs } } <- getTcSInerts
; return (lookupFamHead solved_funeqs fam_ty `firstJust`
- lookupFamHead flat_cache fam_ty `firstJust`
- lookup_in_inerts inert_funeqs) }
+ lookup_in_inerts inert_funeqs `firstJust`
+ lookupFamHead flat_cache fam_ty) }
where
lookup_in_inerts inert_funeqs
= case lookupFamHead inert_funeqs fam_ty of
diff --git a/compiler/typecheck/TcSimplify.lhs b/compiler/typecheck/TcSimplify.lhs
index 09a5b11c22..406fd3a812 100644
--- a/compiler/typecheck/TcSimplify.lhs
+++ b/compiler/typecheck/TcSimplify.lhs
@@ -75,7 +75,13 @@ simplifyTop wanteds
simpl_top :: WantedConstraints -> TcS WantedConstraints
simpl_top wanteds
= do { wc_first_go <- nestTcS (solve_wanteds_and_drop wanteds)
- ; applyTyVarDefaulting wc_first_go
+ ; let meta_tvs = filter isMetaTyVar (varSetElems (tyVarsOfWC wc_first_go))
+ -- tyVarsOfWC: post-simplification the WC should reflect
+ -- all unifications that have happened
+ -- filter isMetaTyVar: we might have runtime-skolems in GHCi,
+ -- and we definitely don't want to try to assign to those!
+
+ ; mapM_ defaultTyVar meta_tvs -- Has unification side effects
; simpl_top_loop wc_first_go }
simpl_top_loop wc
@@ -341,13 +347,8 @@ simplifyInfer _top_lvl apply_mr name_taus wanteds
; return (qtvs, [], False, emptyTcEvBinds) }
| otherwise
- = do { zonked_tau_tvs <- zonkTyVarsAndFV (tyVarsOfTypes (map snd name_taus))
-
- ; ev_binds_var <- newTcEvBinds
- ; traceTc "simplifyInfer {" $ vcat
- [ ptext (sLit "names =") <+> ppr (map fst name_taus)
- , ptext (sLit "taus =") <+> ppr (map snd name_taus)
- , ptext (sLit "tau_tvs (zonked) =") <+> ppr zonked_tau_tvs
+ = do { traceTc "simplifyInfer {" $ vcat
+ [ ptext (sLit "binds =") <+> ppr name_taus
, ptext (sLit "closed =") <+> ppr _top_lvl
, ptext (sLit "apply_mr =") <+> ppr apply_mr
, ptext (sLit "(unzonked) wanted =") <+> ppr wanteds
@@ -367,6 +368,8 @@ simplifyInfer _top_lvl apply_mr name_taus wanteds
-- calling solveWanteds will side-effect their evidence
-- bindings, so we can't just revert to the input
-- constraint.
+
+ ; ev_binds_var <- newTcEvBinds
; wanted_transformed <- solveWantedsTcMWithEvBinds ev_binds_var wanteds $
solve_wanteds_and_drop
-- Post: wanted_transformed are zonked
@@ -381,29 +384,29 @@ simplifyInfer _top_lvl apply_mr name_taus wanteds
-- We discard bindings, insolubles etc, because all we are
-- care aout it
- ; (quant_pred_candidates, _extra_binds)
- <- if insolubleWC wanted_transformed
- then return ([], emptyBag) -- See Note [Quantification with errors]
- else runTcS $
- do { let quant_candidates = approximateWC wanted_transformed
- ; traceTcS "simplifyWithApprox" $
- text "quant_candidates = " <+> ppr quant_candidates
- ; promoteTyVars quant_candidates
- ; _implics <- solveInteract quant_candidates
- ; (flats, _insols) <- getInertUnsolved
+ ; tc_lcl_env <- TcRnMonad.getLclEnv
+ ; let untch = tcl_untch tc_lcl_env
+ ; quant_pred_candidates
+ <- if insolubleWC wanted_transformed
+ then return [] -- See Note [Quantification with errors]
+ else do { gbl_tvs <- tcGetGlobalTyVars
+ ; let quant_cand = approximateWC wanted_transformed
+ meta_tvs = filter isMetaTyVar (varSetElems (tyVarsOfCts quant_cand))
+ ; ((flats, _insols), _extra_binds) <- runTcS $
+ do { mapM_ (promoteAndDefaultTyVar untch gbl_tvs) meta_tvs
+ ; _implics <- solveInteract quant_cand
+ ; getInertUnsolved }
+ ; return (map ctPred $ filter isWantedCt (bagToList flats)) }
-- NB: Dimitrios is slightly worried that we will get
-- family equalities (F Int ~ alpha) in the quantification
-- candidates, as we have performed no further unflattening
-- at this point. Nothing bad, but inferred contexts might
-- look complicated.
- ; return (map ctPred $ filter isWantedCt (bagToList flats)) }
- -- NB: quant_pred_candidates is already the fixpoint of any
- -- unifications that may have happened
-
- ; gbl_tvs <- tcGetGlobalTyVars -- TODO: can we just use untch instead of gbl_tvs?
- ; zonked_tau_tvs <- zonkTyVarsAndFV zonked_tau_tvs
-
+ -- NB: quant_pred_candidates is already the fixpoint of any
+ -- unifications that may have happened
+ ; gbl_tvs <- tcGetGlobalTyVars
+ ; zonked_tau_tvs <- zonkTyVarsAndFV (tyVarsOfTypes (map snd name_taus))
; let init_tvs = zonked_tau_tvs `minusVarSet` gbl_tvs
poly_qtvs = growThetaTyVars quant_pred_candidates init_tvs
`minusVarSet` gbl_tvs
@@ -448,8 +451,7 @@ simplifyInfer _top_lvl apply_mr name_taus wanteds
-- Step 7) Emit an implication
; minimal_bound_ev_vars <- mapM TcMType.newEvVar minimal_flat_preds
- ; lcl_env <- TcRnMonad.getLclEnv
- ; let implic = Implic { ic_untch = pushUntouchables (tcl_untch lcl_env)
+ ; let implic = Implic { ic_untch = pushUntouchables untch
, ic_skols = qtvs_to_return
, ic_fsks = [] -- wanted_tansformed arose only from solveWanteds
-- hence no flatten-skolems (which come from givens)
@@ -458,7 +460,7 @@ simplifyInfer _top_lvl apply_mr name_taus wanteds
, ic_insol = False
, ic_binds = ev_binds_var
, ic_info = skol_info
- , ic_env = lcl_env }
+ , ic_env = tc_lcl_env }
; emitImplication implic
; traceTc "} simplifyInfer/produced residual implication for quantification" $
@@ -845,7 +847,8 @@ floatEqualities skols can_given wanteds@(WC { wc_flat = flats })
= return (emptyBag, wanteds) -- Note [Float Equalities out of Implications]
| otherwise
= do { let (float_eqs, remaining_flats) = partitionBag is_floatable flats
- ; promoteTyVars float_eqs
+ ; untch <- TcSMonad.getUntouchables
+ ; mapM_ (promoteTyVar untch) (varSetElems (tyVarsOfCts float_eqs))
; ty_binds <- getTcSTyBindsMap
; traceTcS "floatEqualities" (vcat [ text "Floated eqs =" <+> ppr float_eqs
, text "Ty binds =" <+> ppr ty_binds])
@@ -859,22 +862,6 @@ floatEqualities skols can_given wanteds@(WC { wc_flat = flats })
where
pred = ctPred ct
-promoteTyVars :: Cts -> TcS ()
--- When we float a constraint out of an implication we
--- must restore (MetaTvInv) in Note [Untouchable type variables]
--- in TcType
-promoteTyVars cts
- = do { untch <- TcSMonad.getUntouchables
- ; mapM_ (promote_tv untch) (varSetElems (tyVarsOfCts cts)) }
- where
- promote_tv untch tv
- | isFloatedTouchableMetaTyVar untch tv
- = do { cloned_tv <- TcSMonad.cloneMetaTyVar tv
- ; let rhs_tv = setMetaTyVarUntouchables cloned_tv untch
- ; setWantedTyBind tv (mkTyVarTy rhs_tv) }
- | otherwise
- = return ()
-
growSkols :: WantedConstraints -> VarSet -> VarSet
-- Find all the type variables that might possibly be unified
-- with a type that mentions a skolem. This test is very conservative.
@@ -885,17 +872,59 @@ growSkols (WC { wc_flat = flats }) skols
where
theta = foldrBag ((:) . ctPred) [] flats
+promoteTyVar :: Untouchables -> TcTyVar -> TcS ()
+-- When we float a constraint out of an implication we must restore
+-- invariant (MetaTvInv) in Note [Untouchable type variables] in TcType
+promoteTyVar untch tv
+ | isFloatedTouchableMetaTyVar untch tv
+ = do { cloned_tv <- TcSMonad.cloneMetaTyVar tv
+ ; let rhs_tv = setMetaTyVarUntouchables cloned_tv untch
+ ; setWantedTyBind tv (mkTyVarTy rhs_tv) }
+ | otherwise
+ = return ()
+
+promoteAndDefaultTyVar :: Untouchables -> TcTyVarSet -> TyVar -> TcS ()
+-- See Note [Promote _and_ default when inferring]
+promoteAndDefaultTyVar untch gbl_tvs tv
+ = do { tv1 <- if tv `elemVarSet` gbl_tvs
+ then return tv
+ else defaultTyVar tv
+ ; promoteTyVar untch tv1 }
+
+defaultTyVar :: TcTyVar -> TcS TcTyVar
+-- Precondition: MetaTyVars only
+-- See Note [DefaultTyVar]
+defaultTyVar the_tv
+ | not (k `eqKind` default_k)
+ = do { tv' <- TcSMonad.cloneMetaTyVar the_tv
+ ; let new_tv = setTyVarKind tv' default_k
+ ; traceTcS "defaultTyVar" (ppr the_tv <+> ppr new_tv)
+ ; setWantedTyBind the_tv (mkTyVarTy new_tv)
+ ; return new_tv }
+ -- Why not directly derived_pred = mkTcEqPred k default_k?
+ -- See Note [DefaultTyVar]
+ -- We keep the same Untouchables on tv'
+
+ | otherwise = return the_tv -- The common case
+ where
+ k = tyVarKind the_tv
+ default_k = defaultKind k
+
approximateWC :: WantedConstraints -> Cts
-- Postcondition: Wanted or Derived Cts
-approximateWC wc = float_wc emptyVarSet wc
+approximateWC wc
+ = float_wc emptyVarSet wc
where
float_wc :: TcTyVarSet -> WantedConstraints -> Cts
- float_wc skols (WC { wc_flat = flat, wc_impl = implic }) = floats1 `unionBags` floats2
- where floats1 = do_bag (float_flat skols) flat
- floats2 = do_bag (float_implic skols) implic
+ float_wc skols (WC { wc_flat = flats, wc_impl = implics })
+ = do_bag (float_flat skols) flats `unionBags`
+ do_bag (float_implic skols) implics
float_implic :: TcTyVarSet -> Implication -> Cts
float_implic skols imp
+ | hasEqualities (ic_given imp) -- Don't float out of equalities
+ = emptyCts -- cf floatEqualities
+ | otherwise -- See Note [approximateWC]
= float_wc skols' (ic_wanted imp)
where
skols' = skols `extendVarSetList` ic_skols imp `extendVarSetList` ic_fsks imp
@@ -910,6 +939,76 @@ approximateWC wc = float_wc emptyVarSet wc
do_bag f = foldrBag (unionBags.f) emptyBag
\end{code}
+Note [ApproximateWC]
+~~~~~~~~~~~~~~~~~~~~
+approximateWC takes a constraint, typically arising from the RHS of a
+let-binding whose type we are *inferring*, and extracts from it some
+*flat* constraints that we might plausibly abstract over. Of course
+the top-level flat constraints are plausible, but we also float constraints
+out from inside, if the are not captured by skolems.
+
+However we do *not* float anything out if the implication binds equality
+constriants, because that defeats the OutsideIn story. Consider
+ data T a where
+ TInt :: T Int
+ MkT :: T a
+
+ f TInt = 3::Int
+
+We get the implication (a ~ Int => res ~ Int), where so far we've decided
+ f :: T a -> res
+We don't want to float (res~Int) out because then we'll infer
+ f :: T a -> Int
+which is only on of the possible types. (GHC 7.6 accidentally *did*
+float out of such implications, which meant it would happily infer
+non-principal types.)
+
+Note [DefaultTyVar]
+~~~~~~~~~~~~~~~~~~~
+defaultTyVar is used on any un-instantiated meta type variables to
+default the kind of OpenKind and ArgKind etc to *. This is important
+to ensure that instance declarations match. For example consider
+
+ instance Show (a->b)
+ foo x = show (\_ -> True)
+
+Then we'll get a constraint (Show (p ->q)) where p has kind ArgKind,
+and that won't match the typeKind (*) in the instance decl. See tests
+tc217 and tc175.
+
+We look only at touchable type variables. No further constraints
+are going to affect these type variables, so it's time to do it by
+hand. However we aren't ready to default them fully to () or
+whatever, because the type-class defaulting rules have yet to run.
+
+An important point is that if the type variable tv has kind k and the
+default is default_k we do not simply generate [D] (k ~ default_k) because:
+
+ (1) k may be ArgKind and default_k may be * so we will fail
+
+ (2) We need to rewrite all occurrences of the tv to be a type
+ variable with the right kind and we choose to do this by rewriting
+ the type variable /itself/ by a new variable which does have the
+ right kind.
+
+Note [Promote _and_ default when inferring]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+When we are inferring a type, we simplify the constraint, and then use
+approximateWC to produce a list of candidate constraints. Then we MUST
+
+ a) Promote any meta-tyvars that have been floated out by
+ approximateWC, to restore invariant (MetaTvInv) described in
+ Note [Untouchable type variables] in TcType.
+
+ b) Default the kind of any meta-tyyvars that are not mentioned in
+ in the environment.
+
+To see (b), suppose the constraint is (C ((a :: OpenKind) -> Int)), and we
+have an instance (C ((x:*) -> Int)). The instance doesn't match -- but it
+should! If we don't solve the constraint, we'll stupidly quantify over
+(C (a->Int)) and, worse, in doing so zonkQuantifiedTyVar will quantify over
+(b:*) instead of (a:OpenKind), which can lead to disaster; see Trac #7332.
+
Note [Float Equalities out of Implications]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For ordinary pattern matches (including existentials) we float
@@ -1028,6 +1127,7 @@ in TcMType.
* Defaulting and disamgiguation *
* *
*********************************************************************************
+
\begin{code}
applyDefaultingRules :: Cts -> TcS Bool
-- True <=> I did some defaulting, reflected in ty_binds
@@ -1052,85 +1152,7 @@ applyDefaultingRules wanteds
; return (or something_happeneds) }
\end{code}
-Note [tryTcS in defaulting]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-defaultTyVar and disambigGroup create new evidence variables for
-default equations, and hence update the EvVar cache. However, after
-applyDefaultingRules we will try to solve these default equations
-using solveInteractCts, which will consult the cache and solve those
-EvVars from themselves! That's wrong.
-
-To avoid this problem we guard defaulting under a @tryTcS@ which leaves
-the original cache unmodified.
-
-There is a second reason for @tryTcS@ in defaulting: disambGroup does
-some constraint solving to determine if a default equation is
-``useful'' in solving some wanted constraints, but we want to
-discharge all evidence and unifications that may have happened during
-this constraint solving.
-
-Finally, @tryTcS@ importantly does not inherit the original cache from
-the higher level but makes up a new cache, the reason is that disambigGroup
-will call solveInteractCts so the new derived and the wanteds must not be
-in the cache!
-
-
-\begin{code}
-applyTyVarDefaulting :: WantedConstraints -> TcS ()
-applyTyVarDefaulting wc
- = do { let tvs = filter isMetaTyVar (varSetElems (tyVarsOfWC wc))
- -- tyVarsOfWC: post-simplification the WC should reflect
- -- all unifications that have happened
- -- filter isMetaTyVar: we might have runtime-skolems in GHCi,
- -- and we definitely don't want to try to assign to those!
-
- ; traceTcS "applyTyVarDefaulting {" (ppr tvs)
- ; mapM_ defaultTyVar tvs
- ; traceTcS "applyTyVarDefaulting end }" empty }
-
-defaultTyVar :: TcTyVar -> TcS ()
-defaultTyVar the_tv
- | not (k `eqKind` default_k)
- = do { tv' <- TcSMonad.cloneMetaTyVar the_tv
- ; let rhs_ty = mkTyVarTy (setTyVarKind tv' default_k)
- ; setWantedTyBind the_tv rhs_ty }
- -- Why not directly derived_pred = mkTcEqPred k default_k?
- -- See Note [DefaultTyVar]
- -- We keep the same Untouchables on tv'
-
- | otherwise = return () -- The common case
- where
- k = tyVarKind the_tv
- default_k = defaultKind k
-\end{code}
-
-Note [DefaultTyVar]
-~~~~~~~~~~~~~~~~~~~
-defaultTyVar is used on any un-instantiated meta type variables to
-default the kind of OpenKind and ArgKind etc to *. This is important
-to ensure that instance declarations match. For example consider
-
- instance Show (a->b)
- foo x = show (\_ -> True)
-
-Then we'll get a constraint (Show (p ->q)) where p has kind ArgKind,
-and that won't match the typeKind (*) in the instance decl. See tests
-tc217 and tc175.
-
-We look only at touchable type variables. No further constraints
-are going to affect these type variables, so it's time to do it by
-hand. However we aren't ready to default them fully to () or
-whatever, because the type-class defaulting rules have yet to run.
-
-An important point is that if the type variable tv has kind k and the
-default is default_k we do not simply generate [D] (k ~ default_k) because:
- (1) k may be ArgKind and default_k may be * so we will fail
-
- (2) We need to rewrite all occurrences of the tv to be a type
- variable with the right kind and we choose to do this by rewriting
- the type variable /itself/ by a new variable which does have the
- right kind.
\begin{code}
findDefaultableGroups
@@ -1192,29 +1214,26 @@ disambigGroup :: [Type] -- The default types
disambigGroup [] _grp
= return False
disambigGroup (default_ty:default_tys) group
- = do { traceTcS "disambigGroup" (ppr group $$ ppr default_ty)
- ; success <- tryTcS $ -- Why tryTcS? See Note [tryTcS in defaulting]
+ = do { traceTcS "disambigGroup {" (ppr group $$ ppr default_ty)
+ ; success <- tryTcS $ -- Why tryTcS? If this attempt fails, we want to
+ -- discard all side effects from the attempt
do { setWantedTyBind the_tv default_ty
- ; traceTcS "disambigGroup (solving) {" $
- text "trying to solve constraints along with default equations ..."
; implics_from_defaulting <- solveInteract wanteds
; MASSERT (isEmptyBag implics_from_defaulting)
-- I am not certain if any implications can be generated
-- but I am letting this fail aggressively if this ever happens.
- ; all_solved <- checkAllSolved
- ; traceTcS "disambigGroup (solving) }" $
- text "disambigGroup solved =" <+> ppr all_solved
- ; return all_solved }
+ ; checkAllSolved }
+
; if success then
-- Success: record the type variable binding, and return
do { setWantedTyBind the_tv default_ty
; wrapWarnTcS $ warnDefaulting wanteds default_ty
- ; traceTcS "disambigGroup succeeded" (ppr default_ty)
+ ; traceTcS "disambigGroup succeeded }" (ppr default_ty)
; return True }
else
-- Failure: try with the next type
- do { traceTcS "disambigGroup failed, will try other default types"
+ do { traceTcS "disambigGroup failed, will try other default types }"
(ppr default_ty)
; disambigGroup default_tys group } }
where
diff --git a/compiler/typecheck/TcSplice.lhs b/compiler/typecheck/TcSplice.lhs
index c5e09a3afa..d5acf6ca28 100644
--- a/compiler/typecheck/TcSplice.lhs
+++ b/compiler/typecheck/TcSplice.lhs
@@ -284,7 +284,7 @@ The predicate we use is TcEnv.thTopLevelId.
%************************************************************************
\begin{code}
-tcBracket :: HsBracket Name -> TcRhoType -> TcM (LHsExpr TcId)
+tcBracket :: HsBracket Name -> TcRhoType -> TcM (HsExpr TcId)
tcSpliceDecls :: LHsExpr Name -> TcM [LHsDecl RdrName]
tcSpliceExpr :: HsSplice Name -> TcRhoType -> TcM (HsExpr TcId)
tcSpliceType :: HsSplice Name -> FreeVars -> TcM (TcType, TcKind)
@@ -350,22 +350,22 @@ tcBracket brack res_ty
-- We build a single implication constraint with a BracketSkol;
-- that in turn tells simplifyTop to report only definite
-- errors
- ; (_,lie) <- captureConstraints $
- newImplication BracketSkol [] [] $
- setStage brack_stage $
- do { meta_ty <- tc_bracket cur_stage brack
- ; unifyType meta_ty res_ty }
+ ; ((_binds1, meta_ty), lie) <- captureConstraints $
+ newImplication BracketSkol [] [] $
+ setStage brack_stage $
+ tc_bracket cur_stage brack
-- It's best to simplify the constraint now, even though in
-- principle some later unification might be useful for it,
-- because we don't want these essentially-junk TH implication
-- contraints floating around nested inside other constraints
-- See for example Trac #4949
- ; _ <- simplifyTop lie
+ ; _binds2 <- simplifyTop lie
-- Return the original expression, not the type-decorated one
; pendings <- readMutVar pending_splices
- ; return (noLoc (HsBracketOut brack pendings)) }
+ ; co <- unifyType meta_ty res_ty
+ ; return (mkHsWrapCo co (HsBracketOut brack pendings)) }
tc_bracket :: ThStage -> HsBracket Name -> TcM TcType
tc_bracket outer_stage br@(VarBr _ name) -- Note [Quoting names]
diff --git a/compiler/typecheck/TcSplice.lhs-boot b/compiler/typecheck/TcSplice.lhs-boot
index de14aa3b95..4f185fb208 100644
--- a/compiler/typecheck/TcSplice.lhs-boot
+++ b/compiler/typecheck/TcSplice.lhs-boot
@@ -18,7 +18,7 @@ tcSpliceType :: HsSplice Name -> FreeVars -> TcM (TcType, TcKind)
tcBracket :: HsBracket Name
-> TcRhoType
- -> TcM (LHsExpr TcId)
+ -> TcM (HsExpr TcId)
tcSpliceDecls :: LHsExpr Name -> TcM [LHsDecl RdrName]
diff --git a/compiler/typecheck/TcTyClsDecls.lhs b/compiler/typecheck/TcTyClsDecls.lhs
index bbd0c93e6b..469635ef29 100644
--- a/compiler/typecheck/TcTyClsDecls.lhs
+++ b/compiler/typecheck/TcTyClsDecls.lhs
@@ -128,7 +128,7 @@ tcTyClGroup boot_details tyclds
-- Populate environment with knot-tied ATyCon for TyCons
-- NB: if the decls mention any ill-staged data cons
- -- (see Note [ARecDataCon: Recusion and promoting data constructors]
+ -- (see Note [Recusion and promoting data constructors]
-- we will have failed already in kcTyClGroup, so no worries here
; tcExtendRecEnv (zipRecTyClss names_w_poly_kinds rec_tyclss) $
@@ -324,8 +324,12 @@ getInitialKind :: TopLevelFlag -> TyClDecl Name -> TcM [(Name, TcTyThing)]
-- Example: data T a b = ...
-- return (T, kv1 -> kv2 -> kv3)
--
--- ALSO for each datacon, return (dc, ARecDataCon)
--- Note [ARecDataCon: Recusion and promoting data constructors]
+-- This pass deals with (ie incorporates into the kind it produces)
+-- * The kind signatures on type-variable binders
+-- * The result kinds signature on a TyClDecl
+--
+-- ALSO for each datacon, return (dc, APromotionErr RecDataConPE)
+-- Note [ARecDataCon: Recursion and promoting data constructors]
--
-- No family instances are passed to getInitialKinds
@@ -361,14 +365,15 @@ getInitialKind top_lvl decl@(TyDecl { tcdLName = L _ name, tcdTyVars = ktvs, tcd
kvs = varSetElems (tyVarsOfType body_kind)
main_pr = (name, AThing (mkForAllTys kvs body_kind))
inner_prs = [(unLoc (con_name con), APromotionErr RecDataConPE) | L _ con <- cons ]
- -- See Note [ARecDataCon: Recusion and promoting data constructors]
+ -- See Note [Recusion and promoting data constructors]
; return (main_pr : inner_prs) }
| TyData { td_cons = cons } <- defn
= kcHsTyVarBndrs False ktvs $ \ arg_kinds ->
do { let main_pr = (name, AThing (mkArrowKinds arg_kinds liftedTypeKind))
- inner_prs = [(unLoc (con_name con), APromotionErr RecDataConPE) | L _ con <- cons ]
- -- See Note [ARecDataCon: Recusion and promoting data constructors]
+ inner_prs = [ (unLoc (con_name con), APromotionErr RecDataConPE)
+ | L _ con <- cons ]
+ -- See Note [Recusion and promoting data constructors]
; return (main_pr : inner_prs) }
| otherwise = pprPanic "getInitialKind" (ppr decl)
@@ -413,13 +418,18 @@ kcLTyClDecl (L loc decl)
kcTyClDecl :: TyClDecl Name -> TcM ()
-- This function is used solely for its side effect on kind variables
+-- NB kind signatures on the type variables and
+-- result kind signature have aready been dealt with
+-- by getInitialKind, so we can ignore them here.
kcTyClDecl decl@(TyDecl { tcdLName = L _ name, tcdTyVars = hs_tvs, tcdTyDefn = defn })
| TyData { td_cons = cons, td_kindSig = Just _ } <- defn
- = mapM_ (wrapLocM kcConDecl) cons -- Ignore the td_ctxt; heavily deprecated and inconvenient
+ = mapM_ (wrapLocM kcConDecl) cons
+ -- hs_tvs and td_kindSig already dealt with in getInitialKind
+ -- Ignore the td_ctxt; heavily deprecated and inconvenient
| TyData { td_ctxt = ctxt, td_cons = cons } <- defn
- = kcTyClTyVars name hs_tvs $ \ _res_k ->
+ = kcTyClTyVars name hs_tvs $
do { _ <- tcHsContext ctxt
; mapM_ (wrapLocM kcConDecl) cons }
@@ -427,7 +437,7 @@ kcTyClDecl decl@(TyDecl { tcdLName = L _ name, tcdTyVars = hs_tvs, tcdTyDefn = d
kcTyClDecl (ClassDecl { tcdLName = L _ name, tcdTyVars = hs_tvs
, tcdCtxt = ctxt, tcdSigs = sigs, tcdATs = ats})
- = kcTyClTyVars name hs_tvs $ \ _res_k ->
+ = kcTyClTyVars name hs_tvs $
do { _ <- tcHsContext ctxt
; mapM_ (wrapLocM kcTyClDecl) ats
; mapM_ (wrapLocM kc_sig) sigs }
@@ -436,8 +446,8 @@ kcTyClDecl (ClassDecl { tcdLName = L _ name, tcdTyVars = hs_tvs
kc_sig (GenericSig _ op_ty) = discardResult (tcHsLiftedType op_ty)
kc_sig _ = return ()
-kcTyClDecl (ForeignType {}) = return ()
kcTyClDecl (TyFamily {}) = return ()
+kcTyClDecl (ForeignType {}) = return ()
-------------------
kcConDecl :: ConDecl Name -> TcM ()
@@ -451,8 +461,8 @@ kcConDecl (ConDecl { con_name = name, con_qvars = ex_tvs
; return () }
\end{code}
-Note [ARecDataCon: Recusion and promoting data constructors]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Note [Recursion and promoting data constructors]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We don't want to allow promotion in a strongly connected component
when kind checking.
diff --git a/compiler/typecheck/TcType.lhs b/compiler/typecheck/TcType.lhs
index b8594afcec..aa69d75e56 100644
--- a/compiler/typecheck/TcType.lhs
+++ b/compiler/typecheck/TcType.lhs
@@ -64,7 +64,7 @@ module TcType (
-- Predicates.
-- Again, newtypes are opaque
eqType, eqTypes, eqPred, cmpType, cmpTypes, cmpPred, eqTypeX,
- pickyEqType, eqKind,
+ pickyEqType, eqKind,
isSigmaTy, isOverloadedTy,
isDoubleTy, isFloatTy, isIntTy, isWordTy, isStringTy,
isIntegerTy, isBoolTy, isUnitTy, isCharTy,
@@ -74,7 +74,7 @@ module TcType (
---------------------------------
-- Misc type manipulators
- deNoteType,
+ deNoteType, occurCheckExpand,
orphNamesOfType, orphNamesOfDFunHead, orphNamesOfCo,
getDFunTyKey,
evVarPred_maybe, evVarPred,
@@ -554,25 +554,9 @@ tidyFreeTyVars :: TidyEnv -> TyVarSet -> TidyEnv
-- ^ Add the free 'TyVar's to the env in tidy form,
-- so that we can tidy the type they are free in
tidyFreeTyVars (full_occ_env, var_env) tyvars
- = fst (tidyOpenTyVars (trimmed_occ_env, var_env) tv_list)
+ = fst (tidyOpenTyVars (full_occ_env, var_env) (varSetElems tyvars))
- where
- tv_list = varSetElems tyvars
-
- trimmed_occ_env = foldr mk_occ_env emptyOccEnv tv_list
- -- The idea here is that we restrict the new TidyEnv to the
- -- _free_ vars of the type, so that we don't gratuitously rename
- -- the _bound_ variables of the type
-
- mk_occ_env :: TyVar -> TidyOccEnv -> TidyOccEnv
- mk_occ_env tv env
- = case lookupOccEnv full_occ_env occ of
- Just n -> extendOccEnv env occ n
- Nothing -> env
- where
- occ = getOccName tv
-
----------------
+ ---------------
tidyOpenTyVars :: TidyEnv -> [TyVar] -> (TidyEnv, [TyVar])
tidyOpenTyVars env tyvars = mapAccumL tidyOpenTyVar env tyvars
@@ -614,9 +598,13 @@ tidyType env (ForAllTy tv ty) = ForAllTy tvp $! (tidyType envp ty)
-- and then uses 'tidyType' to work over the type itself
tidyOpenType :: TidyEnv -> Type -> (TidyEnv, Type)
tidyOpenType env ty
- = (env', tidyType env' ty)
+ = (env', tidyType (trimmed_occ_env, var_env) ty)
where
- env' = tidyFreeTyVars env (tyVarsOfType ty)
+ (env'@(_, var_env), tvs') = tidyOpenTyVars env (varSetElems (tyVarsOfType ty))
+ trimmed_occ_env = initTidyOccEnv (map getOccName tvs')
+ -- The idea here was that we restrict the new TidyEnv to the
+ -- _free_ vars of the type, so that we don't gratuitously rename
+ -- the _bound_ variables of the type.
---------------
tidyOpenTypes :: TidyEnv -> [Type] -> (TidyEnv, [Type])
@@ -1174,6 +1162,84 @@ pickyEqType ty1 ty2
gos _ _ _ = False
\end{code}
+Note [Occurs check expansion]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+@occurCheckExpand tv xi@ expands synonyms in xi just enough to get rid
+of occurrences of tv outside type function arguments, if that is
+possible; otherwise, it returns Nothing.
+
+For example, suppose we have
+ type F a b = [a]
+Then
+ occurCheckExpand b (F Int b) = Just [Int]
+but
+ occurCheckExpand a (F a Int) = Nothing
+
+We don't promise to do the absolute minimum amount of expanding
+necessary, but we try not to do expansions we don't need to. We
+prefer doing inner expansions first. For example,
+ type F a b = (a, Int, a, [a])
+ type G b = Char
+We have
+ occurCheckExpand b (F (G b)) = F Char
+even though we could also expand F to get rid of b.
+
+See also Note [Type synonyms and canonicalization] in TcCanonical
+
+\begin{code}
+occurCheckExpand :: TcTyVar -> Type -> Maybe Type
+-- See Note [Occurs check expansion]
+-- Check whether the given variable occurs in the given type. We may
+-- have needed to do some type synonym unfolding in order to get rid
+-- of the variable, so we also return the unfolded version of the
+-- type, which is guaranteed to be syntactically free of the given
+-- type variable. If the type is already syntactically free of the
+-- variable, then the same type is returned.
+
+occurCheckExpand tv ty
+ | not (tv `elemVarSet` tyVarsOfType ty) = Just ty
+ | otherwise = go ty
+ where
+ go t@(TyVarTy tv') | tv == tv' = Nothing
+ | otherwise = Just t
+ go ty@(LitTy {}) = return ty
+ go (AppTy ty1 ty2) = do { ty1' <- go ty1
+ ; ty2' <- go ty2
+ ; return (mkAppTy ty1' ty2') }
+ -- mkAppTy <$> go ty1 <*> go ty2
+ go (FunTy ty1 ty2) = do { ty1' <- go ty1
+ ; ty2' <- go ty2
+ ; return (mkFunTy ty1' ty2') }
+ -- mkFunTy <$> go ty1 <*> go ty2
+ go ty@(ForAllTy {})
+ | tv `elemVarSet` tyVarsOfTypes tvs_knds = Nothing
+ -- Can't expand away the kinds unless we create
+ -- fresh variables which we don't want to do at this point.
+ | otherwise = do { rho' <- go rho
+ ; return (mkForAllTys tvs rho') }
+ where
+ (tvs,rho) = splitForAllTys ty
+ tvs_knds = map tyVarKind tvs
+
+ -- For a type constructor application, first try expanding away the
+ -- offending variable from the arguments. If that doesn't work, next
+ -- see if the type constructor is a type synonym, and if so, expand
+ -- it and try again.
+ go ty@(TyConApp tc tys)
+{-
+ | isSynFamilyTyCon tc -- It's ok for tv to occur under a type family application
+ = return ty -- Eg. (a ~ F a) is not an occur-check error
+ -- NB This case can't occur during canonicalisation,
+ -- because the arg is a Xi-type, but can occur in the
+ -- call from TcErrors
+ | otherwise
+-}
+ = do { tys <- mapM go tys; return (mkTyConApp tc tys) }
+ `firstJust` -- First try to eliminate the tyvar from the args
+ do { ty <- tcView ty; go ty }
+ -- Failing that, try to expand a synonym
+\end{code}
+
%************************************************************************
%* *
\subsection{Predicate types}
diff --git a/compiler/typecheck/TcUnify.lhs b/compiler/typecheck/TcUnify.lhs
index 4b92023a57..999575be85 100644
--- a/compiler/typecheck/TcUnify.lhs
+++ b/compiler/typecheck/TcUnify.lhs
@@ -55,12 +55,11 @@ import Kind
import TyCon
import TysWiredIn
import Var
-import VarSet
import VarEnv
import ErrUtils
import DynFlags
import BasicTypes
-import Maybes ( allMaybes, isJust )
+import Maybes ( isJust )
import Util
import Outputable
import FastString
@@ -767,22 +766,19 @@ uUnfilledVar origin swapped tv1 details1 non_var_ty2 -- ty2 is not a type varia
MetaTv { mtv_info = TauTv, mtv_ref = ref1 }
-> do { mb_ty2' <- checkTauTvUpdate tv1 non_var_ty2
; case mb_ty2' of
- Nothing -> do { traceTc "Occ/kind defer" (ppr tv1 <+> dcolon <+> ppr (tyVarKind tv1)
- $$ ppr non_var_ty2 $$ ppr (typeKind non_var_ty2))
- ; defer }
Just ty2' -> updateMeta tv1 ref1 ty2'
+ Nothing -> do { traceTc "Occ/kind defer"
+ (ppr tv1 <+> dcolon <+> ppr (tyVarKind tv1)
+ $$ ppr non_var_ty2 $$ ppr (typeKind non_var_ty2))
+ ; defer }
}
_other -> do { traceTc "Skolem defer" (ppr tv1); defer } -- Skolems of all sorts
where
- defer | Just ty2' <- tcView non_var_ty2 -- Note [Avoid deferring]
- -- non_var_ty2 isn't expanded yet
- = uUnfilledVar origin swapped tv1 details1 ty2'
- | otherwise
- = unSwap swapped (uType_defer origin) (mkTyVarTy tv1) non_var_ty2
- -- Occurs check or an untouchable: just defer
- -- NB: occurs check isn't necessarily fatal:
- -- eg tv1 occured in type family parameter
+ defer = unSwap swapped (uType_defer origin) (mkTyVarTy tv1) non_var_ty2
+ -- Occurs check or an untouchable: just defer
+ -- NB: occurs check isn't necessarily fatal:
+ -- eg tv1 occured in type family parameter
----------------
uUnfilledVars :: CtOrigin
@@ -839,7 +835,6 @@ checkTauTvUpdate :: TcTyVar -> TcType -> TcM (Maybe TcType)
-- We are about to update the TauTv tv with ty.
-- Check (a) that tv doesn't occur in ty (occurs check)
-- (b) that kind(ty) is a sub-kind of kind(tv)
--- (c) that ty does not contain any type families, see Note [Type family sharing]
--
-- We have two possible outcomes:
-- (1) Return the type to update the type variable with,
@@ -856,53 +851,66 @@ checkTauTvUpdate :: TcTyVar -> TcType -> TcM (Maybe TcType)
-- we return Nothing, leaving it to the later constraint simplifier to
-- sort matters out.
--- Used in debug meesages only
-_ppr_sub :: Maybe Ordering -> SDoc
-_ppr_sub (Just LT) = text "LT"
-_ppr_sub (Just EQ) = text "EQ"
-_ppr_sub (Just GT) = text "GT"
-_ppr_sub Nothing = text "Nothing"
-
checkTauTvUpdate tv ty
- = do { ty' <- zonkTcType ty
- ; sub_k <- unifyKindX (tyVarKind tv) (typeKind ty')
--- ; traceTc "checktttv" (ppr tv $$ ppr ty' $$ ppr (tyVarKind tv) $$ ppr (typeKind ty') $$ _ppr_sub sub_k)
+ = do { ty1 <- zonkTcType ty
+ ; sub_k <- unifyKindX (tyVarKind tv) (typeKind ty1)
; case sub_k of
- Nothing -> return Nothing
- Just LT -> return Nothing
- _ -> return (ok ty') }
+ Nothing -> return Nothing
+ Just LT -> return Nothing
+ _ | defer_me ty1 -- Quick test
+ -> -- Failed quick test so try harder
+ case occurCheckExpand tv ty1 of
+ Nothing -> return Nothing
+ Just ty2 | defer_me ty2 -> return Nothing
+ | otherwise -> return (Just ty2)
+ | otherwise -> return (Just ty1) }
where
- ok :: TcType -> Maybe TcType
- -- Checks that tv does not occur in the arg type
- -- expanding type synonyms where necessary to make this so
- -- eg type Phantom a = Bool
- -- ok (tv -> Int) = Nothing
- -- ok (x -> Int) = Just (x -> Int)
- -- ok (Phantom tv -> Int) = Just (Bool -> Int)
- ok (TyVarTy tv') | not (tv == tv') = Just (TyVarTy tv')
- ok this_ty@(TyConApp tc tys)
- | not (isSynFamilyTyCon tc), Just tys' <- allMaybes (map ok tys)
- = Just (TyConApp tc tys')
- | isSynTyCon tc, Just ty_expanded <- tcView this_ty
- = ok ty_expanded -- See Note [Type synonyms and the occur check]
- ok ty@(LitTy {}) = Just ty
- ok (FunTy arg res) | Just arg' <- ok arg, Just res' <- ok res
- = Just (FunTy arg' res')
- ok (AppTy fun arg) | Just fun' <- ok fun, Just arg' <- ok arg
- = Just (AppTy fun' arg')
- ok (ForAllTy tv1 ty1) | Just ty1' <- ok ty1 = Just (ForAllTy tv1 ty1')
- -- Fall-through
- ok _ty = Nothing
+ defer_me :: TcType -> Bool
+ -- Checks for (a) occurrence of tv
+ -- (b) type family applicatios
+ -- See Note [Conservative unification check]
+ defer_me (LitTy {}) = False
+ defer_me (TyVarTy tv') = tv == tv'
+ defer_me (TyConApp tc tys) = isSynFamilyTyCon tc || any defer_me tys
+ defer_me (FunTy arg res) = defer_me arg || defer_me res
+ defer_me (AppTy fun arg) = defer_me fun || defer_me arg
+ defer_me (ForAllTy _ ty) = defer_me ty
\end{code}
-Note [Avoid deferring]
-~~~~~~~~~~~~~~~~~~~~~~
-We try to avoid creating deferred constraints only for efficiency.
-Example (Trac #4917)
+Note [Conservative unification check]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+When unifying (tv ~ rhs), w try to avoid creating deferred constraints
+only for efficiency. However, we do not unify (the defer_me check) if
+ a) There's an occurs check (tv is in fvs(rhs))
+ b) There's a type-function call in 'rhs'
+
+If we fail defer_me we use occurCheckExpand to try to make it pass,
+(see Note [Type synonyms and the occur check]) and then use defer_me
+again to check. Example: Trac #4917)
a ~ Const a b
where type Const a b = a. We can solve this immediately, even when
'a' is a skolem, just by expanding the synonym.
+We always defer type-function calls, even if it's be perfectly safe to
+unify, eg (a ~ F [b]). Reason: this ensures that the constraint
+solver gets to see, and hence simplify the type-function call, which
+in turn might simplify the type of an inferred function. Test ghci046
+is a case in point.
+
+More mysteriously, test T7010 gave a horrible error
+ T7010.hs:29:21:
+ Couldn't match type `Serial (ValueTuple Float)' with `IO Float'
+ Expected type: (ValueTuple Vector, ValueTuple Vector)
+ Actual type: (ValueTuple Vector, ValueTuple Vector)
+because an insoluble type function constraint got mixed up with
+a soluble one when flattening. I never fully understood this, but
+deferring type-function applications made it go away :-(.
+T5853 also got a less-good error message with more aggressive
+unification of type functions.
+
+Moreover the Note [Type family sharing] gives another reason, but
+again I'm not sure if it's really valid.
+
Note [Type synonyms and the occur check]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Generally speaking we try to update a variable with type synonyms not
@@ -928,8 +936,7 @@ the underlying definition of the type synonym.
The same applies later on in the constraint interaction code; see TcInteract,
function @occ_check_ok@.
-
-Note [Type family sharing]
+Note [Type family sharing]
~~~~~~~~~~~~~~~~~~~~~~~~~~
We must avoid eagerly unifying type variables to types that contain function symbols,
because this may lead to loss of sharing, and in turn, in very poor performance of the
@@ -942,7 +949,7 @@ constraint simplifier. Assume that we have a wanted constraint:
D m2,
D m3
}
-where D is some type class. If we eagerly unify m1 := [F m2], m2 := [F m3], m3 := [F m2],
+where D is some type class. If we eagerly unify m1 := [F m2], m2 := [F m3], m3 := [F m4],
then, after zonking, our constraint simplifier will be faced with the following wanted
constraint:
{
@@ -950,12 +957,19 @@ constraint:
D [F [F m4]],
D [F m4]
}
-which has to be flattened by the constraint solver. However, because the sharing is lost,
-an polynomially larger number of flatten skolems will be created and the constraint sets
-we are working with will be polynomially larger.
+which has to be flattened by the constraint solver. In the absence of
+a flat-cache, this may generate a polynomially larger number of
+flatten skolems and the constraint sets we are working with will be
+polynomially larger.
+
+Instead, if we defer the unifications m1 := [F m2], etc. we will only
+be generating three flatten skolems, which is the maximum possible
+sharing arising from the original constraint. That's why we used to
+use a local "ok" function, a variant of TcType.occurCheckExpand.
-Instead, if we defer the unifications m1 := [F m2], etc. we will only be generating three
-flatten skolems, which is the maximum possible sharing arising from the original constraint.
+HOWEVER, we *do* now have a flat-cache, which effectively recovers the
+sharing, so there's no great harm in losing it -- and it's generally
+more efficient to do the unification up-front.
\begin{code}
data LookupTyVarResult -- The result of a lookupTcTyVar call
@@ -1125,14 +1139,16 @@ uUnboundKVar kv1 k2@(TyVarTy kv2)
= do { writeMetaTyVar kv1 k2; return (Just EQ) }
uUnboundKVar kv1 non_var_k2
- = do { k2' <- zonkTcKind non_var_k2
- ; let k2'' = defaultKind k2'
+ | isSigTyVar kv1
+ = return Nothing
+ | otherwise
+ = do { k2a <- zonkTcKind non_var_k2
+ ; let k2b = defaultKind k2a
-- MetaKindVars must be bound only to simple kinds
- ; if not (elemVarSet kv1 (tyVarsOfType k2''))
- && not (isSigTyVar kv1)
- then do { writeMetaTyVar kv1 k2''; return (Just EQ) }
- else return Nothing }
+ ; case occurCheckExpand kv1 k2b of
+ Just k2c -> do { writeMetaTyVar kv1 k2c; return (Just EQ) }
+ _ -> return Nothing }
mkKindErrorCtxt :: Type -> Type -> Kind -> Kind -> TidyEnv -> TcM (TidyEnv, SDoc)
mkKindErrorCtxt ty1 ty2 k1 k2 env0
diff --git a/compiler/types/Kind.lhs b/compiler/types/Kind.lhs
index 7318891d87..50d382f5fa 100644
--- a/compiler/types/Kind.lhs
+++ b/compiler/types/Kind.lhs
@@ -167,7 +167,7 @@ okArrowResultKind _ = False
-- Subkinding
-- The tc variants are used during type-checking, where we don't want the
-- Constraint kind to be a subkind of anything
--- After type-checking (in core), Constraint is a subkind of argTypeKind
+-- After type-checking (in core), Constraint is a subkind of openTypeKind
isSubOpenTypeKind :: Kind -> Bool
-- ^ True of any sub-kind of OpenTypeKind
isSubOpenTypeKind (TyConApp kc []) = isSubOpenTypeKindCon kc
diff --git a/compiler/types/TyCon.lhs b/compiler/types/TyCon.lhs
index 5919779703..88fbb3a7e9 100644
--- a/compiler/types/TyCon.lhs
+++ b/compiler/types/TyCon.lhs
@@ -607,7 +607,7 @@ via the PromotedTyCon alternative in TyCon.
kind signature on the forall'd variable; so the tc_kind field of
PromotedTyCon is not identical to the dataConUserType of the
DataCon. But it's the same modulo changing the variable kinds,
- done by Kind.promoteType.
+ done by DataCon.promoteType.
* Small note: We promote the *user* type of the DataCon. Eg
data T = MkT {-# UNPACK #-} !(Bool, Bool)
diff --git a/mk/validate-settings.mk b/mk/validate-settings.mk
index 03f4e71060..bd582ff828 100644
--- a/mk/validate-settings.mk
+++ b/mk/validate-settings.mk
@@ -84,6 +84,16 @@ libraries/containers_dist-install_EXTRA_HC_OPTS += -fno-warn-deprecations
# Temporarily turn off unused-do-bind warnings for the time package
libraries/time_dist-install_EXTRA_HC_OPTS += -fno-warn-unused-do-bind
+
+
+# Rank2Types is deprecated, so switch off deprecation warnings
+libraries/time_dist-install_EXTRA_HC_OPTS += -fno-warn-deprecations
+libraries/containers_dist-install_EXTRA_HC_OPTS += -fno-warn-deprecations
+libraries/dph/dph-lifted-copy_dist-install_EXTRA_HC_OPTS += -fno-warn-deprecations
+# vector already has -Wwarn
+# Cabal already has -Wwarn
+
+
# Temporary: mkTyCon is deprecated
libraries/time_dist-install_EXTRA_HC_OPTS += -fno-warn-deprecations
# On Windows, there are also some unused import warnings