summaryrefslogtreecommitdiff
path: root/compiler/GHC/Tc
diff options
context:
space:
mode:
authorKrzysztof Gogolewski <krzysztof.gogolewski@tweag.io>2020-06-15 19:58:10 +0200
committerBen Gamari <ben@smart-cactus.org>2020-06-17 16:21:58 -0400
commit40fa237e1daab7a76b9871bb6c50b953a1addf23 (patch)
tree79751e932434be440ba35b4d65c54f25a437e134 /compiler/GHC/Tc
parent20616959a7f4821034e14a64c3c9bf288c9bc956 (diff)
downloadhaskell-40fa237e1daab7a76b9871bb6c50b953a1addf23.tar.gz
Linear types (#15981)
This is the first step towards implementation of the linear types proposal (https://github.com/ghc-proposals/ghc-proposals/pull/111). It features * A language extension -XLinearTypes * Syntax for linear functions in the surface language * Linearity checking in Core Lint, enabled with -dlinear-core-lint * Core-to-core passes are mostly compatible with linearity * Fields in a data type can be linear or unrestricted; linear fields have multiplicity-polymorphic constructors. If -XLinearTypes is disabled, the GADT syntax defaults to linear fields The following items are not yet supported: * a # m -> b syntax (only prefix FUN is supported for now) * Full multiplicity inference (multiplicities are really only checked) * Decent linearity error messages * Linear let, where, and case expressions in the surface language (each of these currently introduce the unrestricted variant) * Multiplicity-parametric fields * Syntax for annotating lambda-bound or let-bound with a multiplicity * Syntax for non-linear/multiple-field-multiplicity records * Linear projections for records with a single linear field * Linear pattern synonyms * Multiplicity coercions (test LinearPolyType) A high-level description can be found at https://ghc.haskell.org/trac/ghc/wiki/LinearTypes/Implementation Following the link above you will find a description of the changes made to Core. This commit has been authored by * Richard Eisenberg * Krzysztof Gogolewski * Matthew Pickering * Arnaud Spiwack With contributions from: * Mark Barbone * Alexander Vershilov Updates haddock submodule.
Diffstat (limited to 'compiler/GHC/Tc')
-rw-r--r--compiler/GHC/Tc/Deriv/Functor.hs3
-rw-r--r--compiler/GHC/Tc/Deriv/Generate.hs28
-rw-r--r--compiler/GHC/Tc/Deriv/Generics.hs7
-rw-r--r--compiler/GHC/Tc/Deriv/Infer.hs5
-rw-r--r--compiler/GHC/Tc/Deriv/Utils.hs5
-rw-r--r--compiler/GHC/Tc/Errors.hs2
-rw-r--r--compiler/GHC/Tc/Errors/Hole.hs22
-rw-r--r--compiler/GHC/Tc/Gen/Arrow.hs19
-rw-r--r--compiler/GHC/Tc/Gen/Bind.hs44
-rw-r--r--compiler/GHC/Tc/Gen/Expr.hs295
-rw-r--r--compiler/GHC/Tc/Gen/Expr.hs-boot5
-rw-r--r--compiler/GHC/Tc/Gen/Foreign.hs65
-rw-r--r--compiler/GHC/Tc/Gen/HsType.hs39
-rw-r--r--compiler/GHC/Tc/Gen/Match.hs158
-rw-r--r--compiler/GHC/Tc/Gen/Pat.hs234
-rw-r--r--compiler/GHC/Tc/Gen/Rule.hs5
-rw-r--r--compiler/GHC/Tc/Gen/Sig.hs12
-rw-r--r--compiler/GHC/Tc/Gen/Splice.hs18
-rw-r--r--compiler/GHC/Tc/Instance/Class.hs13
-rw-r--r--compiler/GHC/Tc/Instance/Typeable.hs13
-rw-r--r--compiler/GHC/Tc/Module.hs7
-rw-r--r--compiler/GHC/Tc/Solver.hs9
-rw-r--r--compiler/GHC/Tc/Solver/Canonical.hs28
-rw-r--r--compiler/GHC/Tc/Solver/Flatten.hs15
-rw-r--r--compiler/GHC/Tc/TyCl.hs76
-rw-r--r--compiler/GHC/Tc/TyCl/Build.hs15
-rw-r--r--compiler/GHC/Tc/TyCl/Class.hs3
-rw-r--r--compiler/GHC/Tc/TyCl/Instance.hs9
-rw-r--r--compiler/GHC/Tc/TyCl/PatSyn.hs29
-rw-r--r--compiler/GHC/Tc/TyCl/Utils.hs16
-rw-r--r--compiler/GHC/Tc/Types.hs4
-rw-r--r--compiler/GHC/Tc/Types/Evidence.hs61
-rw-r--r--compiler/GHC/Tc/Types/Origin.hs21
-rw-r--r--compiler/GHC/Tc/Utils/Backpack.hs3
-rw-r--r--compiler/GHC/Tc/Utils/Env.hs28
-rw-r--r--compiler/GHC/Tc/Utils/Instantiate.hs5
-rw-r--r--compiler/GHC/Tc/Utils/Monad.hs48
-rw-r--r--compiler/GHC/Tc/Utils/TcMType.hs39
-rw-r--r--compiler/GHC/Tc/Utils/TcType.hs66
-rw-r--r--compiler/GHC/Tc/Utils/Unify.hs97
-rw-r--r--compiler/GHC/Tc/Utils/Unify.hs-boot7
-rw-r--r--compiler/GHC/Tc/Utils/Zonk.hs43
-rw-r--r--compiler/GHC/Tc/Validity.hs23
43 files changed, 1045 insertions, 599 deletions
diff --git a/compiler/GHC/Tc/Deriv/Functor.hs b/compiler/GHC/Tc/Deriv/Functor.hs
index 6a13cfaccd..a1af9166fe 100644
--- a/compiler/GHC/Tc/Deriv/Functor.hs
+++ b/compiler/GHC/Tc/Deriv/Functor.hs
@@ -40,6 +40,7 @@ import GHC.Tc.Utils.TcType
import GHC.Core.TyCon
import GHC.Core.TyCo.Rep
import GHC.Core.Type
+import GHC.Core.Multiplicity
import GHC.Utils.Misc
import GHC.Types.Var
import GHC.Types.Var.Set
@@ -557,7 +558,7 @@ deepSubtypesContaining tv
foldDataConArgs :: FFoldType a -> DataCon -> [a]
-- Fold over the arguments of the datacon
foldDataConArgs ft con
- = map foldArg (dataConOrigArgTys con)
+ = map foldArg (map scaledThing $ dataConOrigArgTys con)
where
foldArg
= case getTyVar_maybe (last (tyConAppArgs (dataConOrigResTy con))) of
diff --git a/compiler/GHC/Tc/Deriv/Generate.hs b/compiler/GHC/Tc/Deriv/Generate.hs
index a9791043a2..7fa9975790 100644
--- a/compiler/GHC/Tc/Deriv/Generate.hs
+++ b/compiler/GHC/Tc/Deriv/Generate.hs
@@ -66,6 +66,7 @@ import GHC.Core.Coercion.Axiom ( coAxiomSingleBranch )
import GHC.Builtin.Types.Prim
import GHC.Builtin.Types
import GHC.Core.Type
+import GHC.Core.Multiplicity
import GHC.Core.Class
import GHC.Types.Var.Set
import GHC.Types.Var.Env
@@ -210,7 +211,7 @@ gen_Eq_binds loc tycon = do
bs_needed = take con_arity bs_RDRs
tys_needed = dataConOrigArgTys data_con
in
- ([con1_pat, con2_pat], nested_eq_expr tys_needed as_needed bs_needed)
+ ([con1_pat, con2_pat], nested_eq_expr (map scaledThing tys_needed) as_needed bs_needed)
where
nested_eq_expr [] [] [] = true_Expr
nested_eq_expr tys as bs
@@ -456,7 +457,7 @@ gen_Ord_binds loc tycon = do
-- Returns a case alternative Ki b1 b2 ... bv -> compare (a1,a2,...) with (b1,b2,...)
mkInnerEqAlt op data_con
= mkHsCaseAlt (nlConVarPat data_con_RDR bs_needed) $
- mkCompareFields op (dataConOrigArgTys data_con)
+ mkCompareFields op (map scaledThing $ dataConOrigArgTys data_con)
where
data_con_RDR = getRdrName data_con
bs_needed = take (dataConSourceArity data_con) bs_RDRs
@@ -1044,7 +1045,7 @@ gen_Read_binds get_fixity loc tycon
is_infix = dataConIsInfix data_con
is_record = labels `lengthExceeds` 0
as_needed = take con_arity as_RDRs
- read_args = zipWithEqual "gen_Read_binds" read_arg as_needed (dataConOrigArgTys data_con)
+ read_args = zipWithEqual "gen_Read_binds" read_arg as_needed (map scaledThing $ dataConOrigArgTys data_con)
(read_a1:read_a2:_) = read_args
prefix_prec = appPrecedence
@@ -1187,7 +1188,7 @@ gen_Show_binds get_fixity loc tycon
where
nm = wrapOpParens (unpackFS l)
- show_args = zipWithEqual "gen_Show_binds" show_arg bs_needed arg_tys
+ show_args = zipWithEqual "gen_Show_binds" show_arg bs_needed (map scaledThing arg_tys)
(show_arg1:show_arg2:_) = show_args
show_prefix_args = intersperse (nlHsVar showSpace_RDR) show_args
@@ -1378,7 +1379,7 @@ gen_data dflags data_type_name constr_names loc rep_tc
gfoldl_eqn con
= ([nlVarPat k_RDR, z_Pat, nlConVarPat con_name as_needed],
- foldl' mk_k_app (z_Expr `nlHsApp` nlHsVar con_name) as_needed)
+ foldl' mk_k_app (z_Expr `nlHsApp` (eta_expand_data_con con)) as_needed)
where
con_name :: RdrName
con_name = getRdrName con
@@ -1398,9 +1399,18 @@ gen_data dflags data_type_name constr_names loc rep_tc
gunfold_alt dc = mkHsCaseAlt (mk_unfold_pat dc) (mk_unfold_rhs dc)
mk_unfold_rhs dc = foldr nlHsApp
- (z_Expr `nlHsApp` nlHsVar (getRdrName dc))
+ (z_Expr `nlHsApp` (eta_expand_data_con dc))
(replicate (dataConSourceArity dc) (nlHsVar k_RDR))
+ eta_expand_data_con dc =
+ mkHsLam eta_expand_pats
+ (foldl nlHsApp (nlHsVar (getRdrName dc)) eta_expand_hsvars)
+ where
+ eta_expand_pats = map nlVarPat eta_expand_vars
+ eta_expand_hsvars = map nlHsVar eta_expand_vars
+ eta_expand_vars = take (dataConSourceArity dc) as_RDRs
+
+
mk_unfold_pat dc -- Last one is a wild-pat, to avoid
-- redundant test, and annoying warning
| tag-fIRST_TAG == n_cons-1 = nlWildPat -- Last constructor
@@ -1448,7 +1458,7 @@ gen_data dflags data_type_name constr_names loc rep_tc
kind1, kind2 :: Kind
kind1 = typeToTypeKind
-kind2 = liftedTypeKind `mkVisFunTy` kind1
+kind2 = liftedTypeKind `mkVisFunTyMany` kind1
gfoldl_RDR, gunfold_RDR, toConstr_RDR, dataTypeOf_RDR, mkConstr_RDR,
mkDataType_RDR, conIndex_RDR, prefix_RDR, infix_RDR,
@@ -1960,7 +1970,7 @@ genAuxBindSpec dflags loc (DerivCon2Tag tycon)
sig_ty = mkLHsSigWcType $ L loc $ XHsType $ NHsCoreTy $
mkSpecSigmaTy (tyConTyVars tycon) (tyConStupidTheta tycon) $
- mkParentType tycon `mkVisFunTy` intPrimTy
+ mkParentType tycon `mkVisFunTyMany` intPrimTy
lots_of_constructors = tyConFamilySize tycon > 8
-- was: mAX_FAMILY_SIZE_FOR_VEC_RETURNS
@@ -1984,7 +1994,7 @@ genAuxBindSpec dflags loc (DerivTag2Con tycon)
where
sig_ty = mkLHsSigWcType $ L loc $
XHsType $ NHsCoreTy $ mkSpecForAllTys (tyConTyVars tycon) $
- intTy `mkVisFunTy` mkParentType tycon
+ intTy `mkVisFunTyMany` mkParentType tycon
rdr_name = tag2con_RDR dflags tycon
diff --git a/compiler/GHC/Tc/Deriv/Generics.hs b/compiler/GHC/Tc/Deriv/Generics.hs
index ced6f4b690..ea9862d305 100644
--- a/compiler/GHC/Tc/Deriv/Generics.hs
+++ b/compiler/GHC/Tc/Deriv/Generics.hs
@@ -29,6 +29,7 @@ import GHC.Tc.Deriv.Functor
import GHC.Core.DataCon
import GHC.Core.TyCon
import GHC.Core.FamInstEnv ( FamInst, FamFlavor(..), mkSingleCoAxiom )
+import GHC.Core.Multiplicity
import GHC.Tc.Instance.Family
import GHC.Unit.Module ( moduleName, moduleNameFS
, moduleUnit, unitFS, getModule )
@@ -168,7 +169,7 @@ canDoGenerics tc
-- then we can't build the embedding-projection pair, because
-- it relies on instantiating *polymorphic* sum and product types
-- at the argument types of the constructors
- bad_con dc = if (any bad_arg_type (dataConOrigArgTys dc))
+ bad_con dc = if (any bad_arg_type (map scaledThing $ dataConOrigArgTys dc))
then (NotValid (ppr dc <+> text
"must not have exotic unlifted or polymorphic arguments"))
else (if (not (isVanillaDataCon dc))
@@ -575,7 +576,7 @@ tc_mkRepTy gk_ tycon k =
mkD a = mkTyConApp d1 [ k, metaDataTy, sumP (tyConDataCons a) ]
mkC a = mkTyConApp c1 [ k
, metaConsTy a
- , prod (dataConInstOrigArgTys a
+ , prod (map scaledThing . dataConInstOrigArgTys a
. mkTyVarTys . tyConTyVars $ tycon)
(dataConSrcBangs a)
(dataConImplBangs a)
@@ -741,7 +742,7 @@ mk1Sum gk_ us i n datacon = (from_alt, to_alt)
argTys = dataConOrigArgTys datacon
n_args = dataConSourceArity datacon
- datacon_varTys = zip (map mkGenericLocal [us .. us+n_args-1]) argTys
+ datacon_varTys = zip (map mkGenericLocal [us .. us+n_args-1]) (map scaledThing argTys)
datacon_vars = map fst datacon_varTys
datacon_rdr = getRdrName datacon
diff --git a/compiler/GHC/Tc/Deriv/Infer.hs b/compiler/GHC/Tc/Deriv/Infer.hs
index 56dafd2097..17eff9a74b 100644
--- a/compiler/GHC/Tc/Deriv/Infer.hs
+++ b/compiler/GHC/Tc/Deriv/Infer.hs
@@ -41,6 +41,7 @@ import GHC.Tc.Utils.TcType
import GHC.Core.TyCon
import GHC.Core.TyCo.Ppr (pprTyVars)
import GHC.Core.Type
+import GHC.Core.Multiplicity
import GHC.Tc.Solver
import GHC.Tc.Validity (validDerivPred)
import GHC.Tc.Utils.Unify (buildImplicationFor, checkConstraints)
@@ -186,10 +187,10 @@ inferConstraintsStock (DerivInstTys { dit_cls_tys = cls_tys
dataConInstOrigArgTys data_con all_rep_tc_args
-- No constraints for unlifted types
-- See Note [Deriving and unboxed types]
- , not (isUnliftedType arg_ty)
+ , not (isUnliftedType (irrelevantMult arg_ty))
, let orig = DerivOriginDC data_con arg_n wildcard
, preds_and_mbSubst
- <- get_arg_constraints orig arg_t_or_k arg_ty
+ <- get_arg_constraints orig arg_t_or_k (irrelevantMult arg_ty)
]
preds = concat predss
-- If the constraints require a subtype to be of kind
diff --git a/compiler/GHC/Tc/Deriv/Utils.hs b/compiler/GHC/Tc/Deriv/Utils.hs
index 66adb4e554..e118c69830 100644
--- a/compiler/GHC/Tc/Deriv/Utils.hs
+++ b/compiler/GHC/Tc/Deriv/Utils.hs
@@ -48,6 +48,7 @@ import GHC.Tc.Utils.Monad
import GHC.Tc.Utils.TcType
import GHC.Builtin.Names.TH (liftClassKey)
import GHC.Core.TyCon
+import GHC.Core.Multiplicity
import GHC.Core.TyCo.Ppr (pprSourceTyCon)
import GHC.Core.Type
import GHC.Utils.Misc
@@ -853,7 +854,7 @@ cond_stdOK deriv_ctxt permissive dflags tc rep_tc
= bad "has existential type variables in its type"
| not (null theta) -- 4.
= bad "has constraints in its type"
- | not (permissive || all isTauTy (dataConOrigArgTys con)) -- 5.
+ | not (permissive || all isTauTy (map scaledThing $ dataConOrigArgTys con)) -- 5.
= bad "has a higher-rank type"
| otherwise
= IsValid
@@ -887,7 +888,7 @@ cond_args cls _ _ rep_tc
2 (text "for type" <+> quotes (ppr ty)))
where
bad_args = [ arg_ty | con <- tyConDataCons rep_tc
- , arg_ty <- dataConOrigArgTys con
+ , Scaled _ arg_ty <- dataConOrigArgTys con
, isLiftedType_maybe arg_ty /= Just True
, not (ok_ty arg_ty) ]
diff --git a/compiler/GHC/Tc/Errors.hs b/compiler/GHC/Tc/Errors.hs
index d38b7adcbd..631be3465f 100644
--- a/compiler/GHC/Tc/Errors.hs
+++ b/compiler/GHC/Tc/Errors.hs
@@ -2079,7 +2079,7 @@ expandSynonymsToMatch ty1 ty2 = (ty1_ret, ty2_ret)
(t1_2', t2_2') = go t1_2 t2_2
in (mkAppTy t1_1' t1_2', mkAppTy t2_1' t2_2')
- go ty1@(FunTy _ t1_1 t1_2) ty2@(FunTy _ t2_1 t2_2) =
+ go ty1@(FunTy _ w1 t1_1 t1_2) ty2@(FunTy _ w2 t2_1 t2_2) | w1 `eqType` w2 =
let (t1_1', t2_1') = go t1_1 t2_1
(t1_2', t2_2') = go t1_2 t2_2
in ( ty1 { ft_arg = t1_1', ft_res = t1_2' }
diff --git a/compiler/GHC/Tc/Errors/Hole.hs b/compiler/GHC/Tc/Errors/Hole.hs
index 7c0eaa7912..2edce28eac 100644
--- a/compiler/GHC/Tc/Errors/Hole.hs
+++ b/compiler/GHC/Tc/Errors/Hole.hs
@@ -620,7 +620,7 @@ findValidHoleFits tidy_env implics simples h@(Hole { hole_sort = ExprHole _
where newTyVars = replicateM refLvl $ setLvl <$>
(newOpenTypeKind >>= newFlexiTyVar)
setLvl = flip setMetaTyVarTcLevel hole_lvl
- wrapWithVars vars = mkVisFunTys (map mkTyVarTy vars) hole_ty
+ wrapWithVars vars = mkVisFunTysMany (map mkTyVarTy vars) hole_ty
sortFits :: SortingAlg -- How we should sort the hole fits
-> [HoleFit] -- The subs to sort
@@ -758,34 +758,34 @@ tcFilterHoleFits limit typed_hole ht@(hole_ty, _) candidates =
do { traceTc "lookingUp" $ ppr el
; maybeThing <- lookup el
; case maybeThing of
- Just id | not_trivial id ->
- do { fits <- fitsHole ty (idType id)
+ Just (id, id_ty) | not_trivial id ->
+ do { fits <- fitsHole ty id_ty
; case fits of
- Just (wrp, matches) -> keep_it id wrp matches
+ Just (wrp, matches) -> keep_it id id_ty wrp matches
_ -> discard_it }
_ -> discard_it }
where
-- We want to filter out undefined and the likes from GHC.Err
not_trivial id = nameModule_maybe (idName id) /= Just gHC_ERR
- lookup :: HoleFitCandidate -> TcM (Maybe Id)
- lookup (IdHFCand id) = return (Just id)
+ lookup :: HoleFitCandidate -> TcM (Maybe (Id, Type))
+ lookup (IdHFCand id) = return (Just (id, idType id))
lookup hfc = do { thing <- tcLookup name
; return $ case thing of
- ATcId {tct_id = id} -> Just id
- AGlobal (AnId id) -> Just id
+ ATcId {tct_id = id} -> Just (id, idType id)
+ AGlobal (AnId id) -> Just (id, idType id)
AGlobal (AConLike (RealDataCon con)) ->
- Just (dataConWrapId con)
+ Just (dataConWrapId con, dataConNonlinearType con)
_ -> Nothing }
where name = case hfc of
IdHFCand id -> idName id
GreHFCand gre -> gre_name gre
NameHFCand name -> name
discard_it = go subs seen maxleft ty elts
- keep_it eid wrp ms = go (fit:subs) (extendVarSet seen eid)
+ keep_it eid eid_ty wrp ms = go (fit:subs) (extendVarSet seen eid)
((\n -> n - 1) <$> maxleft) ty elts
where
- fit = HoleFit { hfId = eid, hfCand = el, hfType = (idType eid)
+ fit = HoleFit { hfId = eid, hfCand = el, hfType = eid_ty
, hfRefLvl = length (snd ty)
, hfWrap = wrp, hfMatches = ms
, hfDoc = Nothing }
diff --git a/compiler/GHC/Tc/Gen/Arrow.hs b/compiler/GHC/Tc/Gen/Arrow.hs
index c21a885970..6c5fda73af 100644
--- a/compiler/GHC/Tc/Gen/Arrow.hs
+++ b/compiler/GHC/Tc/Gen/Arrow.hs
@@ -29,6 +29,7 @@ import GHC.Tc.Utils.Monad
import GHC.Tc.Utils.Env
import GHC.Tc.Types.Origin
import GHC.Tc.Types.Evidence
+import GHC.Core.Multiplicity
import GHC.Types.Id( mkLocalId )
import GHC.Tc.Utils.Instantiate
import GHC.Builtin.Types
@@ -92,7 +93,7 @@ tcProc pat cmd exp_ty
; (co, (exp_ty1, res_ty)) <- matchExpectedAppTy exp_ty
; (co1, (arr_ty, arg_ty)) <- matchExpectedAppTy exp_ty1
; let cmd_env = CmdEnv { cmd_arr = arr_ty }
- ; (pat', cmd') <- tcCheckPat ProcExpr pat arg_ty $
+ ; (pat', cmd') <- tcCheckPat ProcExpr pat (unrestricted arg_ty) $
tcCmdTop cmd_env cmd (unitTy, res_ty)
; let res_co = mkTcTransCo co
(mkTcAppCo co1 (mkTcNomReflCo res_ty))
@@ -179,7 +180,7 @@ tc_cmd env (HsCmdIf x fun@(SyntaxExprRn {}) pred b1 b2) res_ty -- Rebindable syn
(text "Predicate type of `ifThenElse' depends on result type")
; (pred', fun')
<- tcSyntaxOp IfOrigin fun (map synKnownType [pred_ty, r_ty, r_ty])
- (mkCheckExpType r_ty) $ \ _ ->
+ (mkCheckExpType r_ty) $ \ _ _ ->
tcCheckMonoExpr pred pred_ty
; b1' <- tcCmd env b1 res_ty
@@ -254,13 +255,13 @@ tc_cmd env
-- Check the patterns, and the GRHSs inside
; (pats', grhss') <- setSrcSpan mtch_loc $
- tcPats LambdaExpr pats (map mkCheckExpType arg_tys) $
+ tcPats LambdaExpr pats (map (unrestricted . mkCheckExpType) arg_tys) $
tc_grhss grhss cmd_stk' (mkCheckExpType res_ty)
; let match' = L mtch_loc (Match { m_ext = noExtField
, m_ctxt = LambdaExpr, m_pats = pats'
, m_grhss = grhss' })
- arg_tys = map hsLPatType pats'
+ arg_tys = map (unrestricted . hsLPatType) pats'
cmd' = HsCmdLam x (MG { mg_alts = L l [match']
, mg_ext = MatchGroupTc arg_tys res_ty
, mg_origin = origin })
@@ -309,7 +310,7 @@ tc_cmd env cmd@(HsCmdArrForm x expr f fixity cmd_args) (cmd_stk, res_ty)
do { (cmd_args', cmd_tys) <- mapAndUnzipM tc_cmd_arg cmd_args
-- We use alphaTyVar for 'w'
; let e_ty = mkInfForAllTy alphaTyVar $
- mkVisFunTys cmd_tys $
+ mkVisFunTysMany cmd_tys $
mkCmdArrTy env (mkPairTy alphaTy cmd_stk) res_ty
; expr' <- tcCheckPolyExpr expr e_ty
; return (HsCmdArrForm x expr' f fixity cmd_args') }
@@ -340,7 +341,7 @@ tcCmdMatches :: CmdEnv
-> CmdType
-> TcM (MatchGroup GhcTcId (LHsCmd GhcTcId))
tcCmdMatches env scrut_ty matches (stk, res_ty)
- = tcMatchesCase match_ctxt scrut_ty matches (mkCheckExpType res_ty)
+ = tcMatchesCase match_ctxt (unrestricted scrut_ty) matches (mkCheckExpType res_ty)
where
match_ctxt = MC { mc_what = CaseAlt,
mc_body = mc_body }
@@ -382,7 +383,7 @@ tcArrDoStmt env _ (BodyStmt _ rhs _ _) res_ty thing_inside
tcArrDoStmt env ctxt (BindStmt _ pat rhs) res_ty thing_inside
= do { (rhs', pat_ty) <- tc_arr_rhs env rhs
- ; (pat', thing) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $
+ ; (pat', thing) <- tcCheckPat (StmtCtxt ctxt) pat (unrestricted pat_ty) $
thing_inside res_ty
; return (mkTcBindStmt pat' rhs', thing) }
@@ -390,7 +391,7 @@ tcArrDoStmt env ctxt (RecStmt { recS_stmts = stmts, recS_later_ids = later_names
, recS_rec_ids = rec_names }) res_ty thing_inside
= do { let tup_names = rec_names ++ filterOut (`elem` rec_names) later_names
; tup_elt_tys <- newFlexiTyVarTys (length tup_names) liftedTypeKind
- ; let tup_ids = zipWith mkLocalId tup_names tup_elt_tys
+ ; let tup_ids = zipWith (\n p -> mkLocalId n Many p) tup_names tup_elt_tys -- Many because it's a recursive definition
; tcExtendIdEnv tup_ids $ do
{ (stmts', tup_rets)
<- tcStmtsAndThen ctxt (tcArrDoStmt env) stmts res_ty $ \ _res_ty' ->
@@ -439,7 +440,7 @@ mkPairTy :: Type -> Type -> Type
mkPairTy t1 t2 = mkTyConApp pairTyCon [t1,t2]
arrowTyConKind :: Kind -- *->*->*
-arrowTyConKind = mkVisFunTys [liftedTypeKind, liftedTypeKind] liftedTypeKind
+arrowTyConKind = mkVisFunTysMany [liftedTypeKind, liftedTypeKind] liftedTypeKind
{-
************************************************************************
diff --git a/compiler/GHC/Tc/Gen/Bind.hs b/compiler/GHC/Tc/Gen/Bind.hs
index b88a672795..b87db660e2 100644
--- a/compiler/GHC/Tc/Gen/Bind.hs
+++ b/compiler/GHC/Tc/Gen/Bind.hs
@@ -41,6 +41,7 @@ import GHC.Tc.Types.Evidence
import GHC.Tc.Gen.HsType
import GHC.Tc.Gen.Pat
import GHC.Tc.Utils.TcMType
+import GHC.Core.Multiplicity
import GHC.Core.FamInstEnv( normaliseType )
import GHC.Tc.Instance.Family( tcGetFamInstEnvs )
import GHC.Core.TyCon
@@ -398,6 +399,9 @@ tcValBinds top_lvl binds sigs thing_inside
-- Do not extend the TcBinderStack; instead
-- we extend it on a per-rhs basis in tcExtendForRhs
-- See Note [Relevant bindings and the binder stack]
+ --
+ -- For the moment, let bindings and top-level bindings introduce
+ -- only unrestricted variables.
; tcExtendSigIds top_lvl poly_ids $
do { (binds', (extra_binds', thing))
<- tcBindGroups top_lvl sig_fn prag_fn binds $
@@ -497,9 +501,10 @@ tc_group top_lvl sig_fn prag_fn (Recursive, binds) closed thing_inside
go :: [SCC (LHsBind GhcRn)] -> TcM (LHsBinds GhcTcId, thing)
go (scc:sccs) = do { (binds1, ids1) <- tc_scc scc
- ; (binds2, thing) <- tcExtendLetEnv top_lvl sig_fn
- closed ids1 $
- go sccs
+ -- recursive bindings must be unrestricted
+ -- (the ids added to the environment here are the name of the recursive definitions).
+ ; (binds2, thing) <- tcExtendLetEnv top_lvl sig_fn closed ids1
+ (go sccs)
; return (binds1 `unionBags` binds2, thing) }
go [] = do { thing <- thing_inside; return (emptyBag, thing) }
@@ -541,6 +546,8 @@ tc_single top_lvl sig_fn prag_fn lbind closed thing_inside
NonRecursive NonRecursive
closed
[lbind]
+ -- since we are defining a non-recursive binding, it is not necessary here
+ -- to define an unrestricted binding. But we do so until toplevel linear bindings are supported.
; thing <- tcExtendLetEnv top_lvl sig_fn closed ids thing_inside
; return (binds1, thing) }
@@ -633,7 +640,7 @@ recoveryCode binder_names sig_fn
, Just poly_id <- completeSigPolyId_maybe sig
= poly_id
| otherwise
- = mkLocalId name forall_a_a
+ = mkLocalId name Many forall_a_a
forall_a_a :: TcType
-- At one point I had (forall r (a :: TYPE r). a), but of course
@@ -703,7 +710,7 @@ tcPolyCheck prag_fn
-- NB: tcSkolemise makes fresh type variables
-- See Note [Instantiate sig with fresh variables]
- let mono_id = mkLocalId mono_name rho_ty in
+ let mono_id = mkLocalId mono_name (varMult poly_id) rho_ty in
tcExtendBinderStack [TcIdBndr mono_id NotTopLevel] $
-- Why mono_id in the BinderStack?
-- See Note [Relevant bindings and the binder stack]
@@ -719,7 +726,7 @@ tcPolyCheck prag_fn
-- We re-use mono-name, but we could equally well use a fresh one
; let prag_sigs = lookupPragEnv prag_fn name
- poly_id2 = mkLocalId mono_name (idType poly_id)
+ poly_id2 = mkLocalId mono_name (idMult poly_id) (idType poly_id)
; spec_prags <- tcSpecPrags poly_id prag_sigs
; poly_id <- addInlinePrags poly_id prag_sigs
@@ -933,7 +940,7 @@ mkInferredPolyId insoluble qtvs inferred_theta poly_name mb_sig_inst mono_ty
-- do this check; otherwise (#14000) we may report an ambiguity
-- error for a rather bogus type.
- ; return (mkLocalId poly_name inferred_poly_ty) }
+ ; return (mkLocalId poly_name Many inferred_poly_ty) }
chooseInferredQuantifiers :: TcThetaType -- inferred
@@ -1288,7 +1295,7 @@ tcMonoBinds is_rec sig_fn no_gen
-- type of the thing whose rhs we are type checking
tcMatchesFun (L nm_loc name) matches exp_ty
- ; mono_id <- newLetBndr no_gen name rhs_ty
+ ; mono_id <- newLetBndr no_gen name Many rhs_ty
; return (unitBag $ L b_loc $
FunBind { fun_id = L nm_loc mono_id,
fun_matches = matches',
@@ -1361,7 +1368,10 @@ tcLhs sig_fn no_gen (FunBind { fun_id = L nm_loc name
| otherwise -- No type signature
= do { mono_ty <- newOpenFlexiTyVarTy
- ; mono_id <- newLetBndr no_gen name mono_ty
+ ; mono_id <- newLetBndr no_gen name Many mono_ty
+ -- This ^ generates a binder with Many multiplicity because all
+ -- let/where-binders are unrestricted. When we introduce linear let
+ -- binders, we will need to retrieve the multiplicity information.
; let mono_info = MBI { mbi_poly_name = name
, mbi_sig = Nothing
, mbi_mono_id = mono_id }
@@ -1379,7 +1389,10 @@ tcLhs sig_fn no_gen (PatBind { pat_lhs = pat, pat_rhs = grhss })
; ((pat', nosig_mbis), pat_ty)
<- addErrCtxt (patMonoBindsCtxt pat grhss) $
tcInfer $ \ exp_ty ->
- tcLetPat inst_sig_fun no_gen pat exp_ty $
+ tcLetPat inst_sig_fun no_gen pat (unrestricted exp_ty) $
+ -- The above inferred type get an unrestricted multiplicity. It may be
+ -- worth it to try and find a finer-grained multiplicity here
+ -- if examples warrant it.
mapM lookup_info nosig_names
; let mbis = sig_mbis ++ nosig_mbis
@@ -1426,7 +1439,10 @@ newSigLetBndr (LetGblBndr prags) name (TISI { sig_inst_sig = id_sig })
| CompleteSig { sig_bndr = poly_id } <- id_sig
= addInlinePrags poly_id (lookupPragEnv prags name)
newSigLetBndr no_gen name (TISI { sig_inst_tau = tau })
- = newLetBndr no_gen name tau
+ = newLetBndr no_gen name Many tau
+ -- Binders with a signature are currently always of multiplicity
+ -- Many. Because they come either from toplevel, let, or where
+ -- declarations. Which are all unrestricted currently.
-------------------
tcRhs :: TcMonoBind -> TcM (HsBind GhcTcId)
@@ -1450,6 +1466,12 @@ tcRhs (TcPatBind infos pat' grhss pat_ty)
tcExtendIdBinderStackForRhs infos $
do { traceTc "tcRhs: pat bind" (ppr pat' $$ ppr pat_ty)
; grhss' <- addErrCtxt (patMonoBindsCtxt pat' grhss) $
+ tcScalingUsage Many $
+ -- Like in tcMatchesFun, this scaling happens because all
+ -- let bindings are unrestricted. A difference, here, is
+ -- that when this is not the case, any more, we will have to
+ -- make sure that the pattern is strict, otherwise this will
+ -- be desugar to incorrect code.
tcGRHSsPat grhss pat_ty
; return ( PatBind { pat_lhs = pat', pat_rhs = grhss'
, pat_ext = NPatBindTc emptyNameSet pat_ty
diff --git a/compiler/GHC/Tc/Gen/Expr.hs b/compiler/GHC/Tc/Gen/Expr.hs
index 9294d5fe64..477c8eaa1d 100644
--- a/compiler/GHC/Tc/Gen/Expr.hs
+++ b/compiler/GHC/Tc/Gen/Expr.hs
@@ -35,6 +35,8 @@ import GHC.Tc.Utils.Zonk
import GHC.Tc.Utils.Monad
import GHC.Tc.Utils.Unify
import GHC.Types.Basic
+import GHC.Core.Multiplicity
+import GHC.Core.UsageEnv
import GHC.Tc.Utils.Instantiate
import GHC.Tc.Gen.Bind ( chooseInferredQuantifiers, tcLocalBinds )
import GHC.Tc.Gen.Sig ( tcUserTypeSig, tcInstSig )
@@ -69,6 +71,7 @@ import GHC.Core.Type
import GHC.Tc.Types.Evidence
import GHC.Types.Var.Set
import GHC.Builtin.Types
+import GHC.Builtin.Types.Prim( multiplicityTyVarList )
import GHC.Builtin.PrimOps( tagToEnumKey )
import GHC.Builtin.Names
import GHC.Driver.Session
@@ -218,8 +221,8 @@ tcExpr (HsOverLit x lit) res_ty
tcExpr (NegApp x expr neg_expr) res_ty
= do { (expr', neg_expr')
<- tcSyntaxOp NegateOrigin neg_expr [SynAny] res_ty $
- \[arg_ty] ->
- tcLExpr expr (mkCheckExpType arg_ty)
+ \[arg_ty] [arg_mult] ->
+ tcScalingUsage arg_mult $ tcLExpr expr (mkCheckExpType arg_ty)
; return (NegApp x expr' neg_expr') }
tcExpr e@(HsIPVar _ x) res_ty
@@ -362,6 +365,13 @@ tcExpr expr@(OpApp fix arg1 op arg2) res_ty
; (wrap_arg1, [arg2_sigma], op_res_ty) <-
matchActualFunTysRho doc orig1 (Just (unLoc arg1)) 1 arg1_ty
+ ; mult_wrap <- tcSubMult AppOrigin Many (scaledMult arg2_sigma)
+ -- See Note [tcSubMult's wrapper] in TcUnify.
+ --
+ -- When ($) becomes multiplicity-polymorphic, then the above check will
+ -- need to go. But in the meantime, it would produce ill-typed
+ -- desugared code to accept linear functions to the left of a ($).
+
-- We have (arg1 $ arg2)
-- So: arg1_ty = arg2_ty -> op_res_ty
-- where arg2_sigma maybe polymorphic; that's the point
@@ -372,8 +382,8 @@ tcExpr expr@(OpApp fix arg1 op arg2) res_ty
-- ($) :: forall (r:RuntimeRep) (a:*) (b:TYPE r). (a->b) -> a -> b
-- Eg we do not want to allow (D# $ 4.0#) #5570
-- (which gives a seg fault)
- ; _ <- unifyKind (Just (XHsType $ NHsCoreTy arg2_sigma))
- (tcTypeKind arg2_sigma) liftedTypeKind
+ ; _ <- unifyKind (Just (XHsType $ NHsCoreTy (scaledThing arg2_sigma)))
+ (tcTypeKind (scaledThing arg2_sigma)) liftedTypeKind
-- Ignore the evidence. arg2_sigma must have type * or #,
-- because we know (arg2_sigma -> op_res_ty) is well-kinded
-- (because otherwise matchActualFunTysRho would fail)
@@ -385,14 +395,14 @@ tcExpr expr@(OpApp fix arg1 op arg2) res_ty
; op_id <- tcLookupId op_name
; let op' = L loc (mkHsWrap (mkWpTyApps [ getRuntimeRep op_res_ty
- , arg2_sigma
+ , scaledThing arg2_sigma
, op_res_ty])
(HsVar noExtField (L lv op_id)))
-- arg1' :: arg1_ty
-- wrap_arg1 :: arg1_ty "->" (arg2_sigma -> op_res_ty)
-- op' :: (a2_ty -> op_res_ty) -> a2_ty -> op_res_ty
- expr' = OpApp fix (mkLHsWrap wrap_arg1 arg1') op' arg2'
+ expr' = OpApp fix (mkLHsWrap (wrap_arg1 <.> mult_wrap) arg1') op' arg2'
; tcWrapResult expr expr' op_res_ty res_ty }
@@ -430,12 +440,12 @@ tcExpr expr@(OpApp fix arg1 op arg2) res_ty
tcExpr expr@(SectionR x op arg2) res_ty
= do { (op', op_ty) <- tcInferRhoNC op
- ; (wrap_fun, [arg1_ty, arg2_ty], op_res_ty)
+ ; (wrap_fun, [Scaled arg1_mult arg1_ty, arg2_ty], op_res_ty)
<- matchActualFunTysRho (mk_op_msg op) fn_orig
(Just (unLoc op)) 2 op_ty
; arg2' <- tcArg (unLoc op) arg2 arg2_ty 2
; let expr' = SectionR x (mkLHsWrap wrap_fun op') arg2'
- act_res_ty = mkVisFunTy arg1_ty op_res_ty
+ act_res_ty = mkVisFunTy arg1_mult arg1_ty op_res_ty
; tcWrapResultMono expr expr' act_res_ty res_ty }
where
@@ -491,14 +501,21 @@ tcExpr expr@(ExplicitTuple x tup_args boxity) res_ty
; tup_args1 <- tcTupArgs tup_args arg_tys
; let expr' = ExplicitTuple x tup_args1 boxity
- act_res_ty = mkVisFunTys [ty | (ty, (L _ (Missing _)))
- <- arg_tys `zip` tup_args]
- (mkTupleTy1 boxity arg_tys)
+
+ missing_tys = [ty | (ty, L _ (Missing _)) <- zip arg_tys tup_args]
+ w_tyvars = multiplicityTyVarList (length missing_tys)
+ -- See Note [Linear fields generalization]
+ w_tvb = map (mkTyVarBinder Inferred) w_tyvars
+ act_res_ty
+ = mkForAllTys w_tvb $
+ mkVisFunTys [ mkScaled (mkTyVarTy w_ty) ty |
+ (ty, w_ty) <- zip missing_tys w_tyvars]
+ (mkTupleTy1 boxity arg_tys)
-- See Note [Don't flatten tuples from HsSyn] in GHC.Core.Make
; traceTc "ExplicitTuple" (ppr act_res_ty $$ ppr res_ty)
- ; tcWrapResultMono expr expr' act_res_ty res_ty }
+ ; tcWrapResult expr expr' act_res_ty res_ty }
tcExpr (ExplicitSum _ alt arity expr) res_ty
= do { let sum_tc = sumTyCon arity
@@ -522,9 +539,15 @@ tcExpr (ExplicitList _ witness exprs) res_ty
Just fln -> do { ((exprs', elt_ty), fln')
<- tcSyntaxOp ListOrigin fln
[synKnownType intTy, SynList] res_ty $
- \ [elt_ty] ->
+ \ [elt_ty] [_int_mul, list_mul] ->
+ -- We ignore _int_mul because the integer (first
+ -- argument of fromListN) is statically known: it
+ -- is desugared to a literal. Therefore there is
+ -- no variable of which to scale the usage in that
+ -- first argument, and `_int_mul` is completely
+ -- free in this expression.
do { exprs' <-
- mapM (tc_elt elt_ty) exprs
+ mapM (tcScalingUsage list_mul . tc_elt elt_ty) exprs
; return (exprs', elt_ty) }
; return $ ExplicitList elt_ty (Just fln') exprs' }
@@ -553,6 +576,9 @@ tcExpr (HsCase x scrut matches) res_ty
--
-- But now, in the GADT world, we need to typecheck the scrutinee
-- first, to get type info that may be refined in the case alternatives
+ let mult = Many
+ -- There is not yet syntax or inference mechanism for case
+ -- expressions to be anything else than unrestricted.
-- Typecheck the scrutinee. We use tcInferRho but tcInferSigma
-- would also be possible (tcMatchesCase accepts sigma-types)
@@ -560,10 +586,10 @@ tcExpr (HsCase x scrut matches) res_ty
-- case id of {..}
-- case (\v -> v) of {..}
-- This design choice is discussed in #17790
- (scrut', scrut_ty) <- tcInferRho scrut
+ ; (scrut', scrut_ty) <- tcScalingUsage mult $ tcInferRho scrut
; traceTc "HsCase" (ppr scrut_ty)
- ; matches' <- tcMatchesCase match_ctxt scrut_ty matches res_ty
+ ; matches' <- tcMatchesCase match_ctxt (Scaled mult scrut_ty) matches res_ty
; return (HsCase x scrut' matches') }
where
match_ctxt = MC { mc_what = CaseAlt,
@@ -575,17 +601,18 @@ tcExpr (HsIf x NoSyntaxExprRn pred b1 b2) res_ty -- Ordinary 'if'
-- Just like Note [Case branches must never infer a non-tau type]
-- in GHC.Tc.Gen.Match (See #10619)
- ; b1' <- tcLExpr b1 res_ty
- ; b2' <- tcLExpr b2 res_ty
+ ; (u1,b1') <- tcCollectingUsage $ tcLExpr b1 res_ty
+ ; (u2,b2') <- tcCollectingUsage $ tcLExpr b2 res_ty
+ ; tcEmitBindingUsage (supUE u1 u2)
; return (HsIf x NoSyntaxExprTc pred' b1' b2') }
tcExpr (HsIf x fun@(SyntaxExprRn {}) pred b1 b2) res_ty
= do { ((pred', b1', b2'), fun')
<- tcSyntaxOp IfOrigin fun [SynAny, SynAny, SynAny] res_ty $
- \ [pred_ty, b1_ty, b2_ty] ->
- do { pred' <- tcCheckPolyExpr pred pred_ty
- ; b1' <- tcCheckPolyExpr b1 b1_ty
- ; b2' <- tcCheckPolyExpr b2 b2_ty
+ \ [pred_ty, b1_ty, b2_ty] [pred_mult, b1_mult, b2_mult] ->
+ do { pred' <- tcScalingUsage pred_mult $ tcCheckPolyExpr pred pred_ty
+ ; b1' <- tcScalingUsage b1_mult $ tcCheckPolyExpr b1 b1_ty
+ ; b2' <- tcScalingUsage b2_mult $ tcCheckPolyExpr b2 b2_ty
; return (pred', b1', b2') }
; return (HsIf x fun' pred' b1' b2') }
@@ -679,7 +706,12 @@ tcExpr expr@(RecordCon { rcon_con_name = L loc con_name
Nothing -> nonBidirectionalErr (conLikeName con_like) ;
Just con_id ->
- do { rbinds' <- tcRecordBinds con_like arg_tys rbinds
+ do { rbinds' <- tcRecordBinds con_like (map scaledThing arg_tys) rbinds
+ -- It is currently not possible for a record to have
+ -- multiplicities. When they do, `tcRecordBinds` will take
+ -- scaled types instead. Meanwhile, it's safe to take
+ -- `scaledThing` above, as we know all the multiplicities are
+ -- Many.
; let rcon_tc = RecordConTc
{ rcon_con_like = con_like
, rcon_con_expr = mkHsWrap con_wrap con_expr }
@@ -829,7 +861,20 @@ following.
tcExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = rbnds }) res_ty
= ASSERT( notNull rbnds )
do { -- STEP -2: typecheck the record_expr, the record to be updated
- (record_expr', record_rho) <- tcInferRho record_expr
+ (record_expr', record_rho) <- tcScalingUsage Many $ tcInferRho record_expr
+ -- Record update drops some of the content of the record (namely the
+ -- content of the field being updated). As a consequence, unless the
+ -- field being updated is unrestricted in the record, or we need an
+ -- unrestricted record. Currently, we simply always require an
+ -- unrestricted record.
+ --
+ -- Consider the following example:
+ --
+ -- data R a = R { self :: a }
+ -- bad :: a ⊸ ()
+ -- bad x = let r = R x in case r { self = () } of { R x' -> x' }
+ --
+ -- This should definitely *not* typecheck.
-- STEP -1 See Note [Disambiguating record fields]
-- After this we know that rbinds is unambiguous
@@ -886,8 +931,13 @@ tcExpr expr@(RecordUpd { rupd_expr = record_expr, rupd_flds = rbnds }) res_ty
-- Take apart a representative constructor
; let con1 = ASSERT( not (null relevant_cons) ) head relevant_cons
- (con1_tvs, _, _, _prov_theta, req_theta, con1_arg_tys, _)
+ (con1_tvs, _, _, _prov_theta, req_theta, scaled_con1_arg_tys, _)
= conLikeFullSig con1
+ con1_arg_tys = map scaledThing scaled_con1_arg_tys
+ -- We can safely drop the fields' multiplicities because
+ -- they are currently always 1: there is no syntax for record
+ -- fields with other multiplicities yet. This way we don't need
+ -- to handle it in the rest of the function
con1_flds = map flLabel $ conLikeFieldLabels con1
con1_tv_tys = mkTyVarTys con1_tvs
con1_res_ty = case mtycon of
@@ -1069,36 +1119,36 @@ tcArithSeq :: Maybe (SyntaxExpr GhcRn) -> ArithSeqInfo GhcRn -> ExpRhoType
-> TcM (HsExpr GhcTc)
tcArithSeq witness seq@(From expr) res_ty
- = do { (wrap, elt_ty, wit') <- arithSeqEltType witness res_ty
- ; expr' <- tcCheckPolyExpr expr elt_ty
+ = do { (wrap, elt_mult, elt_ty, wit') <- arithSeqEltType witness res_ty
+ ; expr' <-tcScalingUsage elt_mult $ tcCheckPolyExpr expr elt_ty
; enum_from <- newMethodFromName (ArithSeqOrigin seq)
enumFromName [elt_ty]
; return $ mkHsWrap wrap $
ArithSeq enum_from wit' (From expr') }
tcArithSeq witness seq@(FromThen expr1 expr2) res_ty
- = do { (wrap, elt_ty, wit') <- arithSeqEltType witness res_ty
- ; expr1' <- tcCheckPolyExpr expr1 elt_ty
- ; expr2' <- tcCheckPolyExpr expr2 elt_ty
+ = do { (wrap, elt_mult, elt_ty, wit') <- arithSeqEltType witness res_ty
+ ; expr1' <- tcScalingUsage elt_mult $ tcCheckPolyExpr expr1 elt_ty
+ ; expr2' <- tcScalingUsage elt_mult $ tcCheckPolyExpr expr2 elt_ty
; enum_from_then <- newMethodFromName (ArithSeqOrigin seq)
enumFromThenName [elt_ty]
; return $ mkHsWrap wrap $
ArithSeq enum_from_then wit' (FromThen expr1' expr2') }
tcArithSeq witness seq@(FromTo expr1 expr2) res_ty
- = do { (wrap, elt_ty, wit') <- arithSeqEltType witness res_ty
- ; expr1' <- tcCheckPolyExpr expr1 elt_ty
- ; expr2' <- tcCheckPolyExpr expr2 elt_ty
+ = do { (wrap, elt_mult, elt_ty, wit') <- arithSeqEltType witness res_ty
+ ; expr1' <- tcScalingUsage elt_mult $ tcCheckPolyExpr expr1 elt_ty
+ ; expr2' <- tcScalingUsage elt_mult $ tcCheckPolyExpr expr2 elt_ty
; enum_from_to <- newMethodFromName (ArithSeqOrigin seq)
enumFromToName [elt_ty]
; return $ mkHsWrap wrap $
ArithSeq enum_from_to wit' (FromTo expr1' expr2') }
tcArithSeq witness seq@(FromThenTo expr1 expr2 expr3) res_ty
- = do { (wrap, elt_ty, wit') <- arithSeqEltType witness res_ty
- ; expr1' <- tcCheckPolyExpr expr1 elt_ty
- ; expr2' <- tcCheckPolyExpr expr2 elt_ty
- ; expr3' <- tcCheckPolyExpr expr3 elt_ty
+ = do { (wrap, elt_mult, elt_ty, wit') <- arithSeqEltType witness res_ty
+ ; expr1' <- tcScalingUsage elt_mult $ tcCheckPolyExpr expr1 elt_ty
+ ; expr2' <- tcScalingUsage elt_mult $ tcCheckPolyExpr expr2 elt_ty
+ ; expr3' <- tcScalingUsage elt_mult $ tcCheckPolyExpr expr3 elt_ty
; eft <- newMethodFromName (ArithSeqOrigin seq)
enumFromThenToName [elt_ty]
; return $ mkHsWrap wrap $
@@ -1106,16 +1156,16 @@ tcArithSeq witness seq@(FromThenTo expr1 expr2 expr3) res_ty
-----------------
arithSeqEltType :: Maybe (SyntaxExpr GhcRn) -> ExpRhoType
- -> TcM (HsWrapper, TcType, Maybe (SyntaxExpr GhcTc))
+ -> TcM (HsWrapper, Mult, TcType, Maybe (SyntaxExpr GhcTc))
arithSeqEltType Nothing res_ty
= do { res_ty <- expTypeToType res_ty
; (coi, elt_ty) <- matchExpectedListTy res_ty
- ; return (mkWpCastN coi, elt_ty, Nothing) }
+ ; return (mkWpCastN coi, One, elt_ty, Nothing) }
arithSeqEltType (Just fl) res_ty
- = do { (elt_ty, fl')
+ = do { ((elt_mult, elt_ty), fl')
<- tcSyntaxOp ListOrigin fl [SynList] res_ty $
- \ [elt_ty] -> return elt_ty
- ; return (idHsWrapper, elt_ty, Just fl') }
+ \ [elt_ty] [elt_mult] -> return (elt_mult, elt_ty)
+ ; return (idHsWrapper, elt_mult, elt_ty, Just fl') }
{-
************************************************************************
@@ -1346,7 +1396,7 @@ tcArgs fun orig_fun_ty orig_args
_ -> False
go :: Int -- Which argment number this is (incl type args)
- -> [TcSigmaType] -- Value args to which applied so far
+ -> [Scaled TcSigmaType] -- Value args to which applied so far
-> TcSigmaType
-> [LHsExprArgIn] -> TcM ([LHsExprArgOut], TcSigmaType)
go _ _ fun_ty [] = traceTc "tcArgs:ret" (ppr fun_ty) >> return ([], fun_ty)
@@ -1491,16 +1541,16 @@ and we had the visible type application
----------------
tcArg :: HsExpr GhcRn -- The function (for error messages)
-> LHsExpr GhcRn -- Actual arguments
- -> TcSigmaType -- expected arg type
+ -> Scaled TcSigmaType -- expected arg type
-> Int -- # of argument
-> TcM (LHsExpr GhcTc) -- Resulting argument
-tcArg fun arg ty arg_no
+tcArg fun arg (Scaled mult ty) arg_no
= addErrCtxt (funAppCtxt fun arg arg_no) $
do { traceTc "tcArg" $
vcat [ ppr arg_no <+> text "of" <+> ppr fun
, text "arg type:" <+> ppr ty
, text "arg:" <+> ppr arg ]
- ; tcCheckPolyExprNC arg ty }
+ ; tcScalingUsage mult $ tcCheckPolyExprNC arg ty }
----------------
tcTupArgs :: [LHsTupArg GhcRn] -> [TcSigmaType] -> TcM [LHsTupArg GhcTc]
@@ -1517,7 +1567,10 @@ tcSyntaxOp :: CtOrigin
-> SyntaxExprRn
-> [SyntaxOpType] -- ^ shape of syntax operator arguments
-> ExpRhoType -- ^ overall result type
- -> ([TcSigmaType] -> TcM a) -- ^ Type check any arguments
+ -> ([TcSigmaType] -> [Mult] -> TcM a) -- ^ Type check any arguments,
+ -- takes a type per hole and a
+ -- multiplicity per arrow in
+ -- the shape.
-> TcM (a, SyntaxExprTc)
-- ^ Typecheck a syntax operator
-- The operator is a variable or a lambda at this stage (i.e. renamer
@@ -1531,7 +1584,7 @@ tcSyntaxOpGen :: CtOrigin
-> SyntaxExprRn
-> [SyntaxOpType]
-> SyntaxOpType
- -> ([TcSigmaType] -> TcM a)
+ -> ([TcSigmaType] -> [Mult] -> TcM a)
-> TcM (a, SyntaxExprTc)
tcSyntaxOpGen orig (SyntaxExprRn op) arg_tys res_ty thing_inside
= do { (expr, sigma) <- tcInferAppHead op
@@ -1560,7 +1613,7 @@ two tcSynArgs.
tcSynArgE :: CtOrigin
-> TcSigmaType
-> SyntaxOpType -- ^ shape it is expected to have
- -> ([TcSigmaType] -> TcM a) -- ^ check the arguments
+ -> ([TcSigmaType] -> [Mult] -> TcM a) -- ^ check the arguments
-> TcM (a, HsWrapper)
-- ^ returns a wrapper :: (type of right shape) "->" (type passed in)
tcSynArgE orig sigma_ty syn_ty thing_inside
@@ -1570,26 +1623,26 @@ tcSynArgE orig sigma_ty syn_ty thing_inside
; return (result, skol_wrap <.> ty_wrapper) }
where
go rho_ty SynAny
- = do { result <- thing_inside [rho_ty]
+ = do { result <- thing_inside [rho_ty] []
; return (result, idHsWrapper) }
go rho_ty SynRho -- same as SynAny, because we skolemise eagerly
- = do { result <- thing_inside [rho_ty]
+ = do { result <- thing_inside [rho_ty] []
; return (result, idHsWrapper) }
go rho_ty SynList
= do { (list_co, elt_ty) <- matchExpectedListTy rho_ty
- ; result <- thing_inside [elt_ty]
+ ; result <- thing_inside [elt_ty] []
; return (result, mkWpCastN list_co) }
go rho_ty (SynFun arg_shape res_shape)
= do { ( match_wrapper -- :: (arg_ty -> res_ty) "->" rho_ty
- , ( ( (result, arg_ty, res_ty)
+ , ( ( (result, arg_ty, res_ty, op_mult)
, res_wrapper ) -- :: res_ty_out "->" res_ty
, arg_wrapper1, [], arg_wrapper2 ) ) -- :: arg_ty "->" arg_ty_out
<- matchExpectedFunTys herald GenSigCtxt 1 (mkCheckExpType rho_ty) $
\ [arg_ty] res_ty ->
- do { arg_tc_ty <- expTypeToType arg_ty
+ do { arg_tc_ty <- expTypeToType (scaledThing arg_ty)
; res_tc_ty <- expTypeToType res_ty
-- another nested arrow is too much for now,
@@ -1600,24 +1653,25 @@ tcSynArgE orig sigma_ty syn_ty thing_inside
, text "Too many nested arrows in SyntaxOpType" $$
pprCtOrigin orig )
+ ; let arg_mult = scaledMult arg_ty
; tcSynArgA orig arg_tc_ty [] arg_shape $
- \ arg_results ->
+ \ arg_results arg_res_mults ->
tcSynArgE orig res_tc_ty res_shape $
- \ res_results ->
- do { result <- thing_inside (arg_results ++ res_results)
- ; return (result, arg_tc_ty, res_tc_ty) }}
+ \ res_results res_res_mults ->
+ do { result <- thing_inside (arg_results ++ res_results) ([arg_mult] ++ arg_res_mults ++ res_res_mults)
+ ; return (result, arg_tc_ty, res_tc_ty, arg_mult) }}
; return ( result
, match_wrapper <.>
mkWpFun (arg_wrapper2 <.> arg_wrapper1) res_wrapper
- arg_ty res_ty doc ) }
+ (Scaled op_mult arg_ty) res_ty doc ) }
where
herald = text "This rebindable syntax expects a function with"
doc = text "When checking a rebindable syntax operator arising from" <+> ppr orig
go rho_ty (SynType the_ty)
= do { wrap <- tcSubTypePat orig GenSigCtxt the_ty rho_ty
- ; result <- thing_inside []
+ ; result <- thing_inside [] []
; return (result, wrap) }
-- works on "actual" types, instantiating where necessary
@@ -1626,7 +1680,7 @@ tcSynArgA :: CtOrigin
-> TcSigmaType
-> [SyntaxOpType] -- ^ argument shapes
-> SyntaxOpType -- ^ result shape
- -> ([TcSigmaType] -> TcM a) -- ^ check the arguments
+ -> ([TcSigmaType] -> [Mult] -> TcM a) -- ^ check the arguments
-> TcM (a, HsWrapper, [HsWrapper], HsWrapper)
-- ^ returns a wrapper to be applied to the original function,
-- wrappers to be applied to arguments
@@ -1637,24 +1691,24 @@ tcSynArgA orig sigma_ty arg_shapes res_shape thing_inside
(length arg_shapes) sigma_ty
-- match_wrapper :: sigma_ty "->" (arg_tys -> res_ty)
; ((result, res_wrapper), arg_wrappers)
- <- tc_syn_args_e arg_tys arg_shapes $ \ arg_results ->
+ <- tc_syn_args_e (map scaledThing arg_tys) arg_shapes $ \ arg_results arg_res_mults ->
tc_syn_arg res_ty res_shape $ \ res_results ->
- thing_inside (arg_results ++ res_results)
+ thing_inside (arg_results ++ res_results) (map scaledMult arg_tys ++ arg_res_mults)
; return (result, match_wrapper, arg_wrappers, res_wrapper) }
where
herald = text "This rebindable syntax expects a function with"
tc_syn_args_e :: [TcSigmaType] -> [SyntaxOpType]
- -> ([TcSigmaType] -> TcM a)
+ -> ([TcSigmaType] -> [Mult] -> TcM a)
-> TcM (a, [HsWrapper])
-- the wrappers are for arguments
tc_syn_args_e (arg_ty : arg_tys) (arg_shape : arg_shapes) thing_inside
= do { ((result, arg_wraps), arg_wrap)
- <- tcSynArgE orig arg_ty arg_shape $ \ arg1_results ->
- tc_syn_args_e arg_tys arg_shapes $ \ args_results ->
- thing_inside (arg1_results ++ args_results)
+ <- tcSynArgE orig arg_ty arg_shape $ \ arg1_results arg1_mults ->
+ tc_syn_args_e arg_tys arg_shapes $ \ args_results args_mults ->
+ thing_inside (arg1_results ++ args_results) (arg1_mults ++ args_mults)
; return (result, arg_wrap : arg_wraps) }
- tc_syn_args_e _ _ thing_inside = (, []) <$> thing_inside []
+ tc_syn_args_e _ _ thing_inside = (, []) <$> thing_inside [] []
tc_syn_arg :: TcSigmaType -> SyntaxOpType
-> ([TcSigmaType] -> TcM a)
@@ -1817,7 +1871,7 @@ tcCheckRecSelId rn_expr f@(Unambiguous {}) res_ty
tcCheckRecSelId rn_expr (Ambiguous _ lbl) res_ty
= case tcSplitFunTy_maybe =<< checkingExpType_maybe res_ty of
Nothing -> ambiguousSelector lbl
- Just (arg, _) -> do { sel_name <- disambiguateSelector lbl arg
+ Just (arg, _) -> do { sel_name <- disambiguateSelector lbl (scaledThing arg)
; tcCheckRecSelId rn_expr (Unambiguous sel_name lbl)
res_ty }
@@ -1862,6 +1916,7 @@ tc_infer_id lbl id_name
ATcId { tct_id = id }
-> do { check_naughty id -- Note [Local record selectors]
; checkThLocalId id
+ ; tcEmitBindingUsage $ unitUE id_name One
; return_id id }
AGlobal (AnId id)
@@ -1881,25 +1936,47 @@ tc_infer_id lbl id_name
return_id id = return (HsVar noExtField (noLoc id), idType id)
return_data_con con
- -- For data constructors, must perform the stupid-theta check
- | null stupid_theta
- = return (HsConLikeOut noExtField (RealDataCon con), con_ty)
-
- | otherwise
- -- See Note [Instantiating stupid theta]
- = do { let (tvs, theta, rho) = tcSplitSigmaTy con_ty
- ; (subst, tvs') <- newMetaTyVars tvs
- ; let tys' = mkTyVarTys tvs'
- theta' = substTheta subst theta
- rho' = substTy subst rho
- ; wrap <- instCall (OccurrenceOf id_name) tys' theta'
- ; addDataConStupidTheta con tys'
- ; return ( mkHsWrap wrap (HsConLikeOut noExtField (RealDataCon con))
- , rho') }
-
- where
- con_ty = dataConUserType con
- stupid_theta = dataConStupidTheta con
+ = do { let tvs = dataConUserTyVarBinders con
+ theta = dataConOtherTheta con
+ args = dataConOrigArgTys con
+ res = dataConOrigResTy con
+
+ -- See Note [Linear fields generalization]
+ ; mul_vars <- newFlexiTyVarTys (length args) multiplicityTy
+ ; let scaleArgs args' = zipWithEqual "return_data_con" combine mul_vars args'
+ combine var (Scaled One ty) = Scaled var ty
+ combine _ scaled_ty = scaled_ty
+ -- The combine function implements the fact that, as
+ -- described in Note [Linear fields generalization], if a
+ -- field is not linear (last line) it isn't made polymorphic.
+
+ etaWrapper arg_tys = foldr (\scaled_ty wr -> WpFun WpHole wr scaled_ty empty) WpHole arg_tys
+
+ -- See Note [Instantiating stupid theta]
+ ; let shouldInstantiate = (not (null (dataConStupidTheta con)) ||
+ isKindLevPoly (tyConResKind (dataConTyCon con)))
+ ; case shouldInstantiate of
+ True -> do { (subst, tvs') <- newMetaTyVars (binderVars tvs)
+ ; let tys' = mkTyVarTys tvs'
+ theta' = substTheta subst theta
+ args' = substScaledTys subst args
+ res' = substTy subst res
+ ; wrap <- instCall (OccurrenceOf id_name) tys' theta'
+ ; let scaled_arg_tys = scaleArgs args'
+ eta_wrap = etaWrapper scaled_arg_tys
+ ; addDataConStupidTheta con tys'
+ ; return ( mkHsWrap (eta_wrap <.> wrap)
+ (HsConLikeOut noExtField (RealDataCon con))
+ , mkVisFunTys scaled_arg_tys res')
+ }
+ False -> let scaled_arg_tys = scaleArgs args
+ wrap1 = mkWpTyApps (mkTyVarTys $ binderVars tvs)
+ eta_wrap = etaWrapper (map unrestricted theta ++ scaled_arg_tys)
+ wrap2 = mkWpTyLams $ binderVars tvs
+ in return ( mkHsWrap (wrap2 <.> eta_wrap <.> wrap1)
+ (HsConLikeOut noExtField (RealDataCon con))
+ , mkInvisForAllTys tvs $ mkInvisFunTysMany theta $ mkVisFunTys scaled_arg_tys res)
+ }
check_naughty id
| isNaughtyRecordSelector id = failWithTc (naughtyRecordSel lbl)
@@ -1918,7 +1995,7 @@ tcUnboundId :: HsExpr GhcRn -> OccName -> ExpRhoType -> TcM (HsExpr GhcTc)
tcUnboundId rn_expr occ res_ty
= do { ty <- newOpenFlexiTyVarTy -- Allow Int# etc (#12531)
; name <- newSysName occ
- ; let ev = mkLocalId name ty
+ ; let ev = mkLocalId name Many ty
; emitNewExprHole occ ev ty
; tcWrapResultO (UnboundOccurrenceOf occ) rn_expr
(HsVar noExtField (noLoc ev)) ty res_ty }
@@ -1972,6 +2049,42 @@ in this case. Thus, users cannot use visible type application with
a data constructor sporting a stupid theta. I won't feel so bad for
the users that complain.
+Note [Linear fields generalization]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+As per Note [Polymorphisation of linear fields], linear field of data
+constructors get a polymorphic type when the data constructor is used as a term.
+
+ Just :: forall {p} a. a #p-> Maybe a
+
+This rule is known only to the typechecker: Just keeps its linear type in Core.
+
+In order to desugar this generalised typing rule, we simply eta-expand:
+
+ \a (x # p :: a) -> Just @a x
+
+has the appropriate type. We insert these eta-expansion with WpFun wrappers.
+
+A small hitch: if the constructor is levity-polymorphic (unboxed tuples, sums,
+certain newtypes with -XUnliftedNewtypes) then this strategy produces
+
+ \r1 r2 a b (x # p :: a) (y # q :: b) -> (# a, b #)
+
+Which has type
+
+ forall r1 r2 a b. a #p-> b #q-> (# a, b #)
+
+Which violates the levity-polymorphism restriction see Note [Levity polymorphism
+checking] in DsMonad.
+
+So we really must instantiate r1 and r2 rather than quantify over them. For
+simplicity, we just instantiate the entire type, as described in Note
+[Instantiating stupid theta]. It breaks visible type application with unboxed
+tuples, sums and levity-polymorphic newtypes, but this doesn't appear to be used
+anywhere.
+
+A better plan: let's force all representation variable to be *inferred*, so that
+they are not subject to visible type applications. Then we can instantiate
+inferred argument eagerly.
-}
isTagToEnum :: HsExpr GhcTc -> Bool
@@ -2149,7 +2262,7 @@ getFixedTyVars upd_fld_occs univ_tvs cons
++ prov_theta
++ req_theta
flds = conLikeFieldLabels con
- fixed_tvs = exactTyCoVarsOfTypes fixed_tys
+ fixed_tvs = exactTyCoVarsOfTypes (map scaledThing fixed_tys)
-- fixed_tys: See Note [Type of a record update]
`unionVarSet` tyCoVarsOfTypes theta
-- Universally-quantified tyvars that
@@ -2497,7 +2610,7 @@ tcRecordField con_like flds_w_tys (L loc (FieldOcc sel_name lbl)) rhs
do { rhs' <- tcCheckPolyExprNC rhs field_ty
; let field_id = mkUserLocal (nameOccName sel_name)
(nameUnique sel_name)
- field_ty loc
+ Many field_ty loc
-- Yuk: the field_id has the *unique* of the selector Id
-- (so we can find it easily)
-- but is a LocalId with the appropriate type of the RHS
diff --git a/compiler/GHC/Tc/Gen/Expr.hs-boot b/compiler/GHC/Tc/Gen/Expr.hs-boot
index 1f26ef242a..f4b12e28a5 100644
--- a/compiler/GHC/Tc/Gen/Expr.hs-boot
+++ b/compiler/GHC/Tc/Gen/Expr.hs-boot
@@ -4,6 +4,7 @@ import GHC.Hs ( HsExpr, LHsExpr, SyntaxExprRn, SyntaxExprTc )
import GHC.Tc.Utils.TcType ( TcRhoType, TcSigmaType, SyntaxOpType, ExpType, ExpRhoType )
import GHC.Tc.Types ( TcM )
import GHC.Tc.Types.Origin ( CtOrigin )
+import GHC.Core.Type ( Mult )
import GHC.Hs.Extension ( GhcRn, GhcTcId )
tcCheckPolyExpr ::
@@ -31,14 +32,14 @@ tcSyntaxOp :: CtOrigin
-> SyntaxExprRn
-> [SyntaxOpType] -- ^ shape of syntax operator arguments
-> ExpType -- ^ overall result type
- -> ([TcSigmaType] -> TcM a) -- ^ Type check any arguments
+ -> ([TcSigmaType] -> [Mult] -> TcM a) -- ^ Type check any arguments
-> TcM (a, SyntaxExprTc)
tcSyntaxOpGen :: CtOrigin
-> SyntaxExprRn
-> [SyntaxOpType]
-> SyntaxOpType
- -> ([TcSigmaType] -> TcM a)
+ -> ([TcSigmaType] -> [Mult] -> TcM a)
-> TcM (a, SyntaxExprTc)
diff --git a/compiler/GHC/Tc/Gen/Foreign.hs b/compiler/GHC/Tc/Gen/Foreign.hs
index 06febcef33..97757c0889 100644
--- a/compiler/GHC/Tc/Gen/Foreign.hs
+++ b/compiler/GHC/Tc/Gen/Foreign.hs
@@ -46,6 +46,7 @@ import GHC.Tc.Instance.Family
import GHC.Core.FamInstEnv
import GHC.Core.Coercion
import GHC.Core.Type
+import GHC.Core.Multiplicity
import GHC.Types.ForeignCall
import GHC.Utils.Error
import GHC.Types.Id
@@ -93,20 +94,6 @@ parameters.
Similarly, we don't need to look in AppTy's, because nothing headed by
an AppTy will be marshalable.
-
-Note [FFI type roles]
-~~~~~~~~~~~~~~~~~~~~~
-The 'go' helper function within normaliseFfiType' always produces
-representational coercions. But, in the "children_only" case, we need to
-use these coercions in a TyConAppCo. Accordingly, the roles on the coercions
-must be twiddled to match the expectation of the enclosing TyCon. However,
-we cannot easily go from an R coercion to an N one, so we forbid N roles
-on FFI type constructors. Currently, only two such type constructors exist:
-IO and FunPtr. Thus, this is not an onerous burden.
-
-If we ever want to lift this restriction, we would need to make 'go' take
-the target role as a parameter. This wouldn't be hard, but it's a complication
-not yet necessary and so is not yet implemented.
-}
-- normaliseFfiType takes the type from an FFI declaration, and
@@ -120,33 +107,31 @@ normaliseFfiType ty
normaliseFfiType' fam_envs ty
normaliseFfiType' :: FamInstEnvs -> Type -> TcM (Coercion, Type, Bag GlobalRdrElt)
-normaliseFfiType' env ty0 = go initRecTc ty0
+normaliseFfiType' env ty0 = go Representational initRecTc ty0
where
- go :: RecTcChecker -> Type -> TcM (Coercion, Type, Bag GlobalRdrElt)
- go rec_nts ty
+ go :: Role -> RecTcChecker -> Type -> TcM (Coercion, Type, Bag GlobalRdrElt)
+ go role rec_nts ty
| Just ty' <- tcView ty -- Expand synonyms
- = go rec_nts ty'
+ = go role rec_nts ty'
| Just (tc, tys) <- splitTyConApp_maybe ty
- = go_tc_app rec_nts tc tys
+ = go_tc_app role rec_nts tc tys
| (bndrs, inner_ty) <- splitForAllVarBndrs ty
, not (null bndrs)
- = do (coi, nty1, gres1) <- go rec_nts inner_ty
+ = do (coi, nty1, gres1) <- go role rec_nts inner_ty
return ( mkHomoForAllCos (binderVars bndrs) coi
, mkForAllTys bndrs nty1, gres1 )
| otherwise -- see Note [Don't recur in normaliseFfiType']
- = return (mkRepReflCo ty, ty, emptyBag)
+ = return (mkReflCo role ty, ty, emptyBag)
- go_tc_app :: RecTcChecker -> TyCon -> [Type]
+ go_tc_app :: Role -> RecTcChecker -> TyCon -> [Type]
-> TcM (Coercion, Type, Bag GlobalRdrElt)
- go_tc_app rec_nts tc tys
+ go_tc_app role rec_nts tc tys
-- We don't want to look through the IO newtype, even if it is
-- in scope, so we have a special case for it:
| tc_key `elem` [ioTyConKey, funPtrTyConKey, funTyConKey]
- -- These *must not* have nominal roles on their parameters!
- -- See Note [FFI type roles]
= children_only
| isNewTyCon tc -- Expand newtypes
@@ -160,13 +145,13 @@ normaliseFfiType' env ty0 = go initRecTc ty0
= do { rdr_env <- getGlobalRdrEnv
; case checkNewtypeFFI rdr_env tc of
Nothing -> nothing
- Just gre -> do { (co', ty', gres) <- go rec_nts' nt_rhs
+ Just gre -> do { (co', ty', gres) <- go role rec_nts' nt_rhs
; return (mkTransCo nt_co co', ty', gre `consBag` gres) } }
| isFamilyTyCon tc -- Expand open tycons
- , (co, ty) <- normaliseTcApp env Representational tc tys
+ , (co, ty) <- normaliseTcApp env role tc tys
, not (isReflexiveCo co)
- = do (co', ty', gres) <- go rec_nts ty
+ = do (co', ty', gres) <- go role rec_nts ty
return (mkTransCo co co', ty', gres)
| otherwise
@@ -174,19 +159,15 @@ normaliseFfiType' env ty0 = go initRecTc ty0
where
tc_key = getUnique tc
children_only
- = do xs <- mapM (go rec_nts) tys
+ = do xs <- zipWithM (\ty r -> go r rec_nts ty) tys (tyConRolesX role tc)
let (cos, tys', gres) = unzip3 xs
- -- the (repeat Representational) is because 'go' always
- -- returns R coercions
- cos' = zipWith3 downgradeRole (tyConRoles tc)
- (repeat Representational) cos
- return ( mkTyConAppCo Representational tc cos'
+ return ( mkTyConAppCo role tc cos
, mkTyConApp tc tys', unionManyBags gres)
- nt_co = mkUnbranchedAxInstCo Representational (newTyConCo tc) tys []
+ nt_co = mkUnbranchedAxInstCo role (newTyConCo tc) tys []
nt_rhs = newTyConInstRhs tc tys
ty = mkTyConApp tc tys
- nothing = return (mkRepReflCo ty, ty, emptyBag)
+ nothing = return (mkReflCo role ty, ty, emptyBag)
checkNewtypeFFI :: GlobalRdrEnv -> TyCon -> Maybe GlobalRdrElt
checkNewtypeFFI rdr_env tc
@@ -251,12 +232,12 @@ tcFImport (L dloc fo@(ForeignImport { fd_name = L nloc nm, fd_sig_ty = hs_ty
-- Drop the foralls before inspecting the
-- structure of the foreign type.
(arg_tys, res_ty) = tcSplitFunTys (dropForAlls norm_sig_ty)
- id = mkLocalId nm sig_ty
+ id = mkLocalId nm Many sig_ty
-- Use a LocalId to obey the invariant that locally-defined
-- things are LocalIds. However, it does not need zonking,
-- (so GHC.Tc.Utils.Zonk.zonkForeignExports ignores it).
- ; imp_decl' <- tcCheckFIType arg_tys res_ty imp_decl
+ ; imp_decl' <- tcCheckFIType (map scaledThing arg_tys) res_ty imp_decl
-- Can't use sig_ty here because sig_ty :: Type and
-- we need HsType Id hence the undefined
; let fi_decl = ForeignImport { fd_name = L nloc id
@@ -275,7 +256,7 @@ tcCheckFIType arg_tys res_ty (CImport (L lc cconv) safety mh l@(CLabel _) src)
= do checkCg checkCOrAsmOrLlvmOrInterp
-- NB check res_ty not sig_ty!
-- In case sig_ty is (forall a. ForeignPtr a)
- check (isFFILabelTy (mkVisFunTys arg_tys res_ty)) (illegalForeignTyErr Outputable.empty)
+ check (isFFILabelTy (mkVisFunTysMany arg_tys res_ty)) (illegalForeignTyErr Outputable.empty)
cconv' <- checkCConv cconv
return (CImport (L lc cconv') safety mh l src)
@@ -287,7 +268,7 @@ tcCheckFIType arg_tys res_ty (CImport (L lc cconv) safety mh CWrapper src) = do
checkCg checkCOrAsmOrLlvmOrInterp
cconv' <- checkCConv cconv
case arg_tys of
- [arg1_ty] -> do checkForeignArgs isFFIExternalTy arg1_tys
+ [arg1_ty] -> do checkForeignArgs isFFIExternalTy (map scaledThing arg1_tys)
checkForeignRes nonIOok checkSafe isFFIExportResultTy res1_ty
checkForeignRes mustBeIO checkSafe (isFFIDynTy arg1_ty) res_ty
where
@@ -305,7 +286,7 @@ tcCheckFIType arg_tys res_ty idecl@(CImport (L lc cconv) (L ls safety) mh
addErrTc (illegalForeignTyErr Outputable.empty (text "At least one argument expected"))
(arg1_ty:arg_tys) -> do
dflags <- getDynFlags
- let curried_res_ty = mkVisFunTys arg_tys res_ty
+ let curried_res_ty = mkVisFunTysMany arg_tys res_ty
check (isFFIDynTy curried_res_ty arg1_ty)
(illegalForeignTyErr argument)
checkForeignArgs (isFFIArgumentTy dflags safety) arg_tys
@@ -418,7 +399,7 @@ tcCheckFEType sig_ty (CExport (L l (CExportStatic esrc str cconv)) src) = do
checkCg checkCOrAsmOrLlvm
checkTc (isCLabelString str) (badCName str)
cconv' <- checkCConv cconv
- checkForeignArgs isFFIExternalTy arg_tys
+ checkForeignArgs isFFIExternalTy (map scaledThing arg_tys)
checkForeignRes nonIOok noCheckSafe isFFIExportResultTy res_ty
return (CExport (L l (CExportStatic esrc str cconv')) src)
where
diff --git a/compiler/GHC/Tc/Gen/HsType.hs b/compiler/GHC/Tc/Gen/HsType.hs
index b99cc6365b..fecd8b9b2e 100644
--- a/compiler/GHC/Tc/Gen/HsType.hs
+++ b/compiler/GHC/Tc/Gen/HsType.hs
@@ -57,6 +57,9 @@ module GHC.Tc.Gen.HsType (
tcLHsKindSig, checkDataKindSig, DataSort(..),
checkClassKindSig,
+ -- Multiplicity
+ tcMult,
+
-- Pattern type signatures
tcHsPatSigType,
@@ -85,6 +88,7 @@ import GHC.Core.TyCo.Ppr
import GHC.Tc.Errors ( reportAllUnsolved )
import GHC.Tc.Utils.TcType
import GHC.Tc.Utils.Instantiate ( tcInstInvisibleTyBinders, tcInstInvisibleTyBinder )
+import GHC.Core.Multiplicity
import GHC.Core.Type
import GHC.Builtin.Types.Prim
import GHC.Types.Name.Reader( lookupLocalRdrOcc )
@@ -469,7 +473,7 @@ tcHsDeriv hs_ty
; let (tvs, pred) = splitForAllTys ty
(kind_args, _) = splitFunTys (tcTypeKind pred)
; case getClassPredTys_maybe pred of
- Just (cls, tys) -> return (tvs, cls, tys, kind_args)
+ Just (cls, tys) -> return (tvs, cls, tys, map scaledThing kind_args)
Nothing -> failWithTc (text "Illegal deriving item" <+> quotes (ppr hs_ty)) }
-- | Typecheck a deriving strategy. For most deriving strategies, this is a
@@ -684,6 +688,9 @@ concern things that the renamer can't handle.
-}
+tcMult :: HsArrow GhcRn -> TcM Mult
+tcMult hc = tc_mult (mkMode TypeLevel) hc
+
-- | Info about the context in which we're checking a type. Currently,
-- differentiates only between types and kinds, but this will likely
-- grow, at least to include the distinction between patterns and
@@ -888,12 +895,15 @@ tc_hs_type _ ty@(HsSpliceTy {}) _exp_kind
= failWithTc (text "Unexpected type splice:" <+> ppr ty)
---------- Functions and applications
-tc_hs_type mode (HsFunTy _ ty1 ty2) exp_kind
- = tc_fun_type mode ty1 ty2 exp_kind
+tc_hs_type mode ty@(HsFunTy _ mult ty1 ty2) exp_kind
+ | mode_tyki mode == KindLevel && not (isUnrestricted mult)
+ = failWithTc (text "Linear arrows disallowed in kinds:" <+> ppr ty)
+ | otherwise
+ = tc_fun_type mode mult ty1 ty2 exp_kind
tc_hs_type mode (HsOpTy _ ty1 (L _ op) ty2) exp_kind
| op `hasKey` funTyConKey
- = tc_fun_type mode ty1 ty2 exp_kind
+ = tc_fun_type mode HsUnrestrictedArrow ty1 ty2 exp_kind
--------- Foralls
tc_hs_type mode forall@(HsForAllTy { hst_tele = tele, hst_body = ty }) exp_kind
@@ -1084,20 +1094,25 @@ Note [VarBndrs, TyCoVarBinders, TyConBinders, and visibility] in "GHC.Core.TyCo.
-}
------------------------------------------
-tc_fun_type :: TcTyMode -> LHsType GhcRn -> LHsType GhcRn -> TcKind
+tc_mult :: TcTyMode -> HsArrow GhcRn -> TcM Mult
+tc_mult mode ty = tc_lhs_type mode (arrowToHsType ty) multiplicityTy
+------------------------------------------
+tc_fun_type :: TcTyMode -> HsArrow GhcRn -> LHsType GhcRn -> LHsType GhcRn -> TcKind
-> TcM TcType
-tc_fun_type mode ty1 ty2 exp_kind = case mode_tyki mode of
+tc_fun_type mode mult ty1 ty2 exp_kind = case mode_tyki mode of
TypeLevel ->
do { arg_k <- newOpenTypeKind
; res_k <- newOpenTypeKind
; ty1' <- tc_lhs_type mode ty1 arg_k
; ty2' <- tc_lhs_type mode ty2 res_k
- ; checkExpectedKind (HsFunTy noExtField ty1 ty2) (mkVisFunTy ty1' ty2')
+ ; mult' <- tc_mult mode mult
+ ; checkExpectedKind (HsFunTy noExtField mult ty1 ty2) (mkVisFunTy mult' ty1' ty2')
liftedTypeKind exp_kind }
KindLevel -> -- no representation polymorphism in kinds. yet.
do { ty1' <- tc_lhs_type mode ty1 liftedTypeKind
; ty2' <- tc_lhs_type mode ty2 liftedTypeKind
- ; checkExpectedKind (HsFunTy noExtField ty1 ty2) (mkVisFunTy ty1' ty2')
+ ; mult' <- tc_mult mode mult
+ ; checkExpectedKind (HsFunTy noExtField mult ty1 ty2) (mkVisFunTy mult' ty1' ty2')
liftedTypeKind exp_kind }
{- Note [Skolem escape and forall-types]
@@ -2128,7 +2143,7 @@ kcCheckDeclHeader_cusk name flav
++ mkNamedTyConBinders Specified specified
++ map (mkRequiredTyConBinder mentioned_kv_set) tc_tvs
- all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ tc_tvs)
+ all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ tc_tvs)
tycon = mkTcTyCon name final_tc_binders res_kind all_tv_prs
True -- it is generalised
flav
@@ -2363,7 +2378,7 @@ kcCheckDeclHeader_sig kisig name flav
-- Example: (a~b) =>
ZippedBinder (Anon InvisArg bndr_ki) Nothing -> do
name <- newSysName (mkTyVarOccFS (fsLit "ev"))
- let tv = mkTyVar name bndr_ki
+ let tv = mkTyVar name (scaledThing bndr_ki)
return (mkAnonTyConBinder InvisArg tv, [])
-- Non-dependent visible argument with a user-written binder.
@@ -2371,7 +2386,7 @@ kcCheckDeclHeader_sig kisig name flav
ZippedBinder (Anon VisArg bndr_ki) (Just b) ->
return $
let v_name = getName b
- tv = mkTyVar v_name bndr_ki
+ tv = mkTyVar v_name (scaledThing bndr_ki)
tcb = mkAnonTyConBinder VisArg tv
in (tcb, [(v_name, tv)])
@@ -3181,7 +3196,7 @@ etaExpandAlgTyCon tc_bndrs kind
Just (Anon af arg, kind')
-> go loc occs' uniqs' subst' (tcb : acc) kind'
where
- arg' = substTy subst arg
+ arg' = substTy subst (scaledThing arg)
tv = mkTyVar (mkInternalName uniq occ loc) arg'
subst' = extendTCvInScope subst tv
tcb = Bndr tv (AnonTCB af)
diff --git a/compiler/GHC/Tc/Gen/Match.hs b/compiler/GHC/Tc/Gen/Match.hs
index b95899cc1f..0bff299886 100644
--- a/compiler/GHC/Tc/Gen/Match.hs
+++ b/compiler/GHC/Tc/Gen/Match.hs
@@ -51,6 +51,8 @@ import GHC.Tc.Utils.TcType
import GHC.Tc.Gen.Bind
import GHC.Tc.Utils.Unify
import GHC.Tc.Types.Origin
+import GHC.Core.Multiplicity
+import GHC.Core.UsageEnv
import GHC.Types.Name
import GHC.Builtin.Types
import GHC.Types.Id
@@ -100,6 +102,13 @@ tcMatchesFun fn@(L _ fun_name) matches exp_ty
; matchExpectedFunTys herald ctxt arity exp_ty $ \ pat_tys rhs_ty ->
-- NB: exp_type may be polymorphic, but
-- matchExpectedFunTys can cope with that
+ tcScalingUsage Many $
+ -- toplevel bindings and let bindings are, at the
+ -- moment, always unrestricted. The value being bound
+ -- must, accordingly, be unrestricted. Hence them
+ -- being scaled by Many. When let binders come with a
+ -- multiplicity, then @tcMatchesFun@ will have to take
+ -- a multiplicity argument, and scale accordingly.
tcMatches match_ctxt pat_tys rhs_ty matches }
where
arity = matchGroupArity matches
@@ -122,16 +131,16 @@ parser guarantees that each equation has exactly one argument.
-}
tcMatchesCase :: (Outputable (body GhcRn)) =>
- TcMatchCtxt body -- Case context
- -> TcSigmaType -- Type of scrutinee
- -> MatchGroup GhcRn (Located (body GhcRn)) -- The case alternatives
- -> ExpRhoType -- Type of whole case expressions
- -> TcM (MatchGroup GhcTcId (Located (body GhcTcId)))
- -- Translated alternatives
- -- wrapper goes from MatchGroup's ty to expected ty
+ TcMatchCtxt body -- Case context
+ -> Scaled TcSigmaType -- Type of scrutinee
+ -> MatchGroup GhcRn (Located (body GhcRn)) -- The case alternatives
+ -> ExpRhoType -- Type of whole case expressions
+ -> TcM (MatchGroup GhcTcId (Located (body GhcTcId)))
+ -- Translated alternatives
+ -- wrapper goes from MatchGroup's ty to expected ty
-tcMatchesCase ctxt scrut_ty matches res_ty
- = tcMatches ctxt [mkCheckExpType scrut_ty] res_ty matches
+tcMatchesCase ctxt (Scaled scrut_mult scrut_ty) matches res_ty
+ = tcMatches ctxt [Scaled scrut_mult (mkCheckExpType scrut_ty)] res_ty matches
tcMatchLambda :: SDoc -- see Note [Herald for matchExpectedFunTys] in GHC.Tc.Utils.Unify
-> TcMatchCtxt HsExpr
@@ -197,15 +206,16 @@ still gets assigned a polytype.
-- expected type into TauTvs.
-- See Note [Case branches must never infer a non-tau type]
tauifyMultipleMatches :: [LMatch id body]
- -> [ExpType] -> TcM [ExpType]
+ -> [Scaled ExpType] -> TcM [Scaled ExpType]
tauifyMultipleMatches group exp_tys
| isSingletonMatchGroup group = return exp_tys
- | otherwise = mapM tauifyExpType exp_tys
+ | otherwise = mapM (\(Scaled m t) ->
+ fmap (Scaled m) (tauifyExpType t)) exp_tys
-- NB: In the empty-match case, this ensures we fill in the ExpType
-- | Type-check a MatchGroup.
tcMatches :: (Outputable (body GhcRn)) => TcMatchCtxt body
- -> [ExpSigmaType] -- Expected pattern types
+ -> [Scaled ExpSigmaType] -- Expected pattern types
-> ExpRhoType -- Expected result-type of the Match.
-> MatchGroup GhcRn (Located (body GhcRn))
-> TcM (MatchGroup GhcTcId (Located (body GhcTcId)))
@@ -216,14 +226,15 @@ data TcMatchCtxt body -- c.f. TcStmtCtxt, also in this module
-- an alternative
-> ExpRhoType
-> TcM (Located (body GhcTcId)) }
-
tcMatches ctxt pat_tys rhs_ty (MG { mg_alts = L l matches
, mg_origin = origin })
- = do { rhs_ty:pat_tys <- tauifyMultipleMatches matches (rhs_ty:pat_tys)
+ = do { (Scaled _ rhs_ty):pat_tys <- tauifyMultipleMatches matches ((Scaled One rhs_ty):pat_tys) -- return type has implicitly multiplicity 1, it doesn't matter all that much in this case since it isn't used and is eliminated immediately.
-- See Note [Case branches must never infer a non-tau type]
- ; matches' <- mapM (tcMatch ctxt pat_tys rhs_ty) matches
- ; pat_tys <- mapM readExpType pat_tys
+ ; umatches <- mapM (tcCollectingUsage . tcMatch ctxt pat_tys rhs_ty) matches
+ ; let (usages,matches') = unzip umatches
+ ; tcEmitBindingUsage $ supUEs usages
+ ; pat_tys <- mapM (\(Scaled m t) -> fmap (Scaled m) (readExpType t)) pat_tys
; rhs_ty <- readExpType rhs_ty
; return (MG { mg_alts = L l matches'
, mg_ext = MatchGroupTc pat_tys rhs_ty
@@ -231,7 +242,7 @@ tcMatches ctxt pat_tys rhs_ty (MG { mg_alts = L l matches
-------------
tcMatch :: (Outputable (body GhcRn)) => TcMatchCtxt body
- -> [ExpSigmaType] -- Expected pattern types
+ -> [Scaled ExpSigmaType] -- Expected pattern types
-> ExpRhoType -- Expected result-type of the Match.
-> LMatch GhcRn (Located (body GhcRn))
-> TcM (LMatch GhcTcId (Located (body GhcTcId)))
@@ -266,10 +277,11 @@ tcGRHSs :: TcMatchCtxt body -> GRHSs GhcRn (Located (body GhcRn)) -> ExpRhoType
-- but we don't need to do that any more
tcGRHSs ctxt (GRHSs _ grhss (L l binds)) res_ty
- = do { (binds', grhss')
+ = do { (binds', ugrhss)
<- tcLocalBinds binds $
- mapM (wrapLocM (tcGRHS ctxt res_ty)) grhss
-
+ mapM (tcCollectingUsage . wrapLocM (tcGRHS ctxt res_ty)) grhss
+ ; let (usages, grhss') = unzip ugrhss
+ ; tcEmitBindingUsage $ supUEs usages
; return (GRHSs noExtField grhss' (L l binds')) }
-------------
@@ -412,7 +424,7 @@ tcGuardStmt ctxt (BindStmt _ pat rhs) res_ty thing_inside
= do { (rhs', rhs_ty) <- tcInferRhoNC rhs
-- Stmt has a context already
; (pat', thing) <- tcCheckPat_O (StmtCtxt ctxt) (lexprCtOrigin rhs)
- pat rhs_ty $
+ pat (unrestricted rhs_ty) $
thing_inside res_ty
; return (mkTcBindStmt pat' rhs', thing) }
@@ -445,7 +457,7 @@ tcLcStmt _ _ (LastStmt x body noret _) elt_ty thing_inside
tcLcStmt m_tc ctxt (BindStmt _ pat rhs) elt_ty thing_inside
= do { pat_ty <- newFlexiTyVarTy liftedTypeKind
; rhs' <- tcCheckMonoExpr rhs (mkTyConApp m_tc [pat_ty])
- ; (pat', thing) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $
+ ; (pat', thing) <- tcCheckPat (StmtCtxt ctxt) pat (unrestricted pat_ty) $
thing_inside elt_ty
; return (mkTcBindStmt pat' rhs', thing) }
@@ -500,14 +512,14 @@ tcLcStmt m_tc ctxt (TransStmt { trS_form = form, trS_stmts = stmts
by_arrow :: Type -> Type -- Wraps 'ty' to '(a->t) -> ty' if the By is present
by_arrow = case by' of
Nothing -> \ty -> ty
- Just (_,e_ty) -> \ty -> (alphaTy `mkVisFunTy` e_ty) `mkVisFunTy` ty
+ Just (_,e_ty) -> \ty -> (alphaTy `mkVisFunTyMany` e_ty) `mkVisFunTyMany` ty
tup_ty = mkBigCoreVarTupTy bndr_ids
poly_arg_ty = m_app alphaTy
poly_res_ty = m_app (n_app alphaTy)
using_poly_ty = mkInfForAllTy alphaTyVar $
by_arrow $
- poly_arg_ty `mkVisFunTy` poly_res_ty
+ poly_arg_ty `mkVisFunTyMany` poly_res_ty
; using' <- tcCheckPolyExpr using using_poly_ty
; let final_using = fmap (mkHsWrap (WpTyApp tup_ty)) using'
@@ -516,7 +528,7 @@ tcLcStmt m_tc ctxt (TransStmt { trS_form = form, trS_stmts = stmts
-- typically something like [(Int,Bool,Int)]
-- We don't know what tuple_ty is yet, so we use a variable
; let mk_n_bndr :: Name -> TcId -> TcId
- mk_n_bndr n_bndr_name bndr_id = mkLocalId n_bndr_name (n_app (idType bndr_id))
+ mk_n_bndr n_bndr_name bndr_id = mkLocalId n_bndr_name Many (n_app (idType bndr_id))
-- Ensure that every old binder of type `b` is linked up with its
-- new binder which should have type `n b`
@@ -550,8 +562,8 @@ tcMcStmt :: TcExprStmtChecker
tcMcStmt _ (LastStmt x body noret return_op) res_ty thing_inside
= do { (body', return_op')
<- tcSyntaxOp MCompOrigin return_op [SynRho] res_ty $
- \ [a_ty] ->
- tcCheckMonoExprNC body a_ty
+ \ [a_ty] [mult]->
+ tcScalingUsage mult $ tcCheckMonoExprNC body a_ty
; thing <- thing_inside (panic "tcMcStmt: thing_inside")
; return (LastStmt x body' noret return_op', thing) }
@@ -563,14 +575,14 @@ tcMcStmt _ (LastStmt x body noret return_op) res_ty thing_inside
tcMcStmt ctxt (BindStmt xbsrn pat rhs) res_ty thing_inside
-- (>>=) :: rhs_ty -> (pat_ty -> new_res_ty) -> res_ty
- = do { ((rhs', pat', thing, new_res_ty), bind_op')
+ = do { ((rhs', pat_mult, pat', thing, new_res_ty), bind_op')
<- tcSyntaxOp MCompOrigin (xbsrn_bindOp xbsrn)
[SynRho, SynFun SynAny SynRho] res_ty $
- \ [rhs_ty, pat_ty, new_res_ty] ->
- do { rhs' <- tcCheckMonoExprNC rhs rhs_ty
- ; (pat', thing) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $
+ \ [rhs_ty, pat_ty, new_res_ty] [rhs_mult, fun_mult, pat_mult] ->
+ do { rhs' <- tcScalingUsage rhs_mult $ tcCheckMonoExprNC rhs rhs_ty
+ ; (pat', thing) <- tcScalingUsage fun_mult $ tcCheckPat (StmtCtxt ctxt) pat (Scaled pat_mult pat_ty) $
thing_inside (mkCheckExpType new_res_ty)
- ; return (rhs', pat', thing, new_res_ty) }
+ ; return (rhs', pat_mult, pat', thing, new_res_ty) }
-- If (but only if) the pattern can fail, typecheck the 'fail' operator
; fail_op' <- fmap join . forM (xbsrn_failOp xbsrn) $ \fail ->
@@ -579,6 +591,7 @@ tcMcStmt ctxt (BindStmt xbsrn pat rhs) res_ty thing_inside
; let xbstc = XBindStmtTc
{ xbstc_bindOp = bind_op'
, xbstc_boundResultType = new_res_ty
+ , xbstc_boundResultMult = pat_mult
, xbstc_failOp = fail_op'
}
; return (BindStmt xbstc pat' rhs', thing) }
@@ -594,13 +607,14 @@ tcMcStmt _ (BodyStmt _ rhs then_op guard_op) res_ty thing_inside
-- Where test_ty is, for example, Bool
; ((thing, rhs', rhs_ty, guard_op'), then_op')
<- tcSyntaxOp MCompOrigin then_op [SynRho, SynRho] res_ty $
- \ [rhs_ty, new_res_ty] ->
+ \ [rhs_ty, new_res_ty] [rhs_mult, fun_mult] ->
do { (rhs', guard_op')
- <- tcSyntaxOp MCompOrigin guard_op [SynAny]
+ <- tcScalingUsage rhs_mult $
+ tcSyntaxOp MCompOrigin guard_op [SynAny]
(mkCheckExpType rhs_ty) $
- \ [test_ty] ->
- tcCheckMonoExpr rhs test_ty
- ; thing <- thing_inside (mkCheckExpType new_res_ty)
+ \ [test_ty] [test_mult] ->
+ tcScalingUsage test_mult $ tcCheckMonoExpr rhs test_ty
+ ; thing <- tcScalingUsage fun_mult $ thing_inside (mkCheckExpType new_res_ty)
; return (thing, rhs', rhs_ty, guard_op') }
; return (BodyStmt rhs_ty rhs' then_op' guard_op', thing) }
@@ -640,7 +654,7 @@ tcMcStmt ctxt (TransStmt { trS_stmts = stmts, trS_bndrs = bindersMap
-- or res ('by' absent)
by_arrow = case by of
Nothing -> \res -> res
- Just {} -> \res -> (alphaTy `mkVisFunTy` by_e_ty) `mkVisFunTy` res
+ Just {} -> \res -> (alphaTy `mkVisFunTyMany` by_e_ty) `mkVisFunTyMany` res
poly_arg_ty = m1_ty `mkAppTy` alphaTy
using_arg_ty = m1_ty `mkAppTy` tup_ty
@@ -648,7 +662,7 @@ tcMcStmt ctxt (TransStmt { trS_stmts = stmts, trS_bndrs = bindersMap
using_res_ty = m2_ty `mkAppTy` n_app tup_ty
using_poly_ty = mkInfForAllTy alphaTyVar $
by_arrow $
- poly_arg_ty `mkVisFunTy` poly_res_ty
+ poly_arg_ty `mkVisFunTyMany` poly_res_ty
-- 'stmts' returns a result of type (m1_ty tuple_ty),
-- typically something like [(Int,Bool,Int)]
@@ -669,7 +683,7 @@ tcMcStmt ctxt (TransStmt { trS_stmts = stmts, trS_bndrs = bindersMap
-- return :: (a,b,c,..) -> m (a,b,c,..)
; (_, return_op') <- tcSyntaxOp MCompOrigin return_op
[synKnownType (mkBigCoreVarTupTy bndr_ids)]
- res_ty' $ \ _ -> return ()
+ res_ty' $ \ _ _ -> return ()
; return (bndr_ids, by', return_op') }
@@ -678,8 +692,8 @@ tcMcStmt ctxt (TransStmt { trS_stmts = stmts, trS_bndrs = bindersMap
; new_res_ty <- newFlexiTyVarTy liftedTypeKind
; (_, bind_op') <- tcSyntaxOp MCompOrigin bind_op
[ synKnownType using_res_ty
- , synKnownType (n_app tup_ty `mkVisFunTy` new_res_ty) ]
- res_ty $ \ _ -> return ()
+ , synKnownType (n_app tup_ty `mkVisFunTyMany` new_res_ty) ]
+ res_ty $ \ _ _ -> return ()
--------------- Typecheck the 'fmap' function -------------
; fmap_op' <- case form of
@@ -687,9 +701,9 @@ tcMcStmt ctxt (TransStmt { trS_stmts = stmts, trS_bndrs = bindersMap
_ -> fmap unLoc . tcCheckPolyExpr (noLoc fmap_op) $
mkInfForAllTy alphaTyVar $
mkInfForAllTy betaTyVar $
- (alphaTy `mkVisFunTy` betaTy)
- `mkVisFunTy` (n_app alphaTy)
- `mkVisFunTy` (n_app betaTy)
+ (alphaTy `mkVisFunTyMany` betaTy)
+ `mkVisFunTyMany` (n_app alphaTy)
+ `mkVisFunTyMany` (n_app betaTy)
--------------- Typecheck the 'using' function -------------
-- using :: ((a,b,c)->t) -> m1 (a,b,c) -> m2 (n (a,b,c))
@@ -699,7 +713,7 @@ tcMcStmt ctxt (TransStmt { trS_stmts = stmts, trS_bndrs = bindersMap
--------------- Building the bindersMap ----------------
; let mk_n_bndr :: Name -> TcId -> TcId
- mk_n_bndr n_bndr_name bndr_id = mkLocalId n_bndr_name (n_app (idType bndr_id))
+ mk_n_bndr n_bndr_name bndr_id = mkLocalId n_bndr_name Many (n_app (idType bndr_id))
-- Ensure that every old binder of type `b` is linked up with its
-- new binder which should have type `n b`
@@ -752,9 +766,9 @@ tcMcStmt ctxt (ParStmt _ bndr_stmts_s mzip_op bind_op) res_ty thing_inside
; let mzip_ty = mkInfForAllTys [alphaTyVar, betaTyVar] $
(m_ty `mkAppTy` alphaTy)
- `mkVisFunTy`
+ `mkVisFunTyMany`
(m_ty `mkAppTy` betaTy)
- `mkVisFunTy`
+ `mkVisFunTyMany`
(m_ty `mkAppTy` mkBoxedTupleTy [alphaTy, betaTy])
; mzip_op' <- unLoc `fmap` tcCheckPolyExpr (noLoc mzip_op) mzip_ty
@@ -770,7 +784,7 @@ tcMcStmt ctxt (ParStmt _ bndr_stmts_s mzip_op bind_op) res_ty thing_inside
<- tcSyntaxOp MCompOrigin bind_op
[ synKnownType (m_ty `mkAppTy` tuple_ty)
, SynFun (synKnownType tuple_ty) SynRho ] res_ty $
- \ [inner_res_ty] ->
+ \ [inner_res_ty] _ ->
do { stuff <- loop m_ty (mkCheckExpType inner_res_ty)
tup_tys bndr_stmts_s
; return (stuff, inner_res_ty) }
@@ -800,7 +814,7 @@ tcMcStmt ctxt (ParStmt _ bndr_stmts_s mzip_op bind_op) res_ty thing_inside
; (_, return_op') <-
tcSyntaxOp MCompOrigin return_op
[synKnownType tup_ty] m_tup_ty' $
- \ _ -> return ()
+ \ _ _ -> return ()
; (pairs', thing) <- loop m_ty inner_res_ty tup_tys_in pairs
; return (ids, return_op', pairs', thing) }
; return (ParStmtBlock x stmts' ids return_op' : pairs', thing) }
@@ -824,17 +838,17 @@ tcDoStmt _ (LastStmt x body noret _) res_ty thing_inside
tcDoStmt ctxt (BindStmt xbsrn pat rhs) res_ty thing_inside
= do { -- Deal with rebindable syntax:
- -- (>>=) :: rhs_ty -> (pat_ty -> new_res_ty) -> res_ty
+ -- (>>=) :: rhs_ty ->_rhs_mult (pat_ty ->_pat_mult new_res_ty) ->_fun_mult res_ty
-- This level of generality is needed for using do-notation
-- in full generality; see #1537
- ((rhs', pat', new_res_ty, thing), bind_op')
+ ((rhs', pat_mult, pat', new_res_ty, thing), bind_op')
<- tcSyntaxOp DoOrigin (xbsrn_bindOp xbsrn) [SynRho, SynFun SynAny SynRho] res_ty $
- \ [rhs_ty, pat_ty, new_res_ty] ->
- do { rhs' <- tcCheckMonoExprNC rhs rhs_ty
- ; (pat', thing) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $
+ \ [rhs_ty, pat_ty, new_res_ty] [rhs_mult,fun_mult,pat_mult] ->
+ do { rhs' <-tcScalingUsage rhs_mult $ tcCheckMonoExprNC rhs rhs_ty
+ ; (pat', thing) <- tcScalingUsage fun_mult $ tcCheckPat (StmtCtxt ctxt) pat (Scaled pat_mult pat_ty) $
thing_inside (mkCheckExpType new_res_ty)
- ; return (rhs', pat', new_res_ty, thing) }
+ ; return (rhs', pat_mult, pat', new_res_ty, thing) }
-- If (but only if) the pattern can fail, typecheck the 'fail' operator
; fail_op' <- fmap join . forM (xbsrn_failOp xbsrn) $ \fail ->
@@ -842,6 +856,7 @@ tcDoStmt ctxt (BindStmt xbsrn pat rhs) res_ty thing_inside
; let xbstc = XBindStmtTc
{ xbstc_bindOp = bind_op'
, xbstc_boundResultType = new_res_ty
+ , xbstc_boundResultMult = pat_mult
, xbstc_failOp = fail_op'
}
; return (BindStmt xbstc pat' rhs', thing) }
@@ -854,7 +869,7 @@ tcDoStmt ctxt (ApplicativeStmt _ pairs mb_join) res_ty thing_inside
Just join_op ->
second Just <$>
(tcSyntaxOp DoOrigin join_op [SynRho] res_ty $
- \ [rhs_ty] -> tc_app_stmts (mkCheckExpType rhs_ty))
+ \ [rhs_ty] [rhs_mult] -> tcScalingUsage rhs_mult $ tc_app_stmts (mkCheckExpType rhs_ty))
; return (ApplicativeStmt body_ty pairs' mb_join', thing) }
@@ -863,9 +878,9 @@ tcDoStmt _ (BodyStmt _ rhs then_op _) res_ty thing_inside
-- (>>) :: rhs_ty -> new_res_ty -> res_ty
; ((rhs', rhs_ty, thing), then_op')
<- tcSyntaxOp DoOrigin then_op [SynRho, SynRho] res_ty $
- \ [rhs_ty, new_res_ty] ->
- do { rhs' <- tcCheckMonoExprNC rhs rhs_ty
- ; thing <- thing_inside (mkCheckExpType new_res_ty)
+ \ [rhs_ty, new_res_ty] [rhs_mult,fun_mult] ->
+ do { rhs' <- tcScalingUsage rhs_mult $ tcCheckMonoExprNC rhs rhs_ty
+ ; thing <- tcScalingUsage fun_mult $ thing_inside (mkCheckExpType new_res_ty)
; return (rhs', rhs_ty, thing) }
; return (BodyStmt rhs_ty rhs' then_op' noSyntaxExpr, thing) }
@@ -875,7 +890,8 @@ tcDoStmt ctxt (RecStmt { recS_stmts = stmts, recS_later_ids = later_names
res_ty thing_inside
= do { let tup_names = rec_names ++ filterOut (`elem` rec_names) later_names
; tup_elt_tys <- newFlexiTyVarTys (length tup_names) liftedTypeKind
- ; let tup_ids = zipWith mkLocalId tup_names tup_elt_tys
+ ; let tup_ids = zipWith (\n t -> mkLocalId n Many t) tup_names tup_elt_tys
+ -- Many because it's a recursive definition
tup_ty = mkBigCoreTupTy tup_elt_tys
; tcExtendIdEnv tup_ids $ do
@@ -888,21 +904,21 @@ tcDoStmt ctxt (RecStmt { recS_stmts = stmts, recS_later_ids = later_names
-- be polymorphic) with those of "knot-tied" Ids
; (_, ret_op')
<- tcSyntaxOp DoOrigin ret_op [synKnownType tup_ty]
- inner_res_ty $ \_ -> return ()
+ inner_res_ty $ \_ _ -> return ()
; return (ret_op', tup_rets) }
; ((_, mfix_op'), mfix_res_ty)
<- tcInfer $ \ exp_ty ->
tcSyntaxOp DoOrigin mfix_op
- [synKnownType (mkVisFunTy tup_ty stmts_ty)] exp_ty $
- \ _ -> return ()
+ [synKnownType (mkVisFunTyMany tup_ty stmts_ty)] exp_ty $
+ \ _ _ -> return ()
; ((thing, new_res_ty), bind_op')
<- tcSyntaxOp DoOrigin bind_op
[ synKnownType mfix_res_ty
- , synKnownType tup_ty `SynFun` SynRho ]
+ , SynFun (synKnownType tup_ty) SynRho ]
res_ty $
- \ [new_res_ty] ->
+ \ [new_res_ty] _ ->
do { thing <- thing_inside (mkCheckExpType new_res_ty)
; return (thing, new_res_ty) }
@@ -949,7 +965,7 @@ tcMonadFailOp orig pat fail_op res_ty
= return Nothing
| otherwise
= Just . snd <$> (tcSyntaxOp orig fail_op [synKnownType stringTy]
- (mkCheckExpType res_ty) $ \_ -> return ())
+ (mkCheckExpType res_ty) $ \_ _ -> return ())
{-
Note [Treat rebindable syntax first]
@@ -993,7 +1009,7 @@ tcApplicativeStmts ctxt pairs rhs_ty thing_inside
; ts <- replicateM (arity-1) $ newInferExpType
; exp_tys <- replicateM arity $ newFlexiTyVarTy liftedTypeKind
; pat_tys <- replicateM arity $ newFlexiTyVarTy liftedTypeKind
- ; let fun_ty = mkVisFunTys pat_tys body_ty
+ ; let fun_ty = mkVisFunTysMany pat_tys body_ty
-- NB. do the <$>,<*> operators first, we don't want type errors here
-- i.e. goOps before goArgs
@@ -1018,7 +1034,7 @@ tcApplicativeStmts ctxt pairs rhs_ty thing_inside
= do { (_, op')
<- tcSyntaxOp DoOrigin op
[synKnownType t_left, synKnownType exp_ty] t_i $
- \ _ -> return ()
+ \ _ _ -> return ()
; t_i <- readExpType t_i
; ops' <- goOps t_i ops
; return (op' : ops') }
@@ -1035,7 +1051,7 @@ tcApplicativeStmts ctxt pairs rhs_ty thing_inside
= setSrcSpan (combineSrcSpans (getLoc pat) (getLoc rhs)) $
addErrCtxt (pprStmtInCtxt ctxt (mkRnBindStmt pat rhs)) $
do { rhs' <- tcCheckMonoExprNC rhs exp_ty
- ; (pat', _) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $
+ ; (pat', _) <- tcCheckPat (StmtCtxt ctxt) pat (unrestricted pat_ty) $
return ()
; fail_op' <- fmap join . forM fail_op $ \fail ->
tcMonadFailOp (DoPatOrigin pat) pat' fail body_ty
@@ -1052,7 +1068,7 @@ tcApplicativeStmts ctxt pairs rhs_ty thing_inside
tcStmtsAndThen ctxt tcDoStmt stmts (mkCheckExpType exp_ty) $
\res_ty -> do
{ ret' <- tcExpr ret res_ty
- ; (pat', _) <- tcCheckPat (StmtCtxt ctxt) pat pat_ty $
+ ; (pat', _) <- tcCheckPat (StmtCtxt ctxt) pat (unrestricted pat_ty) $
return ()
; return (ret', pat')
}
diff --git a/compiler/GHC/Tc/Gen/Pat.hs b/compiler/GHC/Tc/Gen/Pat.hs
index 830f04a89d..9cbfce243a 100644
--- a/compiler/GHC/Tc/Gen/Pat.hs
+++ b/compiler/GHC/Tc/Gen/Pat.hs
@@ -41,6 +41,7 @@ import GHC.Types.Id
import GHC.Types.Var
import GHC.Types.Name
import GHC.Types.Name.Reader
+import GHC.Core.Multiplicity
import GHC.Tc.Utils.Env
import GHC.Tc.Utils.TcMType
import GHC.Tc.Validity( arityErr )
@@ -77,7 +78,7 @@ import GHC.Data.List.SetOps ( getNth )
tcLetPat :: (Name -> Maybe TcId)
-> LetBndrSpec
- -> LPat GhcRn -> ExpSigmaType
+ -> LPat GhcRn -> Scaled ExpSigmaType
-> TcM a
-> TcM (LPat GhcTcId, a)
tcLetPat sig_fn no_gen pat pat_ty thing_inside
@@ -94,7 +95,7 @@ tcLetPat sig_fn no_gen pat pat_ty thing_inside
-----------------
tcPats :: HsMatchContext GhcRn
-> [LPat GhcRn] -- Patterns,
- -> [ExpSigmaType] -- and their types
+ -> [Scaled ExpSigmaType] -- and their types
-> TcM a -- and the checker for the body
-> TcM ([LPat GhcTcId], a)
@@ -119,12 +120,12 @@ tcInferPat :: HsMatchContext GhcRn -> LPat GhcRn
-> TcM ((LPat GhcTcId, a), TcSigmaType)
tcInferPat ctxt pat thing_inside
= tcInfer $ \ exp_ty ->
- tc_lpat exp_ty penv pat thing_inside
+ tc_lpat (unrestricted exp_ty) penv pat thing_inside
where
penv = PE { pe_lazy = False, pe_ctxt = LamPat ctxt, pe_orig = PatOrigin }
tcCheckPat :: HsMatchContext GhcRn
- -> LPat GhcRn -> TcSigmaType
+ -> LPat GhcRn -> Scaled TcSigmaType
-> TcM a -- Checker for body
-> TcM (LPat GhcTcId, a)
tcCheckPat ctxt = tcCheckPat_O ctxt PatOrigin
@@ -132,11 +133,11 @@ tcCheckPat ctxt = tcCheckPat_O ctxt PatOrigin
-- | A variant of 'tcPat' that takes a custom origin
tcCheckPat_O :: HsMatchContext GhcRn
-> CtOrigin -- ^ origin to use if the type needs inst'ing
- -> LPat GhcRn -> TcSigmaType
+ -> LPat GhcRn -> Scaled TcSigmaType
-> TcM a -- Checker for body
-> TcM (LPat GhcTcId, a)
-tcCheckPat_O ctxt orig pat pat_ty thing_inside
- = tc_lpat (mkCheckExpType pat_ty) penv pat thing_inside
+tcCheckPat_O ctxt orig pat (Scaled pat_mult pat_ty) thing_inside
+ = tc_lpat (Scaled pat_mult (mkCheckExpType pat_ty)) penv pat thing_inside
where
penv = PE { pe_lazy = False, pe_ctxt = LamPat ctxt, pe_orig = orig }
@@ -198,7 +199,7 @@ inPatBind (PE { pe_ctxt = LamPat {} }) = False
* *
********************************************************************* -}
-tcPatBndr :: PatEnv -> Name -> ExpSigmaType -> TcM (HsWrapper, TcId)
+tcPatBndr :: PatEnv -> Name -> Scaled ExpSigmaType -> TcM (HsWrapper, TcId)
-- (coi, xp) = tcPatBndr penv x pat_ty
-- Then coi : pat_ty ~ typeof(xp)
--
@@ -210,34 +211,36 @@ tcPatBndr penv@(PE { pe_ctxt = LetPat { pc_lvl = bind_lvl
-- Note [Typechecking pattern bindings] in GHC.Tc.Gen.Bind
| Just bndr_id <- sig_fn bndr_name -- There is a signature
- = do { wrap <- tc_sub_type penv exp_pat_ty (idType bndr_id)
+ = do { wrap <- tc_sub_type penv (scaledThing exp_pat_ty) (idType bndr_id)
-- See Note [Subsumption check at pattern variables]
; traceTc "tcPatBndr(sig)" (ppr bndr_id $$ ppr (idType bndr_id) $$ ppr exp_pat_ty)
; return (wrap, bndr_id) }
| otherwise -- No signature
- = do { (co, bndr_ty) <- case exp_pat_ty of
+ = do { (co, bndr_ty) <- case scaledThing exp_pat_ty of
Check pat_ty -> promoteTcType bind_lvl pat_ty
Infer infer_res -> ASSERT( bind_lvl == ir_lvl infer_res )
-- If we were under a constructor that bumped
-- the level, we'd be in checking mode
do { bndr_ty <- inferResultToType infer_res
; return (mkTcNomReflCo bndr_ty, bndr_ty) }
- ; bndr_id <- newLetBndr no_gen bndr_name bndr_ty
+ ; let bndr_mult = scaledMult exp_pat_ty
+ ; bndr_id <- newLetBndr no_gen bndr_name bndr_mult bndr_ty
; traceTc "tcPatBndr(nosig)" (vcat [ ppr bind_lvl
, ppr exp_pat_ty, ppr bndr_ty, ppr co
, ppr bndr_id ])
; return (mkWpCastN co, bndr_id) }
tcPatBndr _ bndr_name pat_ty
- = do { pat_ty <- expTypeToType pat_ty
+ = do { let pat_mult = scaledMult pat_ty
+ ; pat_ty <- expTypeToType (scaledThing pat_ty)
; traceTc "tcPatBndr(not let)" (ppr bndr_name $$ ppr pat_ty)
- ; return (idHsWrapper, mkLocalIdOrCoVar bndr_name pat_ty) }
+ ; return (idHsWrapper, mkLocalIdOrCoVar bndr_name pat_mult pat_ty) }
-- We should not have "OrCoVar" here, this is a bug (#17545)
-- Whether or not there is a sig is irrelevant,
-- as this is local
-newLetBndr :: LetBndrSpec -> Name -> TcType -> TcM TcId
+newLetBndr :: LetBndrSpec -> Name -> Mult -> TcType -> TcM TcId
-- Make up a suitable Id for the pattern-binder.
-- See Note [Typechecking pattern bindings], item (4) in GHC.Tc.Gen.Bind
--
@@ -248,11 +251,11 @@ newLetBndr :: LetBndrSpec -> Name -> TcType -> TcM TcId
-- In the monomorphic case when we are not going to generalise
-- (plan NoGen, no_gen = LetGblBndr) there is no AbsBinds,
-- and we use the original name directly
-newLetBndr LetLclBndr name ty
+newLetBndr LetLclBndr name w ty
= do { mono_name <- cloneLocalName name
- ; return (mkLocalId mono_name ty) }
-newLetBndr (LetGblBndr prags) name ty
- = addInlinePrags (mkLocalId name ty) (lookupPragEnv prags name)
+ ; return (mkLocalId mono_name w ty) }
+newLetBndr (LetGblBndr prags) name w ty
+ = addInlinePrags (mkLocalId name w ty) (lookupPragEnv prags name)
tc_sub_type :: PatEnv -> ExpSigmaType -> TcSigmaType -> TcM HsWrapper
-- tcSubTypeET with the UserTypeCtxt specialised to GenSigCtxt
@@ -322,7 +325,7 @@ tcMultiple tc_pat penv args thing_inside
; loop penv args }
--------------------
-tc_lpat :: ExpSigmaType
+tc_lpat :: Scaled ExpSigmaType
-> Checker (LPat GhcRn) (LPat GhcTcId)
tc_lpat pat_ty penv (L span pat) thing_inside
= setSrcSpan span $
@@ -330,7 +333,7 @@ tc_lpat pat_ty penv (L span pat) thing_inside
thing_inside
; return (L span pat', res) }
-tc_lpats :: [ExpSigmaType]
+tc_lpats :: [Scaled ExpSigmaType]
-> Checker [LPat GhcRn] [LPat GhcTcId]
tc_lpats tys penv pats
= ASSERT2( equalLength pats tys, ppr pats $$ ppr tys )
@@ -339,17 +342,24 @@ tc_lpats tys penv pats
(zipEqual "tc_lpats" pats tys)
--------------------
-tc_pat :: ExpSigmaType
+-- See Note [tcSubMult's wrapper] in TcUnify.
+checkManyPattern :: Scaled a -> TcM HsWrapper
+checkManyPattern pat_ty = tcSubMult NonLinearPatternOrigin Many (scaledMult pat_ty)
+
+tc_pat :: Scaled ExpSigmaType
-- ^ Fully refined result type
-> Checker (Pat GhcRn) (Pat GhcTcId)
-- ^ Translated pattern
+
tc_pat pat_ty penv ps_pat thing_inside = case ps_pat of
VarPat x (L l name) -> do
{ (wrap, id) <- tcPatBndr penv name pat_ty
- ; res <- tcExtendIdEnv1 name id thing_inside
- ; pat_ty <- readExpType pat_ty
- ; return (mkHsWrapPat wrap (VarPat x (L l id)) pat_ty, res) }
+ ; (res, mult_wrap) <- tcCheckUsage name (scaledMult pat_ty) $
+ tcExtendIdEnv1 name id thing_inside
+ -- See Note [tcSubMult's wrapper] in TcUnify.
+ ; pat_ty <- readExpType (scaledThing pat_ty)
+ ; return (mkHsWrapPat (wrap <.> mult_wrap) (VarPat x (L l id)) pat_ty, res) }
ParPat x pat -> do
{ (pat', res) <- tc_lpat pat_ty penv pat thing_inside
@@ -360,7 +370,9 @@ tc_pat pat_ty penv ps_pat thing_inside = case ps_pat of
; return (BangPat x pat', res) }
LazyPat x pat -> do
- { (pat', (res, pat_ct))
+ { mult_wrap <- checkManyPattern pat_ty
+ -- See Note [tcSubMult's wrapper] in TcUnify.
+ ; (pat', (res, pat_ct))
<- tc_lpat pat_ty (makeLazy penv) pat $
captureConstraints thing_inside
-- Ignore refined penv', revert to penv
@@ -370,20 +382,24 @@ tc_pat pat_ty penv ps_pat thing_inside = case ps_pat of
-- see Note [Hopping the LIE in lazy patterns]
-- Check that the expected pattern type is itself lifted
- ; pat_ty <- readExpType pat_ty
+ ; pat_ty <- readExpType (scaledThing pat_ty)
; _ <- unifyType Nothing (tcTypeKind pat_ty) liftedTypeKind
- ; return (LazyPat x pat', res) }
+ ; return (mkHsWrapPat mult_wrap (LazyPat x pat') pat_ty, res) }
WildPat _ -> do
- { res <- thing_inside
- ; pat_ty <- expTypeToType pat_ty
- ; return (WildPat pat_ty, res) }
+ { mult_wrap <- checkManyPattern pat_ty
+ -- See Note [tcSubMult's wrapper] in TcUnify.
+ ; res <- thing_inside
+ ; pat_ty <- expTypeToType (scaledThing pat_ty)
+ ; return (mkHsWrapPat mult_wrap (WildPat pat_ty) pat_ty, res) }
AsPat x (L nm_loc name) pat -> do
- { (wrap, bndr_id) <- setSrcSpan nm_loc (tcPatBndr penv name pat_ty)
+ { mult_wrap <- checkManyPattern pat_ty
+ -- See Note [tcSubMult's wrapper] in TcUnify.
+ ; (wrap, bndr_id) <- setSrcSpan nm_loc (tcPatBndr penv name pat_ty)
; (pat', res) <- tcExtendIdEnv1 name bndr_id $
- tc_lpat (mkCheckExpType $ idType bndr_id)
+ tc_lpat (pat_ty `scaledSet`(mkCheckExpType $ idType bndr_id))
penv pat thing_inside
-- NB: if we do inference on:
-- \ (y@(x::forall a. a->a)) = e
@@ -392,35 +408,43 @@ tc_pat pat_ty penv ps_pat thing_inside = case ps_pat of
-- perhaps be fixed, but only with a bit more work.
--
-- If you fix it, don't forget the bindInstsOfPatIds!
- ; pat_ty <- readExpType pat_ty
- ; return (mkHsWrapPat wrap (AsPat x (L nm_loc bndr_id) pat') pat_ty,
- res) }
+ ; pat_ty <- readExpType (scaledThing pat_ty)
+ ; return (mkHsWrapPat (wrap <.> mult_wrap) (AsPat x (L nm_loc bndr_id) pat') pat_ty, res) }
ViewPat _ expr pat -> do
- { (expr',expr_ty) <- tcInferRho expr
+ { mult_wrap <- checkManyPattern pat_ty
+ -- See Note [tcSubMult's wrapper] in TcUnify.
+ --
+ -- It should be possible to have view patterns at linear (or otherwise
+ -- non-Many) multiplicity. But it is not clear at the moment what
+ -- restriction need to be put in place, if any, for linear view
+ -- patterns to desugar to type-correct Core.
+
+ ; (expr',expr_ty) <- tcInferRho expr
-- Note [View patterns and polymorphism]
-- Expression must be a function
; let expr_orig = lexprCtOrigin expr
herald = text "A view pattern expression expects"
- ; (expr_wrap1, inf_arg_ty, inf_res_sigma)
+ ; (expr_wrap1, Scaled _mult inf_arg_ty, inf_res_sigma)
<- matchActualFunTySigma herald expr_orig (Just (unLoc expr)) (1,[]) expr_ty
-- See Note [View patterns and polymorphism]
-- expr_wrap1 :: expr_ty "->" (inf_arg_ty -> inf_res_sigma)
-- Check that overall pattern is more polymorphic than arg type
- ; expr_wrap2 <- tc_sub_type penv pat_ty inf_arg_ty
+ ; expr_wrap2 <- tc_sub_type penv (scaledThing pat_ty) inf_arg_ty
-- expr_wrap2 :: pat_ty "->" inf_arg_ty
-- Pattern must have inf_res_sigma
- ; (pat', res) <- tc_lpat (mkCheckExpType inf_res_sigma) penv pat thing_inside
+ ; (pat', res) <- tc_lpat (pat_ty `scaledSet` mkCheckExpType inf_res_sigma) penv pat thing_inside
- ; pat_ty <- readExpType pat_ty
+ ; let Scaled w h_pat_ty = pat_ty
+ ; pat_ty <- readExpType h_pat_ty
; let expr_wrap2' = mkWpFun expr_wrap2 idHsWrapper
- pat_ty inf_res_sigma doc
+ (Scaled w pat_ty) inf_res_sigma doc
-- expr_wrap2' :: (inf_arg_ty -> inf_res_sigma) "->"
-- (pat_ty -> inf_res_sigma)
- expr_wrap = expr_wrap2' <.> expr_wrap1
+ expr_wrap = expr_wrap2' <.> expr_wrap1 <.> mult_wrap
doc = text "When checking the view pattern function:" <+> (ppr expr)
; return (ViewPat pat_ty (mkLHsWrap expr_wrap expr') pat', res)}
@@ -446,35 +470,35 @@ Fortunately that's what matchExpectedFunTySigma returns anyway.
-- See Note [Pattern coercions] below
SigPat _ pat sig_ty -> do
{ (inner_ty, tv_binds, wcs, wrap) <- tcPatSig (inPatBind penv)
- sig_ty pat_ty
+ sig_ty (scaledThing pat_ty)
-- Using tcExtendNameTyVarEnv is appropriate here
-- because we're not really bringing fresh tyvars into scope.
-- We're *naming* existing tyvars. Note that it is OK for a tyvar
-- from an outer scope to mention one of these tyvars in its kind.
; (pat', res) <- tcExtendNameTyVarEnv wcs $
tcExtendNameTyVarEnv tv_binds $
- tc_lpat (mkCheckExpType inner_ty) penv pat thing_inside
- ; pat_ty <- readExpType pat_ty
+ tc_lpat (pat_ty `scaledSet` mkCheckExpType inner_ty) penv pat thing_inside
+ ; pat_ty <- readExpType (scaledThing pat_ty)
; return (mkHsWrapPat wrap (SigPat inner_ty pat' sig_ty) pat_ty, res) }
------------------------
-- Lists, tuples, arrays
ListPat Nothing pats -> do
- { (coi, elt_ty) <- matchExpectedPatTy matchExpectedListTy penv pat_ty
- ; (pats', res) <- tcMultiple (tc_lpat $ mkCheckExpType elt_ty)
+ { (coi, elt_ty) <- matchExpectedPatTy matchExpectedListTy penv (scaledThing pat_ty)
+ ; (pats', res) <- tcMultiple (tc_lpat (pat_ty `scaledSet` mkCheckExpType elt_ty))
penv pats thing_inside
- ; pat_ty <- readExpType pat_ty
+ ; pat_ty <- readExpType (scaledThing pat_ty)
; return (mkHsWrapPat coi
(ListPat (ListPatTc elt_ty Nothing) pats') pat_ty, res)
}
ListPat (Just e) pats -> do
- { tau_pat_ty <- expTypeToType pat_ty
+ { tau_pat_ty <- expTypeToType (scaledThing pat_ty)
; ((pats', res, elt_ty), e')
<- tcSyntaxOpGen ListOrigin e [SynType (mkCheckExpType tau_pat_ty)]
SynList $
- \ [elt_ty] ->
- do { (pats', res) <- tcMultiple (tc_lpat $ mkCheckExpType elt_ty)
+ \ [elt_ty] _ ->
+ do { (pats', res) <- tcMultiple (tc_lpat (pat_ty `scaledSet` mkCheckExpType elt_ty))
penv pats thing_inside
; return (pats', res, elt_ty) }
; return (ListPat (ListPatTc elt_ty (Just (tau_pat_ty,e'))) pats', res)
@@ -486,12 +510,12 @@ Fortunately that's what matchExpectedFunTySigma returns anyway.
-- NB: tupleTyCon does not flatten 1-tuples
-- See Note [Don't flatten tuples from HsSyn] in GHC.Core.Make
; (coi, arg_tys) <- matchExpectedPatTy (matchExpectedTyConApp tc)
- penv pat_ty
+ penv (scaledThing pat_ty)
-- Unboxed tuples have RuntimeRep vars, which we discard:
-- See Note [Unboxed tuple RuntimeRep vars] in GHC.Core.TyCon
; let con_arg_tys = case boxity of Unboxed -> drop arity arg_tys
Boxed -> arg_tys
- ; (pats', res) <- tc_lpats (map mkCheckExpType con_arg_tys)
+ ; (pats', res) <- tc_lpats (map (scaledSet pat_ty . mkCheckExpType) con_arg_tys)
penv pats thing_inside
; dflags <- getDynFlags
@@ -508,7 +532,7 @@ Fortunately that's what matchExpectedFunTySigma returns anyway.
isBoxed boxity = LazyPat noExtField (noLoc unmangled_result)
| otherwise = unmangled_result
- ; pat_ty <- readExpType pat_ty
+ ; pat_ty <- readExpType (scaledThing pat_ty)
; ASSERT( con_arg_tys `equalLength` pats ) -- Syntactically enforced
return (mkHsWrapPat coi possibly_mangled_result pat_ty, res)
}
@@ -516,12 +540,12 @@ Fortunately that's what matchExpectedFunTySigma returns anyway.
SumPat _ pat alt arity -> do
{ let tc = sumTyCon arity
; (coi, arg_tys) <- matchExpectedPatTy (matchExpectedTyConApp tc)
- penv pat_ty
+ penv (scaledThing pat_ty)
; -- Drop levity vars, we don't care about them here
let con_arg_tys = drop arity arg_tys
- ; (pat', res) <- tc_lpat (mkCheckExpType (con_arg_tys `getNth` (alt - 1)))
+ ; (pat', res) <- tc_lpat (pat_ty `scaledSet` mkCheckExpType (con_arg_tys `getNth` (alt - 1)))
penv pat thing_inside
- ; pat_ty <- readExpType pat_ty
+ ; pat_ty <- readExpType (scaledThing pat_ty)
; return (mkHsWrapPat coi (SumPat con_arg_tys pat' alt arity) pat_ty
, res)
}
@@ -535,9 +559,9 @@ Fortunately that's what matchExpectedFunTySigma returns anyway.
-- Literal patterns
LitPat x simple_lit -> do
{ let lit_ty = hsLitType simple_lit
- ; wrap <- tc_sub_type penv pat_ty lit_ty
+ ; wrap <- tc_sub_type penv (scaledThing pat_ty) lit_ty
; res <- thing_inside
- ; pat_ty <- readExpType pat_ty
+ ; pat_ty <- readExpType (scaledThing pat_ty)
; return ( mkHsWrapPat wrap (LitPat x (convertLit simple_lit)) pat_ty
, res) }
@@ -560,11 +584,16 @@ Fortunately that's what matchExpectedFunTySigma returns anyway.
--
-- When there is no negation, neg_lit_ty and lit_ty are the same
NPat _ (L l over_lit) mb_neg eq -> do
- { let orig = LiteralOrigin over_lit
+ { mult_wrap <- checkManyPattern pat_ty
+ -- See Note [tcSubMult's wrapper] in TcUnify.
+ --
+ -- It may be possible to refine linear pattern so that they work in
+ -- linear environments. But it is not clear how useful this is.
+ ; let orig = LiteralOrigin over_lit
; ((lit', mb_neg'), eq')
- <- tcSyntaxOp orig eq [SynType pat_ty, SynAny]
+ <- tcSyntaxOp orig eq [SynType (scaledThing pat_ty), SynAny]
(mkCheckExpType boolTy) $
- \ [neg_lit_ty] ->
+ \ [neg_lit_ty] _ ->
let new_over_lit lit_ty = newOverloadedLit over_lit
(mkCheckExpType lit_ty)
in case mb_neg of
@@ -573,11 +602,14 @@ Fortunately that's what matchExpectedFunTySigma returns anyway.
-- The 'negate' is re-mappable syntax
second Just <$>
(tcSyntaxOp orig neg [SynRho] (mkCheckExpType neg_lit_ty) $
- \ [lit_ty] -> new_over_lit lit_ty)
+ \ [lit_ty] _ -> new_over_lit lit_ty)
+ -- applied to a closed literal: linearity doesn't matter as
+ -- literals are typed in an empty environment, hence have
+ -- all multiplicities.
; res <- thing_inside
- ; pat_ty <- readExpType pat_ty
- ; return (NPat pat_ty (L l lit') mb_neg' eq', res) }
+ ; pat_ty <- readExpType (scaledThing pat_ty)
+ ; return (mkHsWrapPat mult_wrap (NPat pat_ty (L l lit') mb_neg' eq') pat_ty, res) }
{-
Note [NPlusK patterns]
@@ -610,19 +642,21 @@ AST is used for the subtraction operation.
-- See Note [NPlusK patterns]
NPlusKPat _ (L nm_loc name)
(L loc lit) _ ge minus -> do
- { pat_ty <- expTypeToType pat_ty
+ { mult_wrap <- checkManyPattern pat_ty
+ -- See Note [tcSubMult's wrapper] in TcUnify.
+ ; pat_ty <- expTypeToType (scaledThing pat_ty)
; let orig = LiteralOrigin lit
; (lit1', ge')
<- tcSyntaxOp orig ge [synKnownType pat_ty, SynRho]
(mkCheckExpType boolTy) $
- \ [lit1_ty] ->
+ \ [lit1_ty] _ ->
newOverloadedLit lit (mkCheckExpType lit1_ty)
; ((lit2', minus_wrap, bndr_id), minus')
<- tcSyntaxOpGen orig minus [synKnownType pat_ty, SynRho] SynAny $
- \ [lit2_ty, var_ty] ->
+ \ [lit2_ty, var_ty] _ ->
do { lit2' <- newOverloadedLit lit (mkCheckExpType lit2_ty)
; (wrap, bndr_id) <- setSrcSpan nm_loc $
- tcPatBndr penv name (mkCheckExpType var_ty)
+ tcPatBndr penv name (unrestricted $ mkCheckExpType var_ty)
-- co :: var_ty ~ idType bndr_id
-- minus_wrap is applicable to minus'
@@ -650,7 +684,7 @@ AST is used for the subtraction operation.
-- we get warnings if we try. #17783
pat' = NPlusKPat pat_ty (L nm_loc bndr_id) (L loc lit1') lit2'
ge' minus''
- ; return (pat', res) }
+ ; return (mkHsWrapPat mult_wrap pat' pat_ty, res) }
-- HsSpliced is an annotation produced by 'GHC.Rename.Splice.rnSplicePat'.
-- Here we get rid of it and add the finalizers to the global environment.
@@ -813,7 +847,7 @@ to express the local scope of GADT refinements.
-- with scrutinee of type (T ty)
tcConPat :: PatEnv -> Located Name
- -> ExpSigmaType -- Type of the pattern
+ -> Scaled ExpSigmaType -- Type of the pattern
-> HsConPatDetails GhcRn -> TcM a
-> TcM (Pat GhcTcId, a)
tcConPat penv con_lname@(L _ con_name) pat_ty arg_pats thing_inside
@@ -826,10 +860,10 @@ tcConPat penv con_lname@(L _ con_name) pat_ty arg_pats thing_inside
}
tcDataConPat :: PatEnv -> Located Name -> DataCon
- -> ExpSigmaType -- Type of the pattern
+ -> Scaled ExpSigmaType -- Type of the pattern
-> HsConPatDetails GhcRn -> TcM a
-> TcM (Pat GhcTcId, a)
-tcDataConPat penv (L con_span con_name) data_con pat_ty
+tcDataConPat penv (L con_span con_name) data_con pat_ty_scaled
arg_pats thing_inside
= do { let tycon = dataConTyCon data_con
-- For data families this is the representation tycon
@@ -840,13 +874,13 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty
-- Instantiate the constructor type variables [a->ty]
-- This may involve doing a family-instance coercion,
-- and building a wrapper
- ; (wrap, ctxt_res_tys) <- matchExpectedConTy penv tycon pat_ty
- ; pat_ty <- readExpType pat_ty
+ ; (wrap, ctxt_res_tys) <- matchExpectedConTy penv tycon pat_ty_scaled
+ ; pat_ty <- readExpType (scaledThing pat_ty_scaled)
-- Add the stupid theta
; setSrcSpan con_span $ addDataConStupidTheta data_con ctxt_res_tys
- ; let all_arg_tys = eqSpecPreds eq_spec ++ theta ++ arg_tys
+ ; let all_arg_tys = eqSpecPreds eq_spec ++ theta ++ (map scaledThing arg_tys)
; checkExistentials ex_tvs all_arg_tys penv
; tenv <- instTyVarsWith PatOrigin univ_tvs ctxt_res_tys
@@ -861,7 +895,9 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty
-- pat_ty' is type of the actual constructor application
-- pat_ty' /= pat_ty iff coi /= IdCo
- arg_tys' = substTys tenv arg_tys
+ arg_tys' = substScaledTys tenv arg_tys
+ pat_mult = scaledMult pat_ty_scaled
+ arg_tys_scaled = map (scaleScaled pat_mult) arg_tys'
; traceTc "tcConPat" (vcat [ ppr con_name
, pprTyVars univ_tvs
@@ -875,7 +911,7 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty
; if null ex_tvs && null eq_spec && null theta
then do { -- The common case; no class bindings etc
-- (see Note [Arrows and patterns])
- (arg_pats', res) <- tcConArgs (RealDataCon data_con) arg_tys'
+ (arg_pats', res) <- tcConArgs (RealDataCon data_con) arg_tys_scaled
penv arg_pats thing_inside
; let res_pat = ConPat { pat_con = header
, pat_args = arg_pats'
@@ -912,7 +948,7 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty
; given <- newEvVars theta'
; (ev_binds, (arg_pats', res))
<- checkConstraints skol_info ex_tvs' given $
- tcConArgs (RealDataCon data_con) arg_tys' penv arg_pats thing_inside
+ tcConArgs (RealDataCon data_con) arg_tys_scaled penv arg_pats thing_inside
; let res_pat = ConPat
{ pat_con = header
@@ -929,7 +965,7 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty
} }
tcPatSynPat :: PatEnv -> Located Name -> PatSyn
- -> ExpSigmaType -- Type of the pattern
+ -> Scaled ExpSigmaType -- Type of the pattern
-> HsConPatDetails GhcRn -> TcM a
-> TcM (Pat GhcTcId, a)
tcPatSynPat penv (L con_span _) pat_syn pat_ty arg_pats thing_inside
@@ -937,15 +973,20 @@ tcPatSynPat penv (L con_span _) pat_syn pat_ty arg_pats thing_inside
; (subst, univ_tvs') <- newMetaTyVars univ_tvs
- ; let all_arg_tys = ty : prov_theta ++ arg_tys
+ ; let all_arg_tys = ty : prov_theta ++ (map scaledThing arg_tys)
; checkExistentials ex_tvs all_arg_tys penv
; (tenv, ex_tvs') <- tcInstSuperSkolTyVarsX subst ex_tvs
; let ty' = substTy tenv ty
- arg_tys' = substTys tenv arg_tys
+ arg_tys' = substScaledTys tenv arg_tys
+ pat_mult = scaledMult pat_ty
+ arg_tys_scaled = map (scaleScaled pat_mult) arg_tys'
prov_theta' = substTheta tenv prov_theta
req_theta' = substTheta tenv req_theta
- ; wrap <- tc_sub_type penv pat_ty ty'
+ ; mult_wrap <- checkManyPattern pat_ty
+ -- See Note [tcSubMult's wrapper] in TcUnify.
+
+ ; wrap <- tc_sub_type penv (scaledThing pat_ty) ty'
; traceTc "tcPatSynPat" (ppr pat_syn $$
ppr pat_ty $$
ppr ty' $$
@@ -966,7 +1007,7 @@ tcPatSynPat penv (L con_span _) pat_syn pat_ty arg_pats thing_inside
; traceTc "checkConstraints {" Outputable.empty
; (ev_binds, (arg_pats', res))
<- checkConstraints skol_info ex_tvs' prov_dicts' $
- tcConArgs (PatSynCon pat_syn) arg_tys' penv arg_pats thing_inside
+ tcConArgs (PatSynCon pat_syn) arg_tys_scaled penv arg_pats thing_inside
; traceTc "checkConstraints }" (ppr ev_binds)
; let res_pat = ConPat { pat_con = L con_span $ PatSynCon pat_syn
@@ -979,8 +1020,8 @@ tcPatSynPat penv (L con_span _) pat_syn pat_ty arg_pats thing_inside
, cpt_wrap = req_wrap
}
}
- ; pat_ty <- readExpType pat_ty
- ; return (mkHsWrapPat wrap res_pat pat_ty, res) }
+ ; pat_ty <- readExpType (scaledThing pat_ty)
+ ; return (mkHsWrapPat (wrap <.> mult_wrap) res_pat pat_ty, res) }
----------------------------
-- | Convenient wrapper for calling a matchExpectedXXX function
@@ -1001,9 +1042,9 @@ matchExpectedConTy :: PatEnv
-- constructor actually returns
-- In the case of a data family this is
-- the /representation/ TyCon
- -> ExpSigmaType -- The type of the pattern; in the case
- -- of a data family this would mention
- -- the /family/ TyCon
+ -> Scaled ExpSigmaType -- The type of the pattern; in the
+ -- case of a data family this would
+ -- mention the /family/ TyCon
-> TcM (HsWrapper, [TcSigmaType])
-- See Note [Matching constructor patterns]
-- Returns a wrapper : pat_ty "->" T ty1 ... tyn
@@ -1011,7 +1052,7 @@ matchExpectedConTy (PE { pe_orig = orig }) data_tc exp_pat_ty
| Just (fam_tc, fam_args, co_tc) <- tyConFamInstSig_maybe data_tc
-- Comments refer to Note [Matching constructor patterns]
-- co_tc :: forall a. T [a] ~ T7 a
- = do { pat_ty <- expTypeToType exp_pat_ty
+ = do { pat_ty <- expTypeToType (scaledThing exp_pat_ty)
; (wrap, pat_rho) <- topInstantiate orig pat_ty
; (subst, tvs') <- newMetaTyVars (tyConTyVars data_tc)
@@ -1038,7 +1079,7 @@ matchExpectedConTy (PE { pe_orig = orig }) data_tc exp_pat_ty
; return ( mkWpCastR full_co <.> wrap, tys') }
| otherwise
- = do { pat_ty <- expTypeToType exp_pat_ty
+ = do { pat_ty <- expTypeToType (scaledThing exp_pat_ty)
; (wrap, pat_rho) <- topInstantiate orig pat_ty
; (coi, tys) <- matchExpectedTyConApp data_tc pat_rho
; return (mkWpCastN (mkTcSymCo coi) <.> wrap, tys) }
@@ -1072,7 +1113,7 @@ Suppose (coi, tys) = matchExpectedConType data_tc pat_ty
error messages; it's a purely internal thing
-}
-tcConArgs :: ConLike -> [TcSigmaType]
+tcConArgs :: ConLike -> [Scaled TcSigmaType]
-> Checker (HsConPatDetails GhcRn) (HsConPatDetails GhcTc)
tcConArgs con_like arg_tys penv con_args thing_inside = case con_args of
@@ -1114,7 +1155,7 @@ tcConArgs con_like arg_tys penv con_args thing_inside = case con_args of
pun), res) }
- find_field_ty :: Name -> FieldLabelString -> TcM TcType
+ find_field_ty :: Name -> FieldLabelString -> TcM (Scaled TcType)
find_field_ty sel lbl
= case [ty | (fl, ty) <- field_tys, flSelector fl == sel ] of
@@ -1131,14 +1172,15 @@ tcConArgs con_like arg_tys penv con_args thing_inside = case con_args of
traceTc "find_field" (ppr pat_ty <+> ppr extras)
ASSERT( null extras ) (return pat_ty)
- field_tys :: [(FieldLabel, TcType)]
+ field_tys :: [(FieldLabel, Scaled TcType)]
field_tys = zip (conLikeFieldLabels con_like) arg_tys
-- Don't use zipEqual! If the constructor isn't really a record, then
-- dataConFieldLabels will be empty (and each field in the pattern
-- will generate an error below).
-tcConArg :: Checker (LPat GhcRn, TcSigmaType) (LPat GhcTc)
-tcConArg penv (arg_pat, arg_ty) = tc_lpat (mkCheckExpType arg_ty) penv arg_pat
+tcConArg :: Checker (LPat GhcRn, Scaled TcSigmaType) (LPat GhcTc)
+tcConArg penv (arg_pat, Scaled arg_mult arg_ty)
+ = tc_lpat (Scaled arg_mult (mkCheckExpType arg_ty)) penv arg_pat
addDataConStupidTheta :: DataCon -> [TcType] -> TcM ()
-- Instantiate the "stupid theta" of the data con, and throw
diff --git a/compiler/GHC/Tc/Gen/Rule.hs b/compiler/GHC/Tc/Gen/Rule.hs
index 7475b2e737..49de48cebd 100644
--- a/compiler/GHC/Tc/Gen/Rule.hs
+++ b/compiler/GHC/Tc/Gen/Rule.hs
@@ -28,6 +28,7 @@ import GHC.Tc.Utils.Unify( buildImplicationFor )
import GHC.Tc.Types.Evidence( mkTcCoVarCo )
import GHC.Core.Type
import GHC.Core.TyCon( isTypeFamilyTyCon )
+import GHC.Core.Multiplicity
import GHC.Types.Id
import GHC.Types.Var( EvVar )
import GHC.Types.Var.Set
@@ -221,7 +222,7 @@ tcRuleTmBndrs [] = return ([],[])
tcRuleTmBndrs (L _ (RuleBndr _ (L _ name)) : rule_bndrs)
= do { ty <- newOpenFlexiTyVarTy
; (tyvars, tmvars) <- tcRuleTmBndrs rule_bndrs
- ; return (tyvars, mkLocalId name ty : tmvars) }
+ ; return (tyvars, mkLocalId name Many ty : tmvars) }
tcRuleTmBndrs (L _ (RuleBndrSig _ (L _ name) rn_ty) : rule_bndrs)
-- e.g x :: a->a
-- The tyvar 'a' is brought into scope first, just as if you'd written
@@ -230,7 +231,7 @@ tcRuleTmBndrs (L _ (RuleBndrSig _ (L _ name) rn_ty) : rule_bndrs)
-- error for each out-of-scope type variable used
= do { let ctxt = RuleSigCtxt name
; (_ , tvs, id_ty) <- tcHsPatSigType ctxt rn_ty
- ; let id = mkLocalId name id_ty
+ ; let id = mkLocalId name Many id_ty
-- See Note [Typechecking pattern signature binders] in GHC.Tc.Gen.HsType
-- The type variables scope over subsequent bindings; yuk
diff --git a/compiler/GHC/Tc/Gen/Sig.hs b/compiler/GHC/Tc/Gen/Sig.hs
index df0c7d37f6..89fcff3079 100644
--- a/compiler/GHC/Tc/Gen/Sig.hs
+++ b/compiler/GHC/Tc/Gen/Sig.hs
@@ -40,6 +40,7 @@ import GHC.Tc.Utils.Instantiate( topInstantiate )
import GHC.Tc.Utils.Env( tcLookupId )
import GHC.Tc.Types.Evidence( HsWrapper, (<.>) )
import GHC.Core.Type ( mkTyVarBinders )
+import GHC.Core.Multiplicity
import GHC.Driver.Session
import GHC.Types.Var ( TyVar, Specificity(..), tyVarKind, binderVars )
@@ -224,7 +225,12 @@ tcUserTypeSig loc hs_sig_ty mb_name
= do { sigma_ty <- tcHsSigWcType ctxt_F hs_sig_ty
; traceTc "tcuser" (ppr sigma_ty)
; return $
- CompleteSig { sig_bndr = mkLocalId name sigma_ty
+ CompleteSig { sig_bndr = mkLocalId name Many sigma_ty
+ -- We use `Many' as the multiplicity here,
+ -- as if this identifier corresponds to
+ -- anything, it is a top-level
+ -- definition. Which are all unrestricted in
+ -- the current implementation.
, sig_ctxt = ctxt_T
, sig_loc = loc } }
-- Location of the <type> in f :: <type>
@@ -266,7 +272,7 @@ no_anon_wc lty = go lty
HsWildCardTy _ -> False
HsAppTy _ ty1 ty2 -> go ty1 && go ty2
HsAppKindTy _ ty ki -> go ty && go ki
- HsFunTy _ ty1 ty2 -> go ty1 && go ty2
+ HsFunTy _ w ty1 ty2 -> go ty1 && go ty2 && go (arrowToHsType w)
HsListTy _ ty -> go ty
HsTupleTy _ _ tys -> gos tys
HsSumTy _ tys -> gos tys
@@ -436,7 +442,7 @@ tcPatSynSig name sig_ty
-- arguments become the types of binders. We thus cannot allow
-- levity polymorphism here
; let (arg_tys, _) = tcSplitFunTys body_ty'
- ; mapM_ (checkForLevPoly empty) arg_tys
+ ; mapM_ (checkForLevPoly empty . scaledThing) arg_tys
; traceTc "tcTySig }" $
vcat [ text "implicit_tvs" <+> ppr_tvs implicit_tvs'
diff --git a/compiler/GHC/Tc/Gen/Splice.hs b/compiler/GHC/Tc/Gen/Splice.hs
index 140299997a..5d0db81183 100644
--- a/compiler/GHC/Tc/Gen/Splice.hs
+++ b/compiler/GHC/Tc/Gen/Splice.hs
@@ -44,6 +44,7 @@ import GHC.Driver.Finder
import GHC.Types.Name
import GHC.Tc.Utils.Monad
import GHC.Tc.Utils.TcType
+import GHC.Core.Multiplicity
import GHC.Utils.Outputable
import GHC.Tc.Gen.Expr
@@ -238,7 +239,7 @@ tcUntypedBracket rn_expr brack ps res_ty
-- | A type variable with kind * -> * named "m"
mkMetaTyVar :: TcM TyVar
mkMetaTyVar =
- newNamedFlexiTyVar (fsLit "m") (mkVisFunTy liftedTypeKind liftedTypeKind)
+ newNamedFlexiTyVar (fsLit "m") (mkVisFunTyMany liftedTypeKind liftedTypeKind)
-- | For a type 'm', emit the constraint 'Quote m'.
@@ -1757,7 +1758,7 @@ reifyDataCon isGadtDataCon tys dc
filterOut (`elemVarSet` eq_spec_tvs) g_univ_tvs
; let (tvb_subst, g_user_tvs) = subst_tv_binders univ_subst g_user_tvs'
g_theta = substTys tvb_subst g_theta'
- g_arg_tys = substTys tvb_subst g_arg_tys'
+ g_arg_tys = substTys tvb_subst (map scaledThing g_arg_tys')
g_res_ty = substTy tvb_subst g_res_ty'
; r_arg_tys <- reifyTypes (if isGadtDataCon then g_arg_tys else arg_tys)
@@ -2115,9 +2116,14 @@ reifyType ty@(AppTy {}) = do
filter_out_invisible_args ty_head ty_args =
filterByList (map isVisibleArgFlag $ appTyArgFlags ty_head ty_args)
ty_args
-reifyType ty@(FunTy { ft_af = af, ft_arg = t1, ft_res = t2 })
+reifyType ty@(FunTy { ft_af = af, ft_mult = Many, ft_arg = t1, ft_res = t2 })
| InvisArg <- af = reify_for_all Inferred ty -- Types like ((?x::Int) => Char -> Char)
- | otherwise = do { [r1,r2] <- reifyTypes [t1,t2] ; return (TH.ArrowT `TH.AppT` r1 `TH.AppT` r2) }
+ | otherwise = do { [r1,r2] <- reifyTypes [t1,t2]
+ ; return (TH.ArrowT `TH.AppT` r1 `TH.AppT` r2) }
+reifyType ty@(FunTy { ft_af = af, ft_mult = tm, ft_arg = t1, ft_res = t2 })
+ | InvisArg <- af = noTH (sLit "linear invisible argument") (ppr ty)
+ | otherwise = do { [rm,r1,r2] <- reifyTypes [tm,t1,t2]
+ ; return (TH.MulArrowT `TH.AppT` rm `TH.AppT` r1 `TH.AppT` r2) }
reifyType (CastTy t _) = reifyType t -- Casts are ignored in TH
reifyType ty@(CoercionTy {})= noTH (sLit "coercions in types") (ppr ty)
@@ -2145,7 +2151,7 @@ reifyTypes :: [Type] -> TcM [TH.Type]
reifyTypes = mapM reifyType
reifyPatSynType
- :: ([InvisTVBinder], ThetaType, [InvisTVBinder], ThetaType, [Type], Type) -> TcM TH.Type
+ :: ([InvisTVBinder], ThetaType, [InvisTVBinder], ThetaType, [Scaled Type], Type) -> TcM TH.Type
-- reifies a pattern synonym's type and returns its *complete* type
-- signature; see NOTE [Pattern synonym signatures and Template
-- Haskell]
@@ -2213,7 +2219,7 @@ reify_tc_app tc tys
else TH.TupleT arity
| tc `hasKey` constraintKindTyConKey
= TH.ConstraintT
- | tc `hasKey` funTyConKey = TH.ArrowT
+ | tc `hasKey` unrestrictedFunTyConKey = TH.ArrowT
| tc `hasKey` listTyConKey = TH.ListT
| tc `hasKey` nilDataConKey = TH.PromotedNilT
| tc `hasKey` consDataConKey = TH.PromotedConsT
diff --git a/compiler/GHC/Tc/Instance/Class.hs b/compiler/GHC/Tc/Instance/Class.hs
index aec5c85e20..642e303442 100644
--- a/compiler/GHC/Tc/Instance/Class.hs
+++ b/compiler/GHC/Tc/Instance/Class.hs
@@ -32,6 +32,7 @@ import GHC.Builtin.Names
import GHC.Types.Id
import GHC.Core.Type
+import GHC.Core.Multiplicity
import GHC.Core.Make ( mkStringExprFS, mkNaturalExpr )
import GHC.Types.Name ( Name, pprDefinedAt )
@@ -430,15 +431,15 @@ matchTypeable clas [k,t] -- clas = Typeable
matchTypeable _ _ = return NoInstance
-- | Representation for a type @ty@ of the form @arg -> ret@.
-doFunTy :: Class -> Type -> Type -> Type -> TcM ClsInstResult
-doFunTy clas ty arg_ty ret_ty
+doFunTy :: Class -> Type -> Scaled Type -> Type -> TcM ClsInstResult
+doFunTy clas ty (Scaled mult arg_ty) ret_ty
= return $ OneInst { cir_new_theta = preds
, cir_mk_ev = mk_ev
, cir_what = BuiltinInstance }
where
- preds = map (mk_typeable_pred clas) [arg_ty, ret_ty]
- mk_ev [arg_ev, ret_ev] = evTypeable ty $
- EvTypeableTrFun (EvExpr arg_ev) (EvExpr ret_ev)
+ preds = map (mk_typeable_pred clas) [mult, arg_ty, ret_ty]
+ mk_ev [mult_ev, arg_ev, ret_ev] = evTypeable ty $
+ EvTypeableTrFun (EvExpr mult_ev) (EvExpr arg_ev) (EvExpr ret_ev)
mk_ev _ = panic "GHC.Tc.Solver.Interact.doFunTy"
@@ -685,7 +686,7 @@ matchHasField dflags short_cut clas tys
-- the HasField x r a dictionary. The preds will
-- typically be empty, but if the datatype has a
-- "stupid theta" then we have to include it here.
- ; let theta = mkPrimEqPred sel_ty (mkVisFunTy r_ty a_ty) : preds
+ ; let theta = mkPrimEqPred sel_ty (mkVisFunTyMany r_ty a_ty) : preds
-- Use the equality proof to cast the selector Id to
-- type (r -> a), then use the newtype coercion to cast
diff --git a/compiler/GHC/Tc/Instance/Typeable.hs b/compiler/GHC/Tc/Instance/Typeable.hs
index 3f8b7d8281..a7b3d83e09 100644
--- a/compiler/GHC/Tc/Instance/Typeable.hs
+++ b/compiler/GHC/Tc/Instance/Typeable.hs
@@ -34,6 +34,7 @@ import GHC.Types.Id
import GHC.Core.Type
import GHC.Core.TyCon
import GHC.Core.DataCon
+import GHC.Core.Multiplicity
import GHC.Unit.Module
import GHC.Hs
import GHC.Driver.Session
@@ -437,7 +438,9 @@ kindIsTypeable ty
| isLiftedTypeKind ty = True
kindIsTypeable (TyVarTy _) = True
kindIsTypeable (AppTy a b) = kindIsTypeable a && kindIsTypeable b
-kindIsTypeable (FunTy _ a b) = kindIsTypeable a && kindIsTypeable b
+kindIsTypeable (FunTy _ w a b) = kindIsTypeable w &&
+ kindIsTypeable a &&
+ kindIsTypeable b
kindIsTypeable (TyConApp tc args) = tyConIsTypeable tc
&& all kindIsTypeable args
kindIsTypeable (ForAllTy{}) = False
@@ -466,8 +469,8 @@ liftTc = KindRepM . lift
builtInKindReps :: [(Kind, Name)]
builtInKindReps =
[ (star, starKindRepName)
- , (mkVisFunTy star star, starArrStarKindRepName)
- , (mkVisFunTys [star, star] star, starArrStarArrStarKindRepName)
+ , (mkVisFunTyMany star star, starArrStarKindRepName)
+ , (mkVisFunTysMany [star, star] star, starArrStarArrStarKindRepName)
]
where
star = liftedTypeKind
@@ -537,7 +540,7 @@ getKindRep stuff@(Stuff {..}) in_scope = go
= do -- Place a NOINLINE pragma on KindReps since they tend to be quite
-- large and bloat interface files.
rep_bndr <- (`setInlinePragma` neverInlinePragma)
- <$> newSysLocalId (fsLit "$krep") (mkTyConTy kindRepTyCon)
+ <$> newSysLocalId (fsLit "$krep") Many (mkTyConTy kindRepTyCon)
-- do we need to tie a knot here?
flip runStateT env $ unKindRepM $ do
@@ -591,7 +594,7 @@ mkKindRepRhs stuff@(Stuff {..}) in_scope = new_kind_rep
new_kind_rep (ForAllTy (Bndr var _) ty)
= pprPanic "mkTyConKindRepBinds(ForAllTy)" (ppr var $$ ppr ty)
- new_kind_rep (FunTy _ t1 t2)
+ new_kind_rep (FunTy _ _ t1 t2)
= do rep1 <- getKindRep stuff in_scope t1
rep2 <- getKindRep stuff in_scope t2
return $ nlHsDataCon kindRepFunDataCon
diff --git a/compiler/GHC/Tc/Module.hs b/compiler/GHC/Tc/Module.hs
index f6e5b87f53..5ef192befe 100644
--- a/compiler/GHC/Tc/Module.hs
+++ b/compiler/GHC/Tc/Module.hs
@@ -1274,7 +1274,7 @@ checkBootTyCon is_boot tc1 tc2
check (map flSelector (dataConFieldLabels c1) == map flSelector (dataConFieldLabels c2))
(text "The record label lists for" <+> pname1 <+>
text "differ") `andThenCheck`
- check (eqType (dataConUserType c1) (dataConUserType c2))
+ check (eqType (dataConWrapperType c1) (dataConWrapperType c2))
(text "The types for" <+> pname1 <+> text "differ")
where
name1 = dataConName c1
@@ -2446,7 +2446,7 @@ getGhciStepIO = do
{ hst_tele = mkHsForAllInvisTele
[noLoc $ UserTyVar noExtField SpecifiedSpec (noLoc a_tv)]
, hst_xforall = noExtField
- , hst_body = nlHsFunTy ghciM ioM }
+ , hst_body = nlHsFunTy HsUnrestrictedArrow ghciM ioM }
stepTy :: LHsSigWcType GhcRn
stepTy = mkEmptyWildCardBndrs (mkEmptyImplicitBndrs step_ty)
@@ -2965,7 +2965,8 @@ ppr_datacons debug type_env
= ppr_things "DATA CONSTRUCTORS" ppr_dc wanted_dcs
-- The filter gets rid of class data constructors
where
- ppr_dc dc = ppr dc <+> dcolon <+> ppr (dataConUserType dc)
+ ppr_dc dc = sdocWithDynFlags (\dflags ->
+ ppr dc <+> dcolon <+> ppr (dataConDisplayType dflags dc))
all_dcs = typeEnvDataCons type_env
wanted_dcs | debug = all_dcs
| otherwise = filterOut is_cls_dc all_dcs
diff --git a/compiler/GHC/Tc/Solver.hs b/compiler/GHC/Tc/Solver.hs
index 61477af714..8754ef9fd0 100644
--- a/compiler/GHC/Tc/Solver.hs
+++ b/compiler/GHC/Tc/Solver.hs
@@ -50,7 +50,7 @@ import GHC.Core.Predicate
import GHC.Tc.Types.Origin
import GHC.Tc.Utils.TcType
import GHC.Core.Type
-import GHC.Builtin.Types ( liftedRepTy )
+import GHC.Builtin.Types ( liftedRepTy, manyDataConTy )
import GHC.Core.Unify ( tcMatchTyKi )
import GHC.Utils.Misc
import GHC.Types.Var
@@ -2223,6 +2223,13 @@ defaultTyVarTcS the_tv
= do { traceTcS "defaultTyVarTcS RuntimeRep" (ppr the_tv)
; unifyTyVar the_tv liftedRepTy
; return True }
+ | isMultiplicityVar the_tv
+ , not (isTyVarTyVar the_tv) -- TyVarTvs should only be unified with a tyvar
+ -- never with a type; c.f. TcMType.defaultTyVar
+ -- See Note [Kind generalisation and SigTvs]
+ = do { traceTcS "defaultTyVarTcS Multiplicity" (ppr the_tv)
+ ; unifyTyVar the_tv manyDataConTy
+ ; return True }
| otherwise
= return False -- the common case
diff --git a/compiler/GHC/Tc/Solver/Canonical.hs b/compiler/GHC/Tc/Solver/Canonical.hs
index 2fc8664450..79b42d29d5 100644
--- a/compiler/GHC/Tc/Solver/Canonical.hs
+++ b/compiler/GHC/Tc/Solver/Canonical.hs
@@ -25,6 +25,7 @@ import GHC.Tc.Types.Evidence
import GHC.Tc.Types.EvTerm
import GHC.Core.Class
import GHC.Core.TyCon
+import GHC.Core.Multiplicity
import GHC.Core.TyCo.Rep -- cleverly decomposes types, good for completeness checking
import GHC.Core.Coercion
import GHC.Core
@@ -551,7 +552,7 @@ mk_strict_superclasses rec_clss (CtGiven { ctev_evar = evar, ctev_loc = loc })
(sc_theta, sc_inner_pred) = splitFunTys sc_rho
all_tvs = tvs `chkAppend` sc_tvs
- all_theta = theta `chkAppend` sc_theta
+ all_theta = theta `chkAppend` (map scaledThing sc_theta)
swizzled_pred = mkInfSigmaTy all_tvs all_theta sc_inner_pred
-- evar :: forall tvs. theta => cls tys
@@ -1007,16 +1008,16 @@ can_eq_nc' _flat _rdr_env _envs ev eq_rel ty1@(LitTy l1) _ (LitTy l2) _
-- Decompose FunTy: (s -> t) and (c => t)
-- NB: don't decompose (Int -> blah) ~ (Show a => blah)
can_eq_nc' _flat _rdr_env _envs ev eq_rel
- (FunTy { ft_af = af1, ft_arg = ty1a, ft_res = ty1b }) _
- (FunTy { ft_af = af2, ft_arg = ty2a, ft_res = ty2b }) _
+ (FunTy { ft_mult = am1, ft_af = af1, ft_arg = ty1a, ft_res = ty1b }) _
+ (FunTy { ft_mult = am2, ft_af = af2, ft_arg = ty2a, ft_res = ty2b }) _
| af1 == af2 -- Don't decompose (Int -> blah) ~ (Show a => blah)
, Just ty1a_rep <- getRuntimeRep_maybe ty1a -- getRutimeRep_maybe:
, Just ty1b_rep <- getRuntimeRep_maybe ty1b -- see Note [Decomposing FunTy]
, Just ty2a_rep <- getRuntimeRep_maybe ty2a
, Just ty2b_rep <- getRuntimeRep_maybe ty2b
= canDecomposableTyConAppOK ev eq_rel funTyCon
- [ty1a_rep, ty1b_rep, ty1a, ty1b]
- [ty2a_rep, ty2b_rep, ty2a, ty2b]
+ [am1, ty1a_rep, ty1b_rep, ty1a, ty1b]
+ [am2, ty2a_rep, ty2b_rep, ty2a, ty2b]
-- Decompose type constructor applications
-- NB: e have expanded type synonyms already
@@ -1177,11 +1178,12 @@ zonk_eq_types = go
-- RuntimeReps of the argument and result types. This can be observed in
-- testcase tc269.
go ty1 ty2
- | Just (arg1, res1) <- split1
- , Just (arg2, res2) <- split2
+ | Just (Scaled w1 arg1, res1) <- split1
+ , Just (Scaled w2 arg2, res2) <- split2
+ , eqType w1 w2
= do { res_a <- go arg1 arg2
; res_b <- go res1 res2
- ; return $ combine_rev mkVisFunTy res_b res_a
+ ; return $ combine_rev (mkVisFunTy w1) res_b res_a
}
| isJust split1 || isJust split2
= bale_out ty1 ty2
@@ -2469,10 +2471,11 @@ unifyWanted loc role orig_ty1 orig_ty2
go ty1 ty2 | Just ty1' <- tcView ty1 = go ty1' ty2
go ty1 ty2 | Just ty2' <- tcView ty2 = go ty1 ty2'
- go (FunTy _ s1 t1) (FunTy _ s2 t2)
+ go (FunTy _ w1 s1 t1) (FunTy _ w2 s2 t2)
= do { co_s <- unifyWanted loc role s1 s2
; co_t <- unifyWanted loc role t1 t2
- ; return (mkFunCo role co_s co_t) }
+ ; co_w <- unifyWanted loc Nominal w1 w2
+ ; return (mkFunCo role co_w co_s co_t) }
go (TyConApp tc1 tys1) (TyConApp tc2 tys2)
| tc1 == tc2, tys1 `equalLength` tys2
, isInjectiveTyCon tc1 role -- don't look under newtypes at Rep equality
@@ -2520,9 +2523,10 @@ unify_derived loc role orig_ty1 orig_ty2
go ty1 ty2 | Just ty1' <- tcView ty1 = go ty1' ty2
go ty1 ty2 | Just ty2' <- tcView ty2 = go ty1 ty2'
- go (FunTy _ s1 t1) (FunTy _ s2 t2)
+ go (FunTy _ w1 s1 t1) (FunTy _ w2 s2 t2)
= do { unify_derived loc role s1 s2
- ; unify_derived loc role t1 t2 }
+ ; unify_derived loc role t1 t2
+ ; unify_derived loc role w1 w2 }
go (TyConApp tc1 tys1) (TyConApp tc2 tys2)
| tc1 == tc2, tys1 `equalLength` tys2
, isInjectiveTyCon tc1 role
diff --git a/compiler/GHC/Tc/Solver/Flatten.hs b/compiler/GHC/Tc/Solver/Flatten.hs
index 6916357691..48249caa5c 100644
--- a/compiler/GHC/Tc/Solver/Flatten.hs
+++ b/compiler/GHC/Tc/Solver/Flatten.hs
@@ -39,6 +39,8 @@ import Data.Foldable ( foldrM )
import Control.Arrow ( first )
+import GHC.Core.Multiplicity
+
{-
Note [The flattening story]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1175,12 +1177,13 @@ flatten_one (TyConApp tc tys)
-- _ -> fmode
= flatten_ty_con_app tc tys
-flatten_one ty@(FunTy { ft_arg = ty1, ft_res = ty2 })
+flatten_one ty@(FunTy { ft_mult = mult, ft_arg = ty1, ft_res = ty2 })
= do { (xi1,co1) <- flatten_one ty1
; (xi2,co2) <- flatten_one ty2
+ ; (xi3,co3) <- flatten_one mult
; role <- getRole
- ; return (ty { ft_arg = xi1, ft_res = xi2 }
- , mkFunCo role co1 co2) }
+ ; return (ty { ft_mult = xi3, ft_arg = xi1, ft_res = xi2 }
+ , mkFunCo role co3 co1 co2) }
flatten_one ty@(ForAllTy {})
-- TODO (RAE): This is inadequate, as it doesn't flatten the kind of
@@ -1921,9 +1924,9 @@ split_pi_tys' ty = split ty ty
split orig_ty ty | Just ty' <- coreView ty = split orig_ty ty'
split _ (ForAllTy b res) = let (bs, ty, _) = split res res
in (Named b : bs, ty, True)
- split _ (FunTy { ft_af = af, ft_arg = arg, ft_res = res })
+ split _ (FunTy { ft_af = af, ft_mult = w, ft_arg = arg, ft_res = res })
= let (bs, ty, named) = split res res
- in (Anon af arg : bs, ty, named)
+ in (Anon af (mkScaled w arg) : bs, ty, named)
split orig_ty _ = ([], orig_ty, False)
{-# INLINE split_pi_tys' #-}
@@ -1935,6 +1938,6 @@ ty_con_binders_ty_binders' = foldr go ([], False)
go (Bndr tv (NamedTCB vis)) (bndrs, _)
= (Named (Bndr tv vis) : bndrs, True)
go (Bndr tv (AnonTCB af)) (bndrs, n)
- = (Anon af (tyVarKind tv) : bndrs, n)
+ = (Anon af (unrestricted (tyVarKind tv)) : bndrs, n)
{-# INLINE go #-}
{-# INLINE ty_con_binders_ty_binders' #-}
diff --git a/compiler/GHC/Tc/TyCl.hs b/compiler/GHC/Tc/TyCl.hs
index 6af35c77c2..a4a56c0a14 100644
--- a/compiler/GHC/Tc/TyCl.hs
+++ b/compiler/GHC/Tc/TyCl.hs
@@ -44,6 +44,7 @@ import GHC.Tc.Instance.Class( AssocInstInfo(..) )
import GHC.Tc.Utils.TcMType
import GHC.Builtin.Types ( unitTy, makeRecoveryTyCon )
import GHC.Tc.Utils.TcType
+import GHC.Core.Multiplicity
import GHC.Rename.Env( lookupConstructorFields )
import GHC.Tc.Instance.Family
import GHC.Core.FamInstEnv
@@ -823,9 +824,9 @@ swizzleTcTyConBndrs tc_infos
swizzle_var :: Var -> Var
swizzle_var v
| Just nm <- lookupVarEnv swizzle_env v
- = updateVarType swizzle_ty (v `setVarName` nm)
+ = updateVarTypeAndMult swizzle_ty (v `setVarName` nm)
| otherwise
- = updateVarType swizzle_ty v
+ = updateVarTypeAndMult swizzle_ty v
(map_type, _, _, _) = mapTyCo swizzleMapper
swizzle_ty ty = runIdentity (map_type ty)
@@ -1561,10 +1562,10 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc
-- This includes doing kind unification if the type is a newtype.
-- See Note [Implementation of UnliftedNewtypes] for why we need
-- the first two arguments.
-kcConArgTys :: NewOrData -> Kind -> [LHsType GhcRn] -> TcM ()
+kcConArgTys :: NewOrData -> Kind -> [HsScaled GhcRn (LHsType GhcRn)] -> TcM ()
kcConArgTys new_or_data res_kind arg_tys = do
{ let exp_kind = getArgExpKind new_or_data res_kind
- ; mapM_ (flip tcCheckLHsType exp_kind . getBangType) arg_tys
+ ; mapM_ (flip tcCheckLHsType exp_kind . getBangType . hsScaledThing) arg_tys
-- See Note [Implementation of UnliftedNewtypes], STEP 2
}
@@ -3134,7 +3135,7 @@ tcConDecl rep_tycon tag_map tmpl_bndrs res_kind res_tmpl new_or_data
; (ze, qkvs) <- zonkTyBndrs kvs
; (ze, user_qtvbndrs) <- zonkTyVarBindersX ze exp_tvbndrs
; let user_qtvs = binderVars user_qtvbndrs
- ; arg_tys <- zonkTcTypesToTypesX ze arg_tys
+ ; arg_tys <- zonkScaledTcTypesToTypesX ze arg_tys
; ctxt <- zonkTcTypesToTypesX ze ctxt
; fam_envs <- tcGetFamInstEnvs
@@ -3216,7 +3217,7 @@ tcConDecl rep_tycon tag_map tmpl_bndrs _res_kind res_tmpl new_or_data
-- Zonk to Types
; (ze, tvbndrs) <- zonkTyVarBinders tvbndrs
- ; arg_tys <- zonkTcTypesToTypesX ze arg_tys
+ ; arg_tys <- zonkScaledTcTypesToTypesX ze arg_tys
; ctxt <- zonkTcTypesToTypesX ze ctxt
; res_ty <- zonkTcTypeToTypeX ze res_ty
@@ -3225,7 +3226,7 @@ tcConDecl rep_tycon tag_map tmpl_bndrs _res_kind res_tmpl new_or_data
-- See Note [Checking GADT return types]
ctxt' = substTys arg_subst ctxt
- arg_tys' = substTys arg_subst arg_tys
+ arg_tys' = substScaledTys arg_subst arg_tys
res_ty' = substTy arg_subst res_ty
@@ -3262,7 +3263,7 @@ getArgExpKind NewType res_ki = TheKind res_ki
getArgExpKind DataType _ = OpenKind
tcConIsInfixH98 :: Name
- -> HsConDetails (LHsType GhcRn) (Located [LConDeclField GhcRn])
+ -> HsConDetails a b
-> TcM Bool
tcConIsInfixH98 _ details
= case details of
@@ -3270,7 +3271,7 @@ tcConIsInfixH98 _ details
_ -> return False
tcConIsInfixGADT :: Name
- -> HsConDetails (LHsType GhcRn) (Located [LConDeclField GhcRn])
+ -> HsConDetails (HsScaled GhcRn (LHsType GhcRn)) r
-> TcM Bool
tcConIsInfixGADT con details
= case details of
@@ -3278,7 +3279,7 @@ tcConIsInfixGADT con details
RecCon {} -> return False
PrefixCon arg_tys -- See Note [Infix GADT constructors]
| isSymOcc (getOccName con)
- , [_ty1,_ty2] <- arg_tys
+ , [_ty1,_ty2] <- map hsScaledThing arg_tys
-> do { fix_env <- getFixityEnv
; return (con `elemNameEnv` fix_env) }
| otherwise -> return False
@@ -3287,7 +3288,7 @@ tcConArgs :: ContextKind -- expected kind of arguments
-- always OpenKind for datatypes, but unlifted newtypes
-- might have a specific kind
-> HsConDeclDetails GhcRn
- -> TcM [(TcType, HsSrcBang)]
+ -> TcM [(Scaled TcType, HsSrcBang)]
tcConArgs exp_kind (PrefixCon btys)
= mapM (tcConArg exp_kind) btys
tcConArgs exp_kind (InfixCon bty1 bty2)
@@ -3298,7 +3299,7 @@ tcConArgs exp_kind (RecCon fields)
= mapM (tcConArg exp_kind) btys
where
-- We need a one-to-one mapping from field_names to btys
- combined = map (\(L _ f) -> (cd_fld_names f,cd_fld_type f))
+ combined = map (\(L _ f) -> (cd_fld_names f,hsLinear (cd_fld_type f)))
(unLoc fields)
explode (ns,ty) = zip ns (repeat ty)
exploded = concatMap explode combined
@@ -3307,12 +3308,13 @@ tcConArgs exp_kind (RecCon fields)
tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatypes,
-- but might be an unlifted type with UnliftedNewtypes
- -> LHsType GhcRn -> TcM (TcType, HsSrcBang)
-tcConArg exp_kind bty
+ -> HsScaled GhcRn (LHsType GhcRn) -> TcM (Scaled TcType, HsSrcBang)
+tcConArg exp_kind (HsScaled w bty)
= do { traceTc "tcConArg 1" (ppr bty)
; arg_ty <- tcCheckLHsType (getBangType bty) exp_kind
+ ; w' <- tcMult w
; traceTc "tcConArg 2" (ppr bty)
- ; return (arg_ty, getBangStrictness bty) }
+ ; return (Scaled w' arg_ty, getBangStrictness bty) }
{-
Note [Infix GADT constructors]
@@ -3925,10 +3927,10 @@ checkValidDataCon dflags existential_ok tc con
; checkTc (isJust (tcMatchTy res_ty_tmpl orig_res_ty))
(badDataConTyCon con res_ty_tmpl)
-- Note that checkTc aborts if it finds an error. This is
- -- critical to avoid panicking when we call dataConUserType
+ -- critical to avoid panicking when we call dataConDisplayType
-- on an un-rejiggable datacon!
- ; traceTc "checkValidDataCon 2" (ppr (dataConUserType con))
+ ; traceTc "checkValidDataCon 2" (ppr data_con_display_type)
-- Check that the result type is a *monotype*
-- e.g. reject this: MkT :: T (forall a. a->a)
@@ -3940,7 +3942,7 @@ checkValidDataCon dflags existential_ok tc con
-- later check in checkNewDataCon handles this, producing a
-- better error message than checkForLevPoly would.
; unless (isNewTyCon tc)
- (mapM_ (checkForLevPoly empty) (dataConOrigArgTys con))
+ (mapM_ (checkForLevPoly empty) (map scaledThing $ dataConOrigArgTys con))
-- Extra checks for newtype data constructors. Importantly, these
-- checks /must/ come before the call to checkValidType below. This
@@ -3950,7 +3952,7 @@ checkValidDataCon dflags existential_ok tc con
; when (isNewTyCon tc) (checkNewDataCon con)
-- Check all argument types for validity
- ; checkValidType ctxt (dataConUserType con)
+ ; checkValidType ctxt data_con_display_type
-- Check that existentials are allowed if they are used
; checkTc (existential_ok || isVanillaDataCon con)
@@ -3980,8 +3982,9 @@ checkValidDataCon dflags existential_ok tc con
; traceTc "Done validity of data con" $
vcat [ ppr con
- , text "Datacon user type:" <+> ppr (dataConUserType con)
+ , text "Datacon wrapper type:" <+> ppr (dataConWrapperType con)
, text "Datacon rep type:" <+> ppr (dataConRepType con)
+ , text "Datacon display type:" <+> ppr data_con_display_type
, text "Rep typcon binders:" <+> ppr (tyConBinders (dataConTyCon con))
, case tyConFamInst_maybe (dataConTyCon con) of
Nothing -> text "not family"
@@ -4023,6 +4026,9 @@ checkValidDataCon dflags existential_ok tc con
bad_bang n herald
= hang herald 2 (text "on the" <+> speakNth n
<+> text "argument of" <+> quotes (ppr con))
+
+ data_con_display_type = dataConDisplayType dflags con
+
-------------------------------
checkNewDataCon :: DataCon -> TcM ()
-- Further checks for the data constructor of a newtype
@@ -4032,11 +4038,18 @@ checkNewDataCon con
; unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes
; let allowedArgType =
- unlifted_newtypes || isLiftedType_maybe arg_ty1 == Just True
+ unlifted_newtypes || isLiftedType_maybe (scaledThing arg_ty1) == Just True
; checkTc allowedArgType $ vcat
[ text "A newtype cannot have an unlifted argument type"
, text "Perhaps you intended to use UnliftedNewtypes"
]
+ ; dflags <- getDynFlags
+
+ ; let check_con what msg =
+ checkTc what (msg $$ ppr con <+> dcolon <+> ppr (dataConDisplayType dflags con))
+
+ ; checkTc (ok_mult (scaledMult arg_ty1)) $
+ text "A newtype constructor must be linear"
; check_con (null eq_spec) $
text "A newtype constructor must have a return type of form T a1 ... an"
@@ -4056,8 +4069,6 @@ checkNewDataCon con
where
(_univ_tvs, ex_tvs, eq_spec, theta, arg_tys, _res_ty)
= dataConFullSig con
- check_con what msg
- = checkTc what (msg $$ ppr con <+> dcolon <+> ppr (dataConUserType con))
(arg_ty1 : _) = arg_tys
@@ -4065,6 +4076,9 @@ checkNewDataCon con
ok_bang (HsSrcBang _ _ SrcLazy) = False
ok_bang _ = True
+ ok_mult One = True
+ ok_mult _ = False
+
-------------------------------
checkValidClass :: Class -> TcM ()
checkValidClass cls
@@ -4511,7 +4525,7 @@ checkValidRoles tc
check_dc_roles datacon
= do { traceTc "check_dc_roles" (ppr datacon <+> ppr (tyConRoles tc))
; mapM_ (check_ty_roles role_env Representational) $
- eqSpecPreds eq_spec ++ theta ++ arg_tys }
+ eqSpecPreds eq_spec ++ theta ++ (map scaledThing arg_tys) }
-- See Note [Role-checking data constructor arguments] in GHC.Tc.TyCl.Utils
where
(univ_tvs, ex_tvs, eq_spec, theta, arg_tys, _res_ty)
@@ -4548,8 +4562,9 @@ checkValidRoles tc
= check_ty_roles env role ty1
>> check_ty_roles env Nominal ty2
- check_ty_roles env role (FunTy _ ty1 ty2)
- = check_ty_roles env role ty1
+ check_ty_roles env role (FunTy _ w ty1 ty2)
+ = check_ty_roles env role w
+ >> check_ty_roles env role ty1
>> check_ty_roles env role ty2
check_ty_roles env role (ForAllTy (Bndr tv _) ty)
@@ -4719,10 +4734,11 @@ badGadtDecl tc_name
badExistential :: DataCon -> SDoc
badExistential con
- = hang (text "Data constructor" <+> quotes (ppr con) <+>
- text "has existential type variables, a context, or a specialised result type")
- 2 (vcat [ ppr con <+> dcolon <+> ppr (dataConUserType con)
- , parens $ text "Enable ExistentialQuantification or GADTs to allow this" ])
+ = sdocWithDynFlags (\dflags ->
+ hang (text "Data constructor" <+> quotes (ppr con) <+>
+ text "has existential type variables, a context, or a specialised result type")
+ 2 (vcat [ ppr con <+> dcolon <+> ppr (dataConDisplayType dflags con)
+ , parens $ text "Enable ExistentialQuantification or GADTs to allow this" ]))
badStupidTheta :: Name -> SDoc
badStupidTheta tc_name
diff --git a/compiler/GHC/Tc/TyCl/Build.hs b/compiler/GHC/Tc/TyCl/Build.hs
index af49e9e28c..5361ff0160 100644
--- a/compiler/GHC/Tc/TyCl/Build.hs
+++ b/compiler/GHC/Tc/TyCl/Build.hs
@@ -36,6 +36,7 @@ import GHC.Core.TyCon
import GHC.Core.Type
import GHC.Types.Id
import GHC.Tc.Utils.TcType
+import GHC.Core.Multiplicity
import GHC.Types.SrcLoc( SrcSpan, noSrcSpan )
import GHC.Driver.Session
@@ -65,7 +66,7 @@ mkNewTyConRhs tycon_name tycon con
roles = tyConRoles tycon
res_kind = tyConResKind tycon
con_arg_ty = case dataConRepArgTys con of
- [arg_ty] -> arg_ty
+ [arg_ty] -> scaledThing arg_ty
tys -> pprPanic "mkNewTyConRhs" (ppr con <+> ppr tys)
rhs_ty = substTyWith (dataConUnivTyVars con)
(mkTyVarTys tvs) con_arg_ty
@@ -110,7 +111,7 @@ buildDataCon :: FamInstEnvs
-> [EqSpec] -- Equality spec
-> KnotTied ThetaType -- Does not include the "stupid theta"
-- or the GADT equalities
- -> [KnotTied Type] -- Arguments
+ -> [KnotTied (Scaled Type)] -- Arguments
-> KnotTied Type -- Result types
-> KnotTied TyCon -- Rep tycon
-> NameEnv ConTag -- Maps the Name of each DataCon to its
@@ -132,7 +133,7 @@ buildDataCon fam_envs src_name declared_infix prom_info src_bangs impl_bangs
; traceIf (text "buildDataCon 1" <+> ppr src_name)
; us <- newUniqueSupply
; dflags <- getDynFlags
- ; let stupid_ctxt = mkDataConStupidTheta rep_tycon arg_tys univ_tvs
+ ; let stupid_ctxt = mkDataConStupidTheta rep_tycon (map scaledThing arg_tys) univ_tvs
tag = lookupNameEnv_NF tag_map src_name
-- See Note [Constructor tag allocation], fixes #14657
data_con = mkDataCon src_name declared_infix prom_info
@@ -184,10 +185,10 @@ buildPatSyn src_name declared_infix matcher@(matcher_id,_) builder
-- compatible with the pattern synonym
ASSERT2((and [ univ_tvs `equalLength` univ_tvs1
, ex_tvs `equalLength` ex_tvs1
- , pat_ty `eqType` substTy subst pat_ty1
+ , pat_ty `eqType` substTy subst (scaledThing pat_ty1)
, prov_theta `eqTypes` substTys subst prov_theta1
, req_theta `eqTypes` substTys subst req_theta1
- , compareArgTys arg_tys (substTys subst arg_tys1)
+ , compareArgTys arg_tys (substTys subst (map scaledThing arg_tys1))
])
, (vcat [ ppr univ_tvs <+> twiddle <+> ppr univ_tvs1
, ppr ex_tvs <+> twiddle <+> ppr ex_tvs1
@@ -202,7 +203,7 @@ buildPatSyn src_name declared_infix matcher@(matcher_id,_) builder
where
((_:_:univ_tvs1), req_theta1, tau) = tcSplitSigmaTy $ idType matcher_id
([pat_ty1, cont_sigma, _], _) = tcSplitFunTys tau
- (ex_tvs1, prov_theta1, cont_tau) = tcSplitSigmaTy cont_sigma
+ (ex_tvs1, prov_theta1, cont_tau) = tcSplitSigmaTy (scaledThing cont_sigma)
(arg_tys1, _) = (tcSplitFunTys cont_tau)
twiddle = char '~'
subst = zipTvSubst (univ_tvs1 ++ ex_tvs1)
@@ -314,7 +315,7 @@ buildClass tycon_name binders roles fds
univ_bndrs
[{- No GADT equalities -}]
[{- No theta -}]
- arg_tys
+ (map unrestricted arg_tys) -- type classes are unrestricted
(mkTyConApp rec_tycon (mkTyVarTys univ_tvs))
rec_tycon
(mkTyConTagMap rec_tycon)
diff --git a/compiler/GHC/Tc/TyCl/Class.hs b/compiler/GHC/Tc/TyCl/Class.hs
index cedd42916b..c6f78ae4e2 100644
--- a/compiler/GHC/Tc/TyCl/Class.hs
+++ b/compiler/GHC/Tc/TyCl/Class.hs
@@ -40,6 +40,7 @@ import GHC.Tc.Gen.HsType
import GHC.Tc.Utils.TcMType
import GHC.Core.Type ( piResultTys )
import GHC.Core.Predicate
+import GHC.Core.Multiplicity
import GHC.Tc.Types.Origin
import GHC.Tc.Utils.TcType
import GHC.Tc.Utils.Monad
@@ -284,7 +285,7 @@ tcDefMeth clas tyvars this_dict binds_in hs_sig_fn prag_fn
ctxt = FunSigCtxt sel_name warn_redundant
- ; let local_dm_id = mkLocalId local_dm_name local_dm_ty
+ ; let local_dm_id = mkLocalId local_dm_name Many local_dm_ty
local_dm_sig = CompleteSig { sig_bndr = local_dm_id
, sig_ctxt = ctxt
, sig_loc = getLoc (hsSigType hs_ty) }
diff --git a/compiler/GHC/Tc/TyCl/Instance.hs b/compiler/GHC/Tc/TyCl/Instance.hs
index 4c43d91f3e..68bf24c342 100644
--- a/compiler/GHC/Tc/TyCl/Instance.hs
+++ b/compiler/GHC/Tc/TyCl/Instance.hs
@@ -41,6 +41,7 @@ import GHC.Tc.Types.Origin
import GHC.Tc.TyCl.Build
import GHC.Tc.Utils.Instantiate
import GHC.Tc.Instance.Class( AssocInstInfo(..), isNotAssociated )
+import GHC.Core.Multiplicity
import GHC.Core.InstEnv
import GHC.Tc.Instance.Family
import GHC.Core.FamInstEnv
@@ -1318,7 +1319,7 @@ tcSuperClasses dfun_id cls tyvars dfun_evs inst_tys dfun_ev_binds sc_theta
; addTcEvBind ev_binds_var $ mkWantedEvBind sc_ev_id sc_ev_tm
; let sc_top_ty = mkInfForAllTys tyvars $
mkPhiTy (map idType dfun_evs) sc_pred
- sc_top_id = mkLocalId sc_top_name sc_top_ty
+ sc_top_id = mkLocalId sc_top_name Many sc_top_ty
export = ABE { abe_ext = noExtField
, abe_wrap = idHsWrapper
, abe_poly = sc_top_id
@@ -1798,7 +1799,7 @@ tcMethodBodyHelp hs_sig_fn sel_id local_meth_id meth_bind
; let ctxt = FunSigCtxt sel_name True
-- True <=> check for redundant constraints in the
-- user-specified instance signature
- inner_meth_id = mkLocalId inner_meth_name sig_ty
+ inner_meth_id = mkLocalId inner_meth_name Many sig_ty
inner_meth_sig = CompleteSig { sig_bndr = inner_meth_id
, sig_ctxt = ctxt
, sig_loc = getLoc (hsSigType hs_sig_ty) }
@@ -1849,8 +1850,8 @@ mkMethIds clas tyvars dfun_ev_vars inst_tys sel_id
; local_meth_name <- newName sel_occ
-- Base the local_meth_name on the selector name, because
-- type errors from tcMethodBody come from here
- ; let poly_meth_id = mkLocalId poly_meth_name poly_meth_ty
- local_meth_id = mkLocalId local_meth_name local_meth_ty
+ ; let poly_meth_id = mkLocalId poly_meth_name Many poly_meth_ty
+ local_meth_id = mkLocalId local_meth_name Many local_meth_ty
; return (poly_meth_id, local_meth_id) }
where
diff --git a/compiler/GHC/Tc/TyCl/PatSyn.hs b/compiler/GHC/Tc/TyCl/PatSyn.hs
index 57dd16c8f8..5f99763fdd 100644
--- a/compiler/GHC/Tc/TyCl/PatSyn.hs
+++ b/compiler/GHC/Tc/TyCl/PatSyn.hs
@@ -24,6 +24,7 @@ import GHC.Prelude
import GHC.Hs
import GHC.Tc.Gen.Pat
+import GHC.Core.Multiplicity
import GHC.Core.Type ( tidyTyCoVarBinders, tidyTypes, tidyType )
import GHC.Tc.Utils.Monad
import GHC.Tc.Gen.Sig( emptyPragEnv, completeSigFromId )
@@ -106,7 +107,7 @@ recoverPSB (PSB { psb_id = L _ name
where
-- The matcher_id is used only by the desugarer, so actually
-- and error-thunk would probably do just as well here.
- matcher_id = mkLocalId matcher_name $
+ matcher_id = mkLocalId matcher_name Many $
mkSpecForAllTys [alphaTyVar] alphaTy
{- Note [Pattern synonym error recovery]
@@ -387,7 +388,7 @@ tcCheckPatSynDecl psb@PSB{ psb_id = lname@(L _ name), psb_args = details
ASSERT2( equalLength arg_names arg_tys, ppr name $$ ppr arg_names $$ ppr arg_tys )
pushLevelAndCaptureConstraints $
tcExtendTyVarEnv univ_tvs $
- tcCheckPat PatSyn lpat pat_ty $
+ tcCheckPat PatSyn lpat (unrestricted pat_ty) $
do { let in_scope = mkInScopeSet (mkVarSet univ_tvs)
empty_subst = mkEmptyTCvSubst in_scope
; (subst, ex_tvs') <- mapAccumLM newMetaTyVarX empty_subst ex_tvs
@@ -402,7 +403,7 @@ tcCheckPatSynDecl psb@PSB{ psb_id = lname@(L _ name), psb_args = details
-- substitution.
-- See also Note [The substitution invariant] in GHC.Core.TyCo.Subst.
; prov_dicts <- mapM (emitWanted (ProvCtxtOrigin psb)) prov_theta'
- ; args' <- zipWithM (tc_arg subst) arg_names arg_tys
+ ; args' <- zipWithM (tc_arg subst) arg_names (map scaledThing arg_tys)
; return (ex_tvs', prov_dicts, args') }
; let skol_info = SigSkol (PatSynCtxt name) pat_ty []
@@ -423,7 +424,7 @@ tcCheckPatSynDecl psb@PSB{ psb_id = lname@(L _ name), psb_args = details
; tc_patsyn_finish lname dir is_infix lpat'
(univ_bndrs, req_theta, ev_binds, req_dicts)
(ex_bndrs, mkTyVarTys ex_tvs', prov_theta, prov_dicts)
- (args', arg_tys)
+ (args', (map scaledThing arg_tys))
pat_ty rec_fields }
where
tc_arg :: TCvSubst -> Name -> Type -> TcM (LHsExpr GhcTcId)
@@ -701,16 +702,16 @@ tcPatSynMatcher (L loc name) lpat
| is_unlifted = ([nlHsVar voidPrimId], [voidPrimTy])
| otherwise = (args, arg_tys)
cont_ty = mkInfSigmaTy ex_tvs prov_theta $
- mkVisFunTys cont_arg_tys res_ty
+ mkVisFunTysMany cont_arg_tys res_ty
- fail_ty = mkVisFunTy voidPrimTy res_ty
+ fail_ty = mkVisFunTyMany voidPrimTy res_ty
; matcher_name <- newImplicitBinder name mkMatcherOcc
- ; scrutinee <- newSysLocalId (fsLit "scrut") pat_ty
- ; cont <- newSysLocalId (fsLit "cont") cont_ty
- ; fail <- newSysLocalId (fsLit "fail") fail_ty
+ ; scrutinee <- newSysLocalId (fsLit "scrut") Many pat_ty
+ ; cont <- newSysLocalId (fsLit "cont") Many cont_ty
+ ; fail <- newSysLocalId (fsLit "fail") Many fail_ty
- ; let matcher_tau = mkVisFunTys [pat_ty, cont_ty, fail_ty] res_ty
+ ; let matcher_tau = mkVisFunTysMany [pat_ty, cont_ty, fail_ty] res_ty
matcher_sigma = mkInfSigmaTy (rr_tv:res_tv:univ_tvs) req_theta matcher_tau
matcher_id = mkExportedVanillaId matcher_name matcher_sigma
-- See Note [Exported LocalIds] in GHC.Types.Id
@@ -730,14 +731,14 @@ tcPatSynMatcher (L loc name) lpat
L (getLoc lpat) $
HsCase noExtField (nlHsVar scrutinee) $
MG{ mg_alts = L (getLoc lpat) cases
- , mg_ext = MatchGroupTc [pat_ty] res_ty
+ , mg_ext = MatchGroupTc [unrestricted pat_ty] res_ty
, mg_origin = Generated
}
body' = noLoc $
HsLam noExtField $
MG{ mg_alts = noLoc [mkSimpleMatch LambdaExpr
args body]
- , mg_ext = MatchGroupTc [pat_ty, cont_ty, fail_ty] res_ty
+ , mg_ext = MatchGroupTc (map unrestricted [pat_ty, cont_ty, fail_ty]) res_ty
, mg_origin = Generated
}
match = mkMatch (mkPrefixFunRhs (L loc name)) []
@@ -799,7 +800,7 @@ mkPatSynBuilderId dir (L _ name)
mkInvisForAllTys univ_bndrs $
mkInvisForAllTys ex_bndrs $
mkPhiTy theta $
- mkVisFunTys arg_tys $
+ mkVisFunTysMany arg_tys $
pat_ty
builder_id = mkExportedVanillaId builder_name builder_sigma
-- See Note [Exported LocalIds] in GHC.Types.Id
@@ -905,7 +906,7 @@ tcPatSynBuilderOcc ps
add_void :: Bool -> Type -> Type
add_void need_dummy_arg ty
- | need_dummy_arg = mkVisFunTy voidPrimTy ty
+ | need_dummy_arg = mkVisFunTyMany voidPrimTy ty
| otherwise = ty
tcPatToExpr :: Name -> [Located Name] -> LPat GhcRn
diff --git a/compiler/GHC/Tc/TyCl/Utils.hs b/compiler/GHC/Tc/TyCl/Utils.hs
index 00a4c01493..b49e81ddd2 100644
--- a/compiler/GHC/Tc/TyCl/Utils.hs
+++ b/compiler/GHC/Tc/TyCl/Utils.hs
@@ -36,6 +36,7 @@ import GHC.Tc.Utils.Monad
import GHC.Tc.Utils.Env
import GHC.Tc.Gen.Bind( tcValBinds )
import GHC.Core.TyCo.Rep( Type(..), Coercion(..), MCoercion(..), UnivCoProvenance(..) )
+import GHC.Core.Multiplicity
import GHC.Tc.Utils.TcType
import GHC.Core.Predicate
import GHC.Builtin.Types( unitTy )
@@ -90,7 +91,7 @@ synonymTyConsOfType ty
go (LitTy _) = emptyNameEnv
go (TyVarTy _) = emptyNameEnv
go (AppTy a b) = go a `plusNameEnv` go b
- go (FunTy _ a b) = go a `plusNameEnv` go b
+ go (FunTy _ w a b) = go w `plusNameEnv` go a `plusNameEnv` go b
go (ForAllTy _ ty) = go ty
go (CastTy ty co) = go ty `plusNameEnv` go_co co
go (CoercionTy co) = go_co co
@@ -124,7 +125,7 @@ synonymTyConsOfType ty
go_co (TyConAppCo _ tc cs) = go_tc tc `plusNameEnv` go_co_s cs
go_co (AppCo co co') = go_co co `plusNameEnv` go_co co'
go_co (ForAllCo _ co co') = go_co co `plusNameEnv` go_co co'
- go_co (FunCo _ co co') = go_co co `plusNameEnv` go_co co'
+ go_co (FunCo _ co_mult co co') = go_co co_mult `plusNameEnv` go_co co `plusNameEnv` go_co co'
go_co (CoVarCo _) = emptyNameEnv
go_co (HoleCo {}) = emptyNameEnv
go_co (AxiomInstCo _ _ cs) = go_co_s cs
@@ -579,7 +580,7 @@ irDataCon datacon
= setRoleInferenceVars univ_tvs $
irExTyVars ex_tvs $ \ ex_var_set ->
mapM_ (irType ex_var_set)
- (map tyVarKind ex_tvs ++ eqSpecPreds eq_spec ++ theta ++ arg_tys)
+ (map tyVarKind ex_tvs ++ eqSpecPreds eq_spec ++ theta ++ (map scaledThing arg_tys))
-- See Note [Role-checking data constructor arguments]
where
(univ_tvs, ex_tvs, eq_spec, theta, arg_tys, _res_ty)
@@ -599,7 +600,7 @@ irType = go
lcls' = extendVarSet lcls tv
; markNominal lcls (tyVarKind tv)
; go lcls' ty }
- go lcls (FunTy _ arg res) = go lcls arg >> go lcls res
+ go lcls (FunTy _ w arg res) = go lcls w >> go lcls arg >> go lcls res
go _ (LitTy {}) = return ()
-- See Note [Coercions in role inference]
go lcls (CastTy ty _) = go lcls ty
@@ -635,7 +636,7 @@ markNominal lcls ty = let nvars = fvVarList (FV.delFVs lcls $ get_ty_vars ty) in
get_ty_vars :: Type -> FV
get_ty_vars (TyVarTy tv) = unitFV tv
get_ty_vars (AppTy t1 t2) = get_ty_vars t1 `unionFV` get_ty_vars t2
- get_ty_vars (FunTy _ t1 t2) = get_ty_vars t1 `unionFV` get_ty_vars t2
+ get_ty_vars (FunTy _ w t1 t2) = get_ty_vars w `unionFV` get_ty_vars t1 `unionFV` get_ty_vars t2
get_ty_vars (TyConApp _ tys) = mapUnionFV get_ty_vars tys
get_ty_vars (ForAllTy tvb ty) = tyCoFVsBndr tvb (get_ty_vars ty)
get_ty_vars (LitTy {}) = emptyFV
@@ -881,7 +882,10 @@ mkOneRecordSelector all_cons idDetails fl
mkPhiTy (conLikeStupidTheta con1) $ -- Urgh!
-- req_theta is empty for normal DataCon
mkPhiTy req_theta $
- mkVisFunTy data_ty $
+ mkVisFunTyMany data_ty $
+ -- Record selectors are always typed with Many. We
+ -- could improve on it in the case where all the
+ -- fields in all the constructor have multiplicity Many.
field_ty
-- Make the binding: sel (C2 { fld = x }) = x
diff --git a/compiler/GHC/Tc/Types.hs b/compiler/GHC/Tc/Types.hs
index 2afb6bc234..1397a3da4b 100644
--- a/compiler/GHC/Tc/Types.hs
+++ b/compiler/GHC/Tc/Types.hs
@@ -95,6 +95,7 @@ import GHC.Core.TyCon ( TyCon, tyConKind )
import GHC.Core.PatSyn ( PatSyn )
import GHC.Types.Id ( idType, idName )
import GHC.Types.FieldLabel ( FieldLabel )
+import GHC.Core.UsageEnv
import GHC.Tc.Utils.TcType
import GHC.Tc.Types.Constraint
import GHC.Tc.Types.Origin
@@ -775,6 +776,9 @@ data TcLclEnv -- Changes as we move inside an expression
tcl_env :: TcTypeEnv, -- The local type environment:
-- Ids and TyVars defined in this module
+ tcl_usage :: TcRef UsageEnv, -- Required multiplicity of bindings is accumulated here.
+
+
tcl_bndrs :: TcBinderStack, -- Used for reporting relevant bindings,
-- and for tidying types
diff --git a/compiler/GHC/Tc/Types/Evidence.hs b/compiler/GHC/Tc/Types/Evidence.hs
index 8649871670..5b33394136 100644
--- a/compiler/GHC/Tc/Types/Evidence.hs
+++ b/compiler/GHC/Tc/Types/Evidence.hs
@@ -88,6 +88,7 @@ import GHC.Utils.Outputable
import GHC.Types.SrcLoc
import Data.IORef( IORef )
import GHC.Types.Unique.Set
+import GHC.Core.Multiplicity
{-
Note [TcCoercions]
@@ -117,7 +118,7 @@ mkTcNomReflCo :: TcType -> TcCoercionN
mkTcRepReflCo :: TcType -> TcCoercionR
mkTcTyConAppCo :: Role -> TyCon -> [TcCoercion] -> TcCoercion
mkTcAppCo :: TcCoercion -> TcCoercionN -> TcCoercion
-mkTcFunCo :: Role -> TcCoercion -> TcCoercion -> TcCoercion
+mkTcFunCo :: Role -> TcCoercion -> TcCoercion -> TcCoercion -> TcCoercion
mkTcAxInstCo :: Role -> CoAxiom br -> BranchIndex
-> [TcType] -> [TcCoercion] -> TcCoercion
mkTcUnbranchedAxInstCo :: CoAxiom Unbranched -> [TcType]
@@ -201,8 +202,8 @@ data HsWrapper
-- Hence (\a. []) `WpCompose` (\b. []) = (\a b. [])
-- But ([] a) `WpCompose` ([] b) = ([] b a)
- | WpFun HsWrapper HsWrapper TcType SDoc
- -- (WpFun wrap1 wrap2 t1)[e] = \(x:t1). wrap2[ e wrap1[x] ]
+ | WpFun HsWrapper HsWrapper (Scaled TcType) SDoc
+ -- (WpFun wrap1 wrap2 (w, t1))[e] = \(x:_w t1). wrap2[ e wrap1[x] ]
-- So note that if wrap1 :: exp_arg <= act_arg
-- wrap2 :: act_res <= exp_res
-- then WpFun wrap1 wrap2 : (act_arg -> arg_res) <= (exp_arg -> exp_res)
@@ -228,6 +229,18 @@ data HsWrapper
| WpLet TcEvBinds -- Non-empty (or possibly non-empty) evidence bindings,
-- so that the identity coercion is always exactly WpHole
+ | WpMultCoercion Coercion
+ -- Note [Checking multiplicity coercions]
+ -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ -- This wrapper can be returned from tcSubMult.
+ -- It is used in case a variable is used with multiplicity m1,
+ -- we need it with multiplicity m2 and we have a coercion c :: m1 ~ m2.
+ -- Compiling such code would require multiplicity coercions in Core,
+ -- which we don't have. If the desugarer sees WpMultCoercion
+ -- with a non-reflexive coercion, it gives an error.
+ -- This is a temporary measure, as we don't really know yet exactly
+ -- what multiplicity coercions should be. But it serves as a good
+ -- approximation for the first iteration for the first iteration of linear types.
-- Cannot derive Data instance because SDoc is not Data (it stores a function).
-- So we do it manually:
@@ -241,6 +254,7 @@ instance Data.Data HsWrapper where
gfoldl k z (WpTyLam a1) = z WpTyLam `k` a1
gfoldl k z (WpTyApp a1) = z WpTyApp `k` a1
gfoldl k z (WpLet a1) = z WpLet `k` a1
+ gfoldl k z (WpMultCoercion a1) = z WpMultCoercion `k` a1
gunfold k z c = case Data.constrIndex c of
1 -> z WpHole
@@ -251,7 +265,8 @@ instance Data.Data HsWrapper where
6 -> k (z WpEvApp)
7 -> k (z WpTyLam)
8 -> k (z WpTyApp)
- _ -> k (z WpLet)
+ 9 -> k (z WpLet)
+ _ -> k (z WpMultCoercion)
toConstr WpHole = wpHole_constr
toConstr (WpCompose _ _) = wpCompose_constr
@@ -262,6 +277,7 @@ instance Data.Data HsWrapper where
toConstr (WpTyLam _) = wpTyLam_constr
toConstr (WpTyApp _) = wpTyApp_constr
toConstr (WpLet _) = wpLet_constr
+ toConstr (WpMultCoercion _) = wpMultCoercion_constr
dataTypeOf _ = hsWrapper_dataType
@@ -270,10 +286,11 @@ hsWrapper_dataType
= Data.mkDataType "HsWrapper"
[ wpHole_constr, wpCompose_constr, wpFun_constr, wpCast_constr
, wpEvLam_constr, wpEvApp_constr, wpTyLam_constr, wpTyApp_constr
- , wpLet_constr]
+ , wpLet_constr, wpMultCoercion_constr ]
wpHole_constr, wpCompose_constr, wpFun_constr, wpCast_constr, wpEvLam_constr,
- wpEvApp_constr, wpTyLam_constr, wpTyApp_constr, wpLet_constr :: Data.Constr
+ wpEvApp_constr, wpTyLam_constr, wpTyApp_constr, wpLet_constr,
+ wpMultCoercion_constr :: Data.Constr
wpHole_constr = mkHsWrapperConstr "WpHole"
wpCompose_constr = mkHsWrapperConstr "WpCompose"
wpFun_constr = mkHsWrapperConstr "WpFun"
@@ -283,11 +300,12 @@ wpEvApp_constr = mkHsWrapperConstr "WpEvApp"
wpTyLam_constr = mkHsWrapperConstr "WpTyLam"
wpTyApp_constr = mkHsWrapperConstr "WpTyApp"
wpLet_constr = mkHsWrapperConstr "WpLet"
+wpMultCoercion_constr = mkHsWrapperConstr "WpMultCoercion"
mkHsWrapperConstr :: String -> Data.Constr
mkHsWrapperConstr name = Data.mkConstr hsWrapper_dataType name [] Data.Prefix
-wpFunEmpty :: HsWrapper -> HsWrapper -> TcType -> HsWrapper
+wpFunEmpty :: HsWrapper -> HsWrapper -> Scaled TcType -> HsWrapper
wpFunEmpty c1 c2 t1 = WpFun c1 c2 t1 empty
(<.>) :: HsWrapper -> HsWrapper -> HsWrapper
@@ -296,15 +314,15 @@ c <.> WpHole = c
c1 <.> c2 = c1 `WpCompose` c2
mkWpFun :: HsWrapper -> HsWrapper
- -> TcType -- the "from" type of the first wrapper
+ -> (Scaled TcType) -- the "from" type of the first wrapper
-> TcType -- either type of the second wrapper (used only when the
-- second wrapper is the identity)
-> SDoc -- what caused you to want a WpFun? Something like "When converting ..."
-> HsWrapper
mkWpFun WpHole WpHole _ _ _ = WpHole
-mkWpFun WpHole (WpCast co2) t1 _ _ = WpCast (mkTcFunCo Representational (mkTcRepReflCo t1) co2)
-mkWpFun (WpCast co1) WpHole _ t2 _ = WpCast (mkTcFunCo Representational (mkTcSymCo co1) (mkTcRepReflCo t2))
-mkWpFun (WpCast co1) (WpCast co2) _ _ _ = WpCast (mkTcFunCo Representational (mkTcSymCo co1) co2)
+mkWpFun WpHole (WpCast co2) (Scaled w t1) _ _ = WpCast (mkTcFunCo Representational (multToCo w) (mkTcRepReflCo t1) co2)
+mkWpFun (WpCast co1) WpHole (Scaled w _) t2 _ = WpCast (mkTcFunCo Representational (multToCo w) (mkTcSymCo co1) (mkTcRepReflCo t2))
+mkWpFun (WpCast co1) (WpCast co2) (Scaled w _) _ _ = WpCast (mkTcFunCo Representational (multToCo w) (mkTcSymCo co1) co2)
mkWpFun co1 co2 t1 _ d = WpFun co1 co2 t1 d
mkWpCastR :: TcCoercionR -> HsWrapper
@@ -375,6 +393,7 @@ hsWrapDictBinders wrap = go wrap
go (WpTyLam {}) = emptyBag
go (WpTyApp {}) = emptyBag
go (WpLet {}) = emptyBag
+ go (WpMultCoercion {}) = emptyBag
collectHsWrapBinders :: HsWrapper -> ([Var], HsWrapper)
-- Collect the outer lambda binders of a HsWrapper,
@@ -608,9 +627,9 @@ data EvTypeable
-- ^ Dictionary for @Typeable (s t)@,
-- given a dictionaries for @s@ and @t@.
- | EvTypeableTrFun EvTerm EvTerm
- -- ^ Dictionary for @Typeable (s -> t)@,
- -- given a dictionaries for @s@ and @t@.
+ | EvTypeableTrFun EvTerm EvTerm EvTerm
+ -- ^ Dictionary for @Typeable (s # w -> t)@,
+ -- given a dictionaries for @w@, @s@, and @t@.
| EvTypeableTyLit EvTerm
-- ^ Dictionary for a type literal,
@@ -893,10 +912,10 @@ evVarsOfTerms = mapUnionVarSet evVarsOfTerm
evVarsOfTypeable :: EvTypeable -> VarSet
evVarsOfTypeable ev =
case ev of
- EvTypeableTyCon _ e -> mapUnionVarSet evVarsOfTerm e
- EvTypeableTyApp e1 e2 -> evVarsOfTerms [e1,e2]
- EvTypeableTrFun e1 e2 -> evVarsOfTerms [e1,e2]
- EvTypeableTyLit e -> evVarsOfTerm e
+ EvTypeableTyCon _ e -> mapUnionVarSet evVarsOfTerm e
+ EvTypeableTyApp e1 e2 -> evVarsOfTerms [e1,e2]
+ EvTypeableTrFun em e1 e2 -> evVarsOfTerms [em,e1,e2]
+ EvTypeableTyLit e -> evVarsOfTerm e
{- Note [Free vars of EvFun]
@@ -937,7 +956,7 @@ pprHsWrapper wrap pp_thing_inside
-- False <=> appears as body of let or lambda
help it WpHole = it
help it (WpCompose f1 f2) = help (help it f2) f1
- help it (WpFun f1 f2 t1 _) = add_parens $ text "\\(x" <> dcolon <> ppr t1 <> text ")." <+>
+ help it (WpFun f1 f2 (Scaled w t1) _) = add_parens $ text "\\(x" <> dcolon <> brackets (ppr w) <> ppr t1 <> text ")." <+>
help (\_ -> it True <+> help (\_ -> text "x") f1 True) f2 False
help it (WpCast co) = add_parens $ sep [it False, nest 2 (text "|>"
<+> pprParendCo co)]
@@ -946,6 +965,8 @@ pprHsWrapper wrap pp_thing_inside
help it (WpEvLam id) = add_parens $ sep [ text "\\" <> pprLamBndr id <> dot, it False]
help it (WpTyLam tv) = add_parens $ sep [text "/\\" <> pprLamBndr tv <> dot, it False]
help it (WpLet binds) = add_parens $ sep [text "let" <+> braces (ppr binds), it False]
+ help it (WpMultCoercion co) = add_parens $ sep [it False, nest 2 (text "<multiplicity coercion>"
+ <+> pprParendCo co)]
pprLamBndr :: Id -> SDoc
pprLamBndr v = pprBndr LambdaBind v
@@ -992,7 +1013,7 @@ instance Outputable EvCallStack where
instance Outputable EvTypeable where
ppr (EvTypeableTyCon ts _) = text "TyCon" <+> ppr ts
ppr (EvTypeableTyApp t1 t2) = parens (ppr t1 <+> ppr t2)
- ppr (EvTypeableTrFun t1 t2) = parens (ppr t1 <+> arrow <+> ppr t2)
+ ppr (EvTypeableTrFun tm t1 t2) = parens (ppr t1 <+> mulArrow (ppr tm) <+> ppr t2)
ppr (EvTypeableTyLit t1) = text "TyLit" <> ppr t1
diff --git a/compiler/GHC/Tc/Types/Origin.hs b/compiler/GHC/Tc/Types/Origin.hs
index b453633c65..7dfa5ffd65 100644
--- a/compiler/GHC/Tc/Types/Origin.hs
+++ b/compiler/GHC/Tc/Types/Origin.hs
@@ -34,6 +34,7 @@ import GHC.Core.ConLike
import GHC.Core.TyCon
import GHC.Core.InstEnv
import GHC.Core.PatSyn
+import GHC.Core.Multiplicity ( scaledThing )
import GHC.Unit.Module
import GHC.Types.Name
@@ -285,12 +286,13 @@ pprSigSkolInfo ctxt ty
pprPatSkolInfo :: ConLike -> SDoc
pprPatSkolInfo (RealDataCon dc)
- = sep [ text "a pattern with constructor:"
- , nest 2 $ ppr dc <+> dcolon
- <+> pprType (dataConUserType dc) <> comma ]
- -- pprType prints forall's regardless of -fprint-explicit-foralls
- -- which is what we want here, since we might be saying
- -- type variable 't' is bound by ...
+ = sdocWithDynFlags (\dflags ->
+ sep [ text "a pattern with constructor:"
+ , nest 2 $ ppr dc <+> dcolon
+ <+> pprType (dataConDisplayType dflags dc) <> comma ])
+ -- pprType prints forall's regardless of -fprint-explicit-foralls
+ -- which is what we want here, since we might be saying
+ -- type variable 't' is bound by ...
pprPatSkolInfo (PatSynCon ps)
= sep [ text "a pattern with pattern synonym:"
@@ -444,6 +446,9 @@ data CtOrigin
| InstProvidedOrigin Module ClsInst
-- Skolem variable arose when we were testing if an instance
-- is solvable or not.
+ | NonLinearPatternOrigin
+ | UsageEnvironmentOf Name
+
-- An origin is visible if the place where the constraint arises is manifest
-- in user code. Currently, all origins are visible except for invisible
-- TypeEqOrigins. This is used when choosing which error of
@@ -575,7 +580,7 @@ pprCtOrigin (UnboundOccurrenceOf name)
pprCtOrigin (DerivOriginDC dc n _)
= hang (ctoHerald <+> text "the" <+> speakNth n
<+> text "field of" <+> quotes (ppr dc))
- 2 (parens (text "type" <+> quotes (ppr ty)))
+ 2 (parens (text "type" <+> quotes (ppr (scaledThing ty))))
where
ty = dataConOrigArgTys dc !! (n-1)
@@ -650,5 +655,7 @@ pprCtO (TypeHoleOrigin occ) = text "a use of wildcard" <+> quotes (ppr occ)
pprCtO PatCheckOrigin = text "a pattern-match completeness check"
pprCtO ListOrigin = text "an overloaded list"
pprCtO StaticOrigin = text "a static form"
+pprCtO NonLinearPatternOrigin = text "a non-linear pattern"
+pprCtO (UsageEnvironmentOf x) = hsep [text "multiplicity of", quotes (ppr x)]
pprCtO BracketOrigin = text "a quotation bracket"
pprCtO _ = panic "pprCtOrigin"
diff --git a/compiler/GHC/Tc/Utils/Backpack.hs b/compiler/GHC/Tc/Utils/Backpack.hs
index 1f6090c7b7..72a1aee55d 100644
--- a/compiler/GHC/Tc/Utils/Backpack.hs
+++ b/compiler/GHC/Tc/Utils/Backpack.hs
@@ -50,6 +50,7 @@ import GHC.Types.SrcLoc
import GHC.Driver.Types
import GHC.Utils.Outputable
import GHC.Core.Type
+import GHC.Core.Multiplicity
import GHC.Data.FastString
import GHC.Rename.Fixity ( lookupFixityRn )
import GHC.Data.Maybe
@@ -216,7 +217,7 @@ check_inst sig_inst = do
(substTy skol_subst pred)
givens <- forM theta $ \given -> do
loc <- getCtLocM origin (Just TypeLevel)
- let given_pred = substTy skol_subst given
+ let given_pred = substTy skol_subst (scaledThing given)
new_ev <- newEvVar given_pred
return CtGiven { ctev_pred = given_pred
-- Doesn't matter, make something up
diff --git a/compiler/GHC/Tc/Utils/Env.hs b/compiler/GHC/Tc/Utils/Env.hs
index 2563ff7348..55c0ad4e67 100644
--- a/compiler/GHC/Tc/Utils/Env.hs
+++ b/compiler/GHC/Tc/Utils/Env.hs
@@ -34,6 +34,7 @@ module GHC.Tc.Utils.Env(
tcExtendIdEnv, tcExtendIdEnv1, tcExtendIdEnv2,
tcExtendBinderStack, tcExtendLocalTypeEnv,
isTypeClosedLetBndr,
+ tcCheckUsage,
tcLookup, tcLookupLocated, tcLookupLocalIds,
tcLookupId, tcLookupIdMaybe, tcLookupTyVar,
@@ -78,6 +79,10 @@ import GHC.Iface.Env
import GHC.Tc.Utils.Monad
import GHC.Tc.Utils.TcMType
import GHC.Tc.Utils.TcType
+import GHC.Core.UsageEnv
+import GHC.Tc.Types.Evidence (HsWrapper, idHsWrapper)
+import {-# SOURCE #-} GHC.Tc.Utils.Unify ( tcSubMult )
+import GHC.Tc.Types.Origin ( CtOrigin(UsageEnvironmentOf) )
import GHC.Iface.Load
import GHC.Builtin.Names
import GHC.Builtin.Types
@@ -108,6 +113,7 @@ import GHC.Data.Bag
import GHC.Data.List.SetOps
import GHC.Utils.Error
import GHC.Data.Maybe( MaybeErr(..), orElse )
+import GHC.Core.Multiplicity
import qualified GHC.LanguageExtensions as LangExt
import GHC.Utils.Misc ( HasDebugCallStack )
@@ -621,6 +627,28 @@ tcExtendLocalTypeEnv :: TcLclEnv -> [(Name, TcTyThing)] -> TcLclEnv
tcExtendLocalTypeEnv lcl_env@(TcLclEnv { tcl_env = lcl_type_env }) tc_ty_things
= lcl_env { tcl_env = extendNameEnvList lcl_type_env tc_ty_things }
+-- | @tcCheckUsage name mult thing_inside@ runs @thing_inside@, checks that the
+-- usage of @name@ is a submultiplicity of @mult@, and removes @name@ from the
+-- usage environment. See also Note [tcSubMult's wrapper] in TcUnify.
+tcCheckUsage :: Name -> Mult -> TcM a -> TcM (a, HsWrapper)
+tcCheckUsage name id_mult thing_inside
+ = do { (local_usage, result) <- tcCollectingUsage thing_inside
+ ; wrapper <- check_then_add_usage local_usage
+ ; return (result, wrapper) }
+ where
+ check_then_add_usage :: UsageEnv -> TcM HsWrapper
+ -- Checks that the usage of the newly introduced binder is compatible with
+ -- its multiplicity, and combines the usage of non-new binders to |uenv|
+ check_then_add_usage uenv
+ = do { let actual_u = lookupUE uenv name
+ ; traceTc "check_then_add_usage" (ppr id_mult $$ ppr actual_u)
+ ; wrapper <- case actual_u of
+ Bottom -> return idHsWrapper
+ Zero -> tcSubMult (UsageEnvironmentOf name) Many id_mult
+ MUsage m -> tcSubMult (UsageEnvironmentOf name) m id_mult
+ ; tcEmitBindingUsage (deleteUE uenv name)
+ ; return wrapper }
+
{- *********************************************************************
* *
The TcBinderStack
diff --git a/compiler/GHC/Tc/Utils/Instantiate.hs b/compiler/GHC/Tc/Utils/Instantiate.hs
index df9cf982ee..d027209d04 100644
--- a/compiler/GHC/Tc/Utils/Instantiate.hs
+++ b/compiler/GHC/Tc/Utils/Instantiate.hs
@@ -53,6 +53,7 @@ import GHC.Core ( isOrphan )
import GHC.Tc.Instance.FunDeps
import GHC.Tc.Utils.TcMType
import GHC.Core.Type
+import GHC.Core.Multiplicity
import GHC.Core.TyCo.Rep
import GHC.Core.TyCo.Ppr ( debugPprType )
import GHC.Tc.Utils.TcType
@@ -393,7 +394,7 @@ tcInstInvisibleTyBinder subst (Named (Bndr tv _))
; return (subst', mkTyVarTy tv') }
tcInstInvisibleTyBinder subst (Anon af ty)
- | Just (mk, k1, k2) <- get_eq_tys_maybe (substTy subst ty)
+ | Just (mk, k1, k2) <- get_eq_tys_maybe (substTy subst (scaledThing ty))
-- Equality is the *only* constraint currently handled in types.
-- See Note [Constraints in kinds] in GHC.Core.TyCo.Rep
= ASSERT( af == InvisArg )
@@ -500,7 +501,7 @@ newNonTrivialOverloadedLit orig
; let lit_ty = hsLitType hs_lit
; (_, fi') <- tcSyntaxOp orig (mkRnSyntaxExpr meth_name)
[synKnownType lit_ty] res_ty $
- \_ -> return ()
+ \_ _ -> return ()
; let L _ witness = nlHsSyntaxApps fi' [nlHsLit hs_lit]
; res_ty <- readExpType res_ty
; return (lit { ol_witness = witness
diff --git a/compiler/GHC/Tc/Utils/Monad.hs b/compiler/GHC/Tc/Utils/Monad.hs
index ca85a087b6..e485b667af 100644
--- a/compiler/GHC/Tc/Utils/Monad.hs
+++ b/compiler/GHC/Tc/Utils/Monad.hs
@@ -69,6 +69,9 @@ module GHC.Tc.Utils.Monad(
addMessages,
discardWarnings,
+ -- * Usage environment
+ tcCollectingUsage, tcScalingUsage, tcEmitBindingUsage,
+
-- * Shared error message stuff: renamer and typechecker
mkLongErrAt, mkErrDocAt, addLongErrAt, reportErrors, reportError,
reportWarning, recoverM, mapAndRecoverM, mapAndReportM, foldAndRecoverM,
@@ -157,6 +160,8 @@ import GHC.Driver.Types
import GHC.Unit
import GHC.Types.Name.Reader
import GHC.Types.Name
+import GHC.Core.UsageEnv
+import GHC.Core.Multiplicity
import GHC.Core.Type
import GHC.Tc.Utils.TcType
@@ -332,6 +337,7 @@ initTcWithGbl :: HscEnv
initTcWithGbl hsc_env gbl_env loc do_this
= do { lie_var <- newIORef emptyWC
; errs_var <- newIORef (emptyBag, emptyBag)
+ ; usage_var <- newIORef zeroUE
; let lcl_env = TcLclEnv {
tcl_errs = errs_var,
tcl_loc = loc, -- Should be over-ridden very soon!
@@ -341,6 +347,7 @@ initTcWithGbl hsc_env gbl_env loc do_this
tcl_th_bndrs = emptyNameEnv,
tcl_arrow_ctxt = NoArrowCtxt,
tcl_env = emptyNameEnv,
+ tcl_usage = usage_var,
tcl_bndrs = [],
tcl_lie = lie_var,
tcl_tclvl = topTcLevel
@@ -625,15 +632,16 @@ newSysName occ
= do { uniq <- newUnique
; return (mkSystemName uniq occ) }
-newSysLocalId :: FastString -> TcType -> TcRnIf gbl lcl TcId
-newSysLocalId fs ty
+newSysLocalId :: FastString -> Mult -> TcType -> TcRnIf gbl lcl TcId
+newSysLocalId fs w ty
= do { u <- newUnique
- ; return (mkSysLocal fs u ty) }
+ ; return (mkSysLocal fs u w ty) }
-newSysLocalIds :: FastString -> [TcType] -> TcRnIf gbl lcl [TcId]
+newSysLocalIds :: FastString -> [Scaled TcType] -> TcRnIf gbl lcl [TcId]
newSysLocalIds fs tys
= do { us <- newUniqueSupply
- ; return (zipWith (mkSysLocal fs) (uniqsFromSupply us) tys) }
+ ; let mkId' n (Scaled w t) = mkSysLocal fs n w t
+ ; return (zipWith mkId' (uniqsFromSupply us) tys) }
instance MonadUnique (IOEnv (Env gbl lcl)) where
getUniqueM = newUnique
@@ -1191,6 +1199,36 @@ captureConstraints thing_inside
Just res -> return (res, lie) }
-----------------------
+-- | @tcCollectingUsage thing_inside@ runs @thing_inside@ and returns the usage
+-- information which was collected as part of the execution of
+-- @thing_inside@. Careful: @tcCollectingUsage thing_inside@ itself does not
+-- report any usage information, it's up to the caller to incorporate the
+-- returned usage information into the larger context appropriately.
+tcCollectingUsage :: TcM a -> TcM (UsageEnv,a)
+tcCollectingUsage thing_inside
+ = do { env0 <- getLclEnv
+ ; local_usage_ref <- newTcRef zeroUE
+ ; let env1 = env0 { tcl_usage = local_usage_ref }
+ ; result <- setLclEnv env1 thing_inside
+ ; local_usage <- readTcRef local_usage_ref
+ ; return (local_usage,result) }
+
+-- | @tcScalingUsage mult thing_inside@ runs @thing_inside@ and scales all the
+-- usage information by @mult@.
+tcScalingUsage :: Mult -> TcM a -> TcM a
+tcScalingUsage mult thing_inside
+ = do { (usage, result) <- tcCollectingUsage thing_inside
+ ; traceTc "tcScalingUsage" (ppr mult)
+ ; tcEmitBindingUsage $ scaleUE mult usage
+ ; return result }
+
+tcEmitBindingUsage :: UsageEnv -> TcM ()
+tcEmitBindingUsage ue
+ = do { lcl_env <- getLclEnv
+ ; let usage = tcl_usage lcl_env
+ ; updTcRef usage (addUE ue) }
+
+-----------------------
attemptM :: TcRn r -> TcRn (Maybe r)
-- (attemptM thing_inside) runs thing_inside
-- If thing_inside succeeds, returning r,
diff --git a/compiler/GHC/Tc/Utils/TcMType.hs b/compiler/GHC/Tc/Utils/TcMType.hs
index cc8ac8f737..c33c335ac7 100644
--- a/compiler/GHC/Tc/Utils/TcMType.hs
+++ b/compiler/GHC/Tc/Utils/TcMType.hs
@@ -4,7 +4,7 @@
-}
-{-# LANGUAGE CPP, TupleSections, MultiWayIf #-}
+{-# LANGUAGE CPP, TupleSections, MultiWayIf, PatternSynonyms #-}
{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}
@@ -26,6 +26,7 @@ module GHC.Tc.Utils.TcMType (
cloneMetaTyVar,
newFmvTyVar, newFskTyVar,
+ newMultiplicityVar,
readMetaTyVar, writeMetaTyVar, writeMetaTyVarRef,
newTauTvDetailsAtLevel, newMetaDetails, newMetaTyVarName,
isFilledMetaTyVar_maybe, isFilledMetaTyVar, isUnfilledMetaTyVar,
@@ -126,6 +127,7 @@ import GHC.Data.FastString
import GHC.Data.Bag
import GHC.Data.Pair
import GHC.Types.Unique.Set
+import GHC.Core.Multiplicity
import GHC.Driver.Session
import qualified GHC.LanguageExtensions as LangExt
import GHC.Types.Basic ( TypeOrKind(..) )
@@ -173,7 +175,7 @@ newEvVars theta = mapM newEvVar theta
newEvVar :: TcPredType -> TcRnIf gbl lcl EvVar
-- Creates new *rigid* variables for predicates
newEvVar ty = do { name <- newSysName (predTypeOccName ty)
- ; return (mkLocalIdOrCoVar name ty) }
+ ; return (mkLocalIdOrCoVar name Many ty) }
newWanted :: CtOrigin -> Maybe TypeOrKind -> PredType -> TcM CtEvidence
-- Deals with both equality and non-equality predicates
@@ -286,7 +288,7 @@ emitNewExprHole occ ev_id ty
newDict :: Class -> [TcType] -> TcM DictId
newDict cls tys
= do { name <- newSysName (mkDictOcc (getOccName cls))
- ; return (mkLocalId name (mkClassPred cls tys)) }
+ ; return (mkLocalId name Many (mkClassPred cls tys)) }
predTypeOccName :: PredType -> OccName
predTypeOccName ty = case classifyPredType ty of
@@ -925,6 +927,7 @@ writeMetaTyVarRef tyvar ref ty
-- Check for level OK
-- See Note [Level check when unifying]
; MASSERT2( level_check_ok, level_check_msg )
+ -- another level check problem, see #97
-- Check Kinds ok
; MASSERT2( kind_check_ok, kind_msg )
@@ -982,6 +985,9 @@ that can't ever appear in user code, so we're safe!
-}
+newMultiplicityVar :: TcM TcType
+newMultiplicityVar = newFlexiTyVarTy multiplicityTy
+
newFlexiTyVar :: Kind -> TcM TcTyVar
newFlexiTyVar kind = newAnonMetaTyVar TauTv kind
@@ -1320,9 +1326,9 @@ collect_cand_qtvs orig_ty is_dep bound dvs ty
-----------------
go :: CandidatesQTvs -> TcType -> TcM CandidatesQTvs
-- Uses accumulating-parameter style
- go dv (AppTy t1 t2) = foldlM go dv [t1, t2]
- go dv (TyConApp _ tys) = foldlM go dv tys
- go dv (FunTy _ arg res) = foldlM go dv [arg, res]
+ go dv (AppTy t1 t2) = foldlM go dv [t1, t2]
+ go dv (TyConApp _ tys) = foldlM go dv tys
+ go dv (FunTy _ w arg res) = foldlM go dv [w, arg, res]
go dv (LitTy {}) = return dv
go dv (CastTy ty co) = do dv1 <- go dv ty
collect_cand_qtvs_co orig_ty bound dv1 co
@@ -1393,7 +1399,7 @@ collect_cand_qtvs_co orig_ty bound = go_co
go_mco dv1 mco
go_co dv (TyConAppCo _ _ cos) = foldlM go_co dv cos
go_co dv (AppCo co1 co2) = foldlM go_co dv [co1, co2]
- go_co dv (FunCo _ co1 co2) = foldlM go_co dv [co1, co2]
+ go_co dv (FunCo _ w co1 co2) = foldlM go_co dv [w, co1, co2]
go_co dv (AxiomInstCo _ _ cos) = foldlM go_co dv cos
go_co dv (AxiomRuleCo _ cos) = foldlM go_co dv cos
go_co dv (UnivCo prov _ t1 t2) = do dv1 <- go_prov dv prov
@@ -1725,6 +1731,10 @@ defaultTyVar default_kind tv
= do { traceTc "Defaulting a RuntimeRep var to LiftedRep" (ppr tv)
; writeMetaTyVar tv liftedRepTy
; return True }
+ | isMultiplicityVar tv
+ = do { traceTc "Defaulting a Multiplicty var to Many" (ppr tv)
+ ; writeMetaTyVar tv manyDataConTy
+ ; return True }
| default_kind -- -XNoPolyKinds and this is a kind var
= default_kind_var tv -- so default it to * if possible
@@ -2030,8 +2040,7 @@ zonkImplication implic@(Implic { ic_skols = skols
, ic_info = info' }) }
zonkEvVar :: EvVar -> TcM EvVar
-zonkEvVar var = do { ty' <- zonkTcType (varType var)
- ; return (setVarType var ty') }
+zonkEvVar var = updateVarTypeAndMultM zonkTcType var
zonkWC :: WantedConstraints -> TcM WantedConstraints
@@ -2218,9 +2227,7 @@ zonkInvisTVBinder (Bndr tv spec) = do { tv' <- zonkTcTyVarToTyVar tv
-- zonkId is used *during* typechecking just to zonk the Id's type
zonkId :: TcId -> TcM TcId
-zonkId id
- = do { ty' <- zonkTcType (idType id)
- ; return (Id.setIdType id ty') }
+zonkId id = Id.updateIdTypeAndMultM zonkTcType id
zonkCoVar :: CoVar -> TcM CoVar
zonkCoVar = zonkId
@@ -2308,7 +2315,7 @@ tidyHole env h@(Hole { hole_ty = ty }) = h { hole_ty = tidyType env ty }
----------------
tidyEvVar :: TidyEnv -> EvVar -> EvVar
-tidyEvVar env var = setVarType var (tidyType env (varType var))
+tidyEvVar env var = updateVarTypeAndMult (tidyType env) var
----------------
tidySkolemInfo :: TidyEnv -> SkolemInfo -> SkolemInfo
@@ -2333,8 +2340,10 @@ tidySigSkol env cx ty tv_prs
where
(env', tv') = tidy_tv_bndr env tv
- tidy_ty env ty@(FunTy InvisArg arg res) -- Look under c => t
- = ty { ft_arg = tidyType env arg, ft_res = tidy_ty env res }
+ tidy_ty env ty@(FunTy InvisArg w arg res) -- Look under c => t
+ = ty { ft_mult = tidy_ty env w,
+ ft_arg = tidyType env arg,
+ ft_res = tidy_ty env res }
tidy_ty env ty = tidyType env ty
diff --git a/compiler/GHC/Tc/Utils/TcType.hs b/compiler/GHC/Tc/Utils/TcType.hs
index 9cc1d79df9..f06cdd7d31 100644
--- a/compiler/GHC/Tc/Utils/TcType.hs
+++ b/compiler/GHC/Tc/Utils/TcType.hs
@@ -134,7 +134,8 @@ module GHC.Tc.Utils.TcType (
mkForAllTy, mkForAllTys, mkInvisForAllTys, mkTyCoInvForAllTys,
mkSpecForAllTys, mkTyCoInvForAllTy,
mkInfForAllTy, mkInfForAllTys,
- mkVisFunTy, mkVisFunTys, mkInvisFunTy, mkInvisFunTys,
+ mkVisFunTy, mkVisFunTys, mkInvisFunTy, mkInvisFunTyMany,
+ mkVisFunTyMany, mkVisFunTysMany, mkInvisFunTysMany,
mkTyConApp, mkAppTy, mkAppTys,
mkTyConTy, mkTyVarTy, mkTyVarTys,
mkTyCoVarTy, mkTyCoVarTys,
@@ -155,9 +156,10 @@ module GHC.Tc.Utils.TcType (
Type.lookupTyVar, Type.extendTCvSubst, Type.substTyVarBndr,
Type.extendTvSubst,
isInScope, mkTCvSubst, mkTvSubst, zipTyEnv, zipCoEnv,
- Type.substTy, substTys, substTyWith, substTyWithCoVars,
+ Type.substTy, substTys, substScaledTys, substTyWith, substTyWithCoVars,
substTyAddInScope,
- substTyUnchecked, substTysUnchecked, substThetaUnchecked,
+ substTyUnchecked, substTysUnchecked, substScaledTyUnchecked,
+ substThetaUnchecked,
substTyWithUnchecked,
substCoUnchecked, substCoWithUnchecked,
substTheta,
@@ -198,6 +200,7 @@ import GHC.Core.TyCo.Subst ( mkTvSubst, substTyWithCoVars )
import GHC.Core.TyCo.FVs
import GHC.Core.TyCo.Ppr
import GHC.Core.Class
+import GHC.Core.Multiplicity
import GHC.Types.Var
import GHC.Types.ForeignCall
import GHC.Types.Var.Set
@@ -411,6 +414,9 @@ mkCheckExpType = Check
-- for the 'SynType', because you've said positively that it should be an
-- Int, and so it shall be.
--
+-- You'll also get three multiplicities back: one for each function arrow. See
+-- also Note [Linear types] in Multiplicity.
+--
-- This is defined here to avoid defining it in GHC.Tc.Gen.Expr boot file.
data SyntaxOpType
= SynAny -- ^ Any type
@@ -804,7 +810,8 @@ tcTyFamInstsAndVisX = go
go _ (LitTy {}) = []
go is_invis_arg (ForAllTy bndr ty) = go is_invis_arg (binderType bndr)
++ go is_invis_arg ty
- go is_invis_arg (FunTy _ ty1 ty2) = go is_invis_arg ty1
+ go is_invis_arg (FunTy _ w ty1 ty2) = go is_invis_arg w
+ ++ go is_invis_arg ty1
++ go is_invis_arg ty2
go is_invis_arg ty@(AppTy _ _) =
let (ty_head, ty_args) = splitAppTys ty
@@ -861,8 +868,8 @@ anyRewritableTyVar ignore_cos role pred ty
go _ _ (LitTy {}) = False
go rl bvs (TyConApp tc tys) = go_tc rl bvs tc tys
go rl bvs (AppTy fun arg) = go rl bvs fun || go NomEq bvs arg
- go rl bvs (FunTy _ arg res) = go NomEq bvs arg_rep || go NomEq bvs res_rep ||
- go rl bvs arg || go rl bvs res
+ go rl bvs (FunTy _ w arg res) = go NomEq bvs arg_rep || go NomEq bvs res_rep ||
+ go rl bvs arg || go rl bvs res || go rl bvs w
where arg_rep = getRuntimeRep arg -- forgetting these causes #17024
res_rep = getRuntimeRep res
go rl bvs (ForAllTy tv ty) = go rl (bvs `extendVarSet` binderVar tv) ty
@@ -1133,7 +1140,7 @@ mkSpecSigmaTy :: [TyVar] -> [PredType] -> Type -> Type
mkSpecSigmaTy tyvars preds ty = mkSigmaTy (mkTyCoVarBinders Specified tyvars) preds ty
mkPhiTy :: [PredType] -> Type -> Type
-mkPhiTy = mkInvisFunTys
+mkPhiTy = mkInvisFunTysMany
---------------
getDFunTyKey :: Type -> OccName -- Get some string from a type, to be used to
@@ -1329,18 +1336,18 @@ tcSplitTyConApp ty = case tcSplitTyConApp_maybe ty of
Nothing -> pprPanic "tcSplitTyConApp" (pprType ty)
-----------------------
-tcSplitFunTys :: Type -> ([Type], Type)
+tcSplitFunTys :: Type -> ([Scaled Type], Type)
tcSplitFunTys ty = case tcSplitFunTy_maybe ty of
Nothing -> ([], ty)
Just (arg,res) -> (arg:args, res')
where
(args,res') = tcSplitFunTys res
-tcSplitFunTy_maybe :: Type -> Maybe (Type, Type)
+tcSplitFunTy_maybe :: Type -> Maybe (Scaled Type, Type)
tcSplitFunTy_maybe ty
| Just ty' <- tcView ty = tcSplitFunTy_maybe ty'
-tcSplitFunTy_maybe (FunTy { ft_af = af, ft_arg = arg, ft_res = res })
- | VisArg <- af = Just (arg, res)
+tcSplitFunTy_maybe (FunTy { ft_af = af, ft_mult = w, ft_arg = arg, ft_res = res })
+ | VisArg <- af = Just (Scaled w arg, res)
tcSplitFunTy_maybe _ = Nothing
-- Note the VisArg guard
-- Consider (?x::Int) => Bool
@@ -1353,7 +1360,7 @@ tcSplitFunTy_maybe _ = Nothing
tcSplitFunTysN :: Arity -- n: Number of desired args
-> TcRhoType
-> Either Arity -- Number of missing arrows
- ([TcSigmaType], -- Arg types (always N types)
+ ([Scaled TcSigmaType],-- Arg types (always N types)
TcSigmaType) -- The rest of the type
-- ^ Split off exactly the specified number argument types
-- Returns
@@ -1369,10 +1376,10 @@ tcSplitFunTysN n ty
| otherwise
= Left n
-tcSplitFunTy :: Type -> (Type, Type)
+tcSplitFunTy :: Type -> (Scaled Type, Type)
tcSplitFunTy ty = expectJust "tcSplitFunTy" (tcSplitFunTy_maybe ty)
-tcFunArgTy :: Type -> Type
+tcFunArgTy :: Type -> Scaled Type
tcFunArgTy ty = fst (tcSplitFunTy ty)
tcFunResultTy :: Type -> Type
@@ -1452,7 +1459,7 @@ tcSplitDFunTy ty
= case tcSplitForAllTys ty of { (tvs, rho) ->
case splitFunTys rho of { (theta, tau) ->
case tcSplitDFunHead tau of { (clas, tys) ->
- (tvs, theta, clas, tys) }}}
+ (tvs, map scaledThing theta, clas, tys) }}}
tcSplitDFunHead :: Type -> (Class, [Type])
tcSplitDFunHead = getClassPredTys
@@ -1544,10 +1551,10 @@ tc_eq_type keep_syns vis_only orig_ty1 orig_ty2
-- Make sure we handle all FunTy cases since falling through to the
-- AppTy case means that tcRepSplitAppTy_maybe may see an unzonked
-- kind variable, which causes things to blow up.
- go env (FunTy _ arg1 res1) (FunTy _ arg2 res2)
- = go env arg1 arg2 && go env res1 res2
- go env ty (FunTy _ arg res) = eqFunTy env arg res ty
- go env (FunTy _ arg res) ty = eqFunTy env arg res ty
+ go env (FunTy _ w1 arg1 res1) (FunTy _ w2 arg2 res2)
+ = go env w1 w2 && go env arg1 arg2 && go env res1 res2
+ go env ty (FunTy _ w arg res) = eqFunTy env w arg res ty
+ go env (FunTy _ w arg res) ty = eqFunTy env w arg res ty
-- See Note [Equality on AppTys] in GHC.Core.Type
go env (AppTy s1 t1) ty2
@@ -1582,25 +1589,25 @@ tc_eq_type keep_syns vis_only orig_ty1 orig_ty2
orig_env = mkRnEnv2 $ mkInScopeSet $ tyCoVarsOfTypes [orig_ty1, orig_ty2]
- -- @eqFunTy arg res ty@ is True when @ty@ equals @FunTy arg res@. This is
+ -- @eqFunTy w arg res ty@ is True when @ty@ equals @FunTy w arg res@. This is
-- sometimes hard to know directly because @ty@ might have some casts
-- obscuring the FunTy. And 'splitAppTy' is difficult because we can't
-- always extract a RuntimeRep (see Note [xyz]) if the kind of the arg or
-- res is unzonked/unflattened. Thus this function, which handles this
-- corner case.
- eqFunTy :: RnEnv2 -> Type -> Type -> Type -> Bool
+ eqFunTy :: RnEnv2 -> Mult -> Type -> Type -> Type -> Bool
-- Last arg is /not/ FunTy
- eqFunTy env arg res ty@(AppTy{}) = get_args ty []
+ eqFunTy env w arg res ty@(AppTy{}) = get_args ty []
where
get_args :: Type -> [Type] -> Bool
get_args (AppTy f x) args = get_args f (x:args)
get_args (CastTy t _) args = get_args t args
get_args (TyConApp tc tys) args
| tc == funTyCon
- , [_, _, arg', res'] <- tys ++ args
- = go env arg arg' && go env res res'
+ , [w', _, _, arg', res'] <- tys ++ args
+ = go env w w' && go env arg arg' && go env res res'
get_args _ _ = False
- eqFunTy _ _ _ _ = False
+ eqFunTy _ _ _ _ _ = False
{- *********************************************************************
* *
@@ -1850,7 +1857,7 @@ isInsolubleOccursCheck eq_rel tv ty
go (AppTy t1 t2) = case eq_rel of -- See Note [AppTy and ReprEq]
NomEq -> go t1 || go t2
ReprEq -> go t1
- go (FunTy _ t1 t2) = go t1 || go t2
+ go (FunTy _ w t1 t2) = go w || go t1 || go t2
go (ForAllTy (Bndr tv' _) inner_ty)
| tv' == tv = False
| otherwise = go (varType tv') || go inner_ty
@@ -2105,8 +2112,9 @@ isAlmostFunctionFree (TyConApp tc args)
| isTypeFamilyTyCon tc = False
| otherwise = all isAlmostFunctionFree args
isAlmostFunctionFree (ForAllTy bndr _) = isAlmostFunctionFree (binderType bndr)
-isAlmostFunctionFree (FunTy _ ty1 ty2) = isAlmostFunctionFree ty1 &&
- isAlmostFunctionFree ty2
+isAlmostFunctionFree (FunTy _ w ty1 ty2) = isAlmostFunctionFree w &&
+ isAlmostFunctionFree ty1 &&
+ isAlmostFunctionFree ty2
isAlmostFunctionFree (LitTy {}) = True
isAlmostFunctionFree (CastTy ty _) = isAlmostFunctionFree ty
isAlmostFunctionFree (CoercionTy {}) = True
@@ -2447,7 +2455,7 @@ sizeType = go
-- size ordering is sound, but why is this better?
-- I came across this when investigating #14010.
go (LitTy {}) = 1
- go (FunTy _ arg res) = go arg + go res + 1
+ go (FunTy _ w arg res) = go w + go arg + go res + 1
go (AppTy fun arg) = go fun + go arg
go (ForAllTy (Bndr tv vis) ty)
| isVisibleArgFlag vis = go (tyVarKind tv) + go ty + 1
diff --git a/compiler/GHC/Tc/Utils/Unify.hs b/compiler/GHC/Tc/Utils/Unify.hs
index efe8301650..a6711abcc1 100644
--- a/compiler/GHC/Tc/Utils/Unify.hs
+++ b/compiler/GHC/Tc/Utils/Unify.hs
@@ -16,6 +16,7 @@ module GHC.Tc.Utils.Unify (
tcWrapResult, tcWrapResultO, tcWrapResultMono,
tcSkolemise, tcSkolemiseScoped, tcSkolemiseET,
tcSubType, tcSubTypeSigma, tcSubTypePat,
+ tcSubMult,
checkConstraints, checkTvConstraints,
buildImplicationFor, buildTvImplication, emitResidualTvConstraint,
@@ -51,6 +52,7 @@ import GHC.Tc.Utils.TcType
import GHC.Tc.Utils.Env
import GHC.Core.Type
import GHC.Core.Coercion
+import GHC.Core.Multiplicity
import GHC.Tc.Types.Evidence
import GHC.Tc.Types.Constraint
import GHC.Core.Predicate
@@ -145,7 +147,7 @@ matchExpectedFunTys :: forall a.
-> UserTypeCtxt
-> Arity
-> ExpRhoType -- Skolemised
- -> ([ExpSigmaType] -> ExpRhoType -> TcM a)
+ -> ([Scaled ExpSigmaType] -> ExpRhoType -> TcM a)
-> TcM (HsWrapper, a)
-- If matchExpectedFunTys n ty = (_, wrap)
-- then wrap : (t1 -> ... -> tn -> ty_r) ~> ty,
@@ -173,11 +175,11 @@ matchExpectedFunTys herald ctx arity orig_ty thing_inside
go acc_arg_tys n ty
| Just ty' <- tcView ty = go acc_arg_tys n ty'
- go acc_arg_tys n (FunTy { ft_af = af, ft_arg = arg_ty, ft_res = res_ty })
+ go acc_arg_tys n (FunTy { ft_mult = mult, ft_af = af, ft_arg = arg_ty, ft_res = res_ty })
= ASSERT( af == VisArg )
- do { (wrap_res, result) <- go (mkCheckExpType arg_ty : acc_arg_tys)
+ do { (wrap_res, result) <- go ((Scaled mult $ mkCheckExpType arg_ty) : acc_arg_tys)
(n-1) res_ty
- ; let fun_wrap = mkWpFun idHsWrapper wrap_res arg_ty res_ty doc
+ ; let fun_wrap = mkWpFun idHsWrapper wrap_res (Scaled mult arg_ty) res_ty doc
; return ( fun_wrap, result ) }
where
doc = text "When inferring the argument type of a function with type" <+>
@@ -209,25 +211,25 @@ matchExpectedFunTys herald ctx arity orig_ty thing_inside
defer acc_arg_tys n (mkCheckExpType ty)
------------
- defer :: [ExpSigmaType] -> Arity -> ExpRhoType -> TcM (HsWrapper, a)
+ defer :: [Scaled ExpSigmaType] -> Arity -> ExpRhoType -> TcM (HsWrapper, a)
defer acc_arg_tys n fun_ty
= do { more_arg_tys <- replicateM n newInferExpType
; res_ty <- newInferExpType
- ; result <- thing_inside (reverse acc_arg_tys ++ more_arg_tys) res_ty
+ ; result <- thing_inside (reverse acc_arg_tys ++ (map unrestricted more_arg_tys)) res_ty
; more_arg_tys <- mapM readExpType more_arg_tys
; res_ty <- readExpType res_ty
- ; let unif_fun_ty = mkVisFunTys more_arg_tys res_ty
+ ; let unif_fun_ty = mkVisFunTysMany more_arg_tys res_ty
; wrap <- tcSubType AppOrigin ctx unif_fun_ty fun_ty
-- Not a good origin at all :-(
; return (wrap, result) }
------------
- mk_ctxt :: [ExpSigmaType] -> TcType -> TidyEnv -> TcM (TidyEnv, MsgDoc)
+ mk_ctxt :: [Scaled ExpSigmaType] -> TcType -> TidyEnv -> TcM (TidyEnv, MsgDoc)
mk_ctxt arg_tys res_ty env
= do { (env', ty) <- zonkTidyTcType env (mkVisFunTys arg_tys' res_ty)
; return ( env', mk_fun_tys_msg herald ty arity) }
where
- arg_tys' = map (checkingExpType "matchExpectedFunTys") (reverse arg_tys)
+ arg_tys' = map (\(Scaled u v) -> Scaled u (checkingExpType "matchExpectedFunTys" v)) (reverse arg_tys)
-- this is safe b/c we're called from "go"
-- Like 'matchExpectedFunTys', but used when you have an "actual" type,
@@ -237,7 +239,7 @@ matchActualFunTysRho :: SDoc -- See Note [Herald for matchExpectedFunTys]
-> Maybe (HsExpr GhcRn) -- the thing with type TcSigmaType
-> Arity
-> TcSigmaType
- -> TcM (HsWrapper, [TcSigmaType], TcRhoType)
+ -> TcM (HsWrapper, [Scaled TcSigmaType], TcRhoType)
-- If matchActualFunTysRho n ty = (wrap, [t1,..,tn], res_ty)
-- then wrap : ty ~> (t1 -> ... -> tn -> res_ty)
-- and res_ty is a RhoType
@@ -266,12 +268,12 @@ matchActualFunTySigma
:: SDoc -- See Note [Herald for matchExpectedFunTys]
-> CtOrigin
-> Maybe (HsExpr GhcRn) -- The thing with type TcSigmaType
- -> (Arity, [TcSigmaType]) -- Total number of value args in the call, and
+ -> (Arity, [Scaled TcSigmaType]) -- Total number of value args in the call, and
-- types of values args to which function has
-- been applied already (reversed)
-- Both are used only for error messages)
-> TcSigmaType -- Type to analyse
- -> TcM (HsWrapper, TcSigmaType, TcSigmaType)
+ -> TcM (HsWrapper, Scaled TcSigmaType, TcSigmaType)
-- See Note [matchActualFunTys error handling] for all these arguments
-- If (wrap, arg_ty, res_ty) = matchActualFunTySigma ... fun_ty
@@ -295,7 +297,7 @@ matchActualFunTySigma herald ct_orig mb_thing err_info fun_ty
where
go :: TcSigmaType -- The remainder of the type as we're processing
- -> TcM (HsWrapper, TcSigmaType, TcSigmaType)
+ -> TcM (HsWrapper, Scaled TcSigmaType, TcSigmaType)
go ty | Just ty' <- tcView ty = go ty'
go ty
@@ -306,9 +308,9 @@ matchActualFunTySigma herald ct_orig mb_thing err_info fun_ty
where
(tvs, theta, _) = tcSplitSigmaTy ty
- go (FunTy { ft_af = af, ft_arg = arg_ty, ft_res = res_ty })
+ go (FunTy { ft_af = af, ft_mult = w, ft_arg = arg_ty, ft_res = res_ty })
= ASSERT( af == VisArg )
- return (idHsWrapper, arg_ty, res_ty)
+ return (idHsWrapper, Scaled w arg_ty, res_ty)
go ty@(TyVarTy tv)
| isMetaTyVar tv
@@ -338,9 +340,9 @@ matchActualFunTySigma herald ct_orig mb_thing err_info fun_ty
defer fun_ty
= do { arg_ty <- newOpenFlexiTyVarTy
; res_ty <- newOpenFlexiTyVarTy
- ; let unif_fun_ty = mkVisFunTy arg_ty res_ty
+ ; let unif_fun_ty = mkVisFunTyMany arg_ty res_ty
; co <- unifyType mb_thing fun_ty unif_fun_ty
- ; return (mkWpCastN co, arg_ty, res_ty) }
+ ; return (mkWpCastN co, unrestricted arg_ty, res_ty) }
------------
mk_ctxt :: TcType -> TidyEnv -> TcM (TidyEnv, MsgDoc)
@@ -405,7 +407,7 @@ matchExpectedTyConApp :: TyCon -- T :: forall kv1 ... kvm. k1 ->
-- Postcondition: (T k1 k2 k3 a b c) is well-kinded
matchExpectedTyConApp tc orig_ty
- = ASSERT(tc /= funTyCon) go orig_ty
+ = ASSERT(not $ isFunTyCon tc) go orig_ty
where
go ty
| Just ty' <- tcView ty
@@ -475,7 +477,7 @@ matchExpectedAppTy orig_ty
; return (co, (ty1, ty2)) }
orig_kind = tcTypeKind orig_ty
- kind1 = mkVisFunTy liftedTypeKind orig_kind
+ kind1 = mkVisFunTyMany liftedTypeKind orig_kind
kind2 = liftedTypeKind -- m :: * -> k
-- arg type :: *
@@ -723,6 +725,48 @@ to a UserTypeCtxt of GenSigCtxt. Why?
-}
+-- Note [tcSubMult's wrapper]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~
+-- There is no notion of multiplicity coercion in Core, therefore the wrapper
+-- returned by tcSubMult (and derived function such as tcCheckUsage and
+-- checkManyPattern) is quite unlike any other wrapper: it checks whether the
+-- coercion produced by the constraint solver is trivial and disappears (it
+-- produces a type error is the constraint is not trivial). See [Checking
+-- multiplicity coercions] in TcEvidence.
+--
+-- This wrapper need to be placed in the term, otherwise checking of the
+-- eventual coercion won't be triggered during desuraging. But it can be put
+-- anywhere, since it doesn't affect the desugared code.
+--
+-- Why do we check this in the desugarer? It's a convenient place, since it's
+-- right after all the constraints are solved. We need the constraints to be
+-- solved to check whether they are trivial or not. Plus there are precedent for
+-- type errors during desuraging (such as the levity polymorphism
+-- restriction). An alternative would be to have a kind of constraints which can
+-- only produce trivial evidence, then this check would happen in the constraint
+-- solver.
+tcSubMult :: CtOrigin -> Mult -> Mult -> TcM HsWrapper
+tcSubMult origin (MultMul w1 w2) w_expected =
+ do { w1 <- tcSubMult origin w1 w_expected
+ ; w2 <- tcSubMult origin w2 w_expected
+ ; return (w1 <.> w2) }
+ -- Currently, we consider p*q and sup p q to be equal. Therefore, p*q <= r is
+ -- equivalent to p <= r and q <= r. For other cases, we approximate p <= q by p
+ -- ~ q. This is not complete, but it's sound. See also Note [Overapproximating
+ -- multiplicities] in Multiplicity.
+tcSubMult origin w_actual w_expected =
+ case submult w_actual w_expected of
+ Submult -> return WpHole
+ Unknown -> tcEqMult origin w_actual w_expected
+
+tcEqMult :: CtOrigin -> Mult -> Mult -> TcM HsWrapper
+tcEqMult origin w_actual w_expected = do
+ {
+ -- Note that here we do not call to `submult`, so we check
+ -- for strict equality.
+ ; coercion <- uType TypeLevel origin w_actual w_expected
+ ; return $ if isReflCo coercion then WpHole else WpMultCoercion coercion }
+
{- **********************************************************************
%* *
ExpType functions: tcInfer, instantiateAndFillInferResult
@@ -1308,10 +1352,11 @@ uType t_or_k origin orig_ty1 orig_ty2
| Just ty2' <- tcView ty2 = go ty1 ty2'
-- Functions (or predicate functions) just check the two parts
- go (FunTy _ fun1 arg1) (FunTy _ fun2 arg2)
+ go (FunTy _ w1 fun1 arg1) (FunTy _ w2 fun2 arg2)
= do { co_l <- uType t_or_k origin fun1 fun2
; co_r <- uType t_or_k origin arg1 arg2
- ; return $ mkFunCo Nominal co_l co_r }
+ ; co_w <- uType t_or_k origin w1 w2
+ ; return $ mkFunCo Nominal co_w co_l co_r }
-- Always defer if a type synonym family (type function)
-- is involved. (Data families behave rigidly.)
@@ -1975,9 +2020,9 @@ matchExpectedFunKind hs_ty n k = go n k
Indirect fun_kind -> go n fun_kind
Flexi -> defer n k }
- go n (FunTy _ arg res)
+ go n (FunTy _ w arg res)
= do { co <- go (n-1) res
- ; return (mkTcFunCo Nominal (mkTcNomReflCo arg) co) }
+ ; return (mkTcFunCo Nominal (mkTcNomReflCo w) (mkTcNomReflCo arg) co) }
go n other
= defer n other
@@ -1985,7 +2030,7 @@ matchExpectedFunKind hs_ty n k = go n k
defer n k
= do { arg_kinds <- newMetaKindVars n
; res_kind <- newMetaKindVar
- ; let new_fun = mkVisFunTys arg_kinds res_kind
+ ; let new_fun = mkVisFunTysMany arg_kinds res_kind
origin = TypeEqOrigin { uo_actual = k
, uo_expected = new_fun
, uo_thing = Just (ppr hs_ty)
@@ -2156,10 +2201,10 @@ preCheck dflags ty_fam_ok tv ty
| bad_tc tc = MTVU_Bad
| otherwise = mapM fast_check tys >> ok
fast_check (LitTy {}) = ok
- fast_check (FunTy{ft_af = af, ft_arg = a, ft_res = r})
+ fast_check (FunTy{ft_af = af, ft_mult = w, ft_arg = a, ft_res = r})
| InvisArg <- af
, not impredicative_ok = MTVU_Bad
- | otherwise = fast_check a >> fast_check r
+ | otherwise = fast_check w >> fast_check a >> fast_check r
fast_check (AppTy fun arg) = fast_check fun >> fast_check arg
fast_check (CastTy ty co) = fast_check ty >> fast_check_co co
fast_check (CoercionTy co) = fast_check_co co
diff --git a/compiler/GHC/Tc/Utils/Unify.hs-boot b/compiler/GHC/Tc/Utils/Unify.hs-boot
index 311dbf66aa..a54107fe07 100644
--- a/compiler/GHC/Tc/Utils/Unify.hs-boot
+++ b/compiler/GHC/Tc/Utils/Unify.hs-boot
@@ -3,9 +3,10 @@ module GHC.Tc.Utils.Unify where
import GHC.Prelude
import GHC.Tc.Utils.TcType ( TcTauType )
import GHC.Tc.Types ( TcM )
-import GHC.Tc.Types.Evidence ( TcCoercion )
+import GHC.Tc.Types.Evidence ( TcCoercion, HsWrapper )
+import GHC.Tc.Types.Origin ( CtOrigin )
import GHC.Hs.Expr ( HsExpr )
-import GHC.Hs.Type ( HsType )
+import GHC.Hs.Type ( HsType, Mult )
import GHC.Hs.Extension ( GhcRn )
-- This boot file exists only to tie the knot between
@@ -13,3 +14,5 @@ import GHC.Hs.Extension ( GhcRn )
unifyType :: Maybe (HsExpr GhcRn) -> TcTauType -> TcTauType -> TcM TcCoercion
unifyKind :: Maybe (HsType GhcRn) -> TcTauType -> TcTauType -> TcM TcCoercion
+
+tcSubMult :: CtOrigin -> Mult -> Mult -> TcM HsWrapper
diff --git a/compiler/GHC/Tc/Utils/Zonk.hs b/compiler/GHC/Tc/Utils/Zonk.hs
index 4372a39e9d..05eb4d9ba4 100644
--- a/compiler/GHC/Tc/Utils/Zonk.hs
+++ b/compiler/GHC/Tc/Utils/Zonk.hs
@@ -36,7 +36,7 @@ module GHC.Tc.Utils.Zonk (
zonkTyVarBinders, zonkTyVarBindersX, zonkTyVarBinderX,
zonkTyBndrs, zonkTyBndrsX,
zonkTcTypeToType, zonkTcTypeToTypeX,
- zonkTcTypesToTypes, zonkTcTypesToTypesX,
+ zonkTcTypesToTypes, zonkTcTypesToTypesX, zonkScaledTcTypesToTypesX,
zonkTyVarOcc,
zonkCoToCo,
zonkEvBinds, zonkTcEvBinds,
@@ -80,6 +80,7 @@ import GHC.Data.Bag
import GHC.Utils.Outputable
import GHC.Utils.Misc
import GHC.Types.Unique.FM
+import GHC.Core.Multiplicity
import GHC.Core
import {-# SOURCE #-} GHC.Tc.Gen.Splice (runTopSplice)
@@ -372,11 +373,11 @@ zonkIdOccs env ids = map (zonkIdOcc env) ids
-- to its final form. The TyVarEnv give
zonkIdBndr :: ZonkEnv -> TcId -> TcM Id
zonkIdBndr env v
- = do ty' <- zonkTcTypeToTypeX env (idType v)
+ = do Scaled w' ty' <- zonkScaledTcTypeToTypeX env (idScaledType v)
ensureNotLevPoly ty'
(text "In the type of binder" <+> quotes (ppr v))
- return (modifyIdInfo (`setLevityInfoWithType` ty') (setIdType v ty'))
+ return (modifyIdInfo (`setLevityInfoWithType` ty') (setIdMult (setIdType v ty') w'))
zonkIdBndrs :: ZonkEnv -> [TcId] -> TcM [Id]
zonkIdBndrs env ids = mapM (zonkIdBndr env) ids
@@ -401,11 +402,7 @@ zonkEvBndr :: ZonkEnv -> EvVar -> TcM EvVar
-- Works for dictionaries and coercions
-- Does not extend the ZonkEnv
zonkEvBndr env var
- = do { let var_ty = varType var
- ; ty <-
- {-# SCC "zonkEvBndr_zonkTcTypeToType" #-}
- zonkTcTypeToTypeX env var_ty
- ; return (setVarType var ty) }
+ = updateVarTypeAndMultM ({-# SCC "zonkEvBndr_zonkTcTypeToType" #-} zonkTcTypeToTypeX env) var
{-
zonkEvVarOcc :: ZonkEnv -> EvVar -> TcM EvTerm
@@ -583,10 +580,10 @@ zonk_bind env (AbsBinds { abs_tvs = tyvars, abs_ev_vars = evs
where
zonk_val_bind env lbind
| has_sig
- , (L loc bind@(FunBind { fun_id = L mloc mono_id
+ , (L loc bind@(FunBind { fun_id = (L mloc mono_id)
, fun_matches = ms
, fun_ext = co_fn })) <- lbind
- = do { new_mono_id <- updateVarTypeM (zonkTcTypeToTypeX env) mono_id
+ = do { new_mono_id <- updateVarTypeAndMultM (zonkTcTypeToTypeX env) mono_id
-- Specifically /not/ zonkIdBndr; we do not
-- want to complain about a levity-polymorphic binder
; (env', new_co_fn) <- zonkCoFn env co_fn
@@ -674,7 +671,7 @@ zonkMatchGroup env zBody (MG { mg_alts = L l ms
, mg_ext = MatchGroupTc arg_tys res_ty
, mg_origin = origin })
= do { ms' <- mapM (zonkMatch env zBody) ms
- ; arg_tys' <- zonkTcTypesToTypesX env arg_tys
+ ; arg_tys' <- zonkScaledTcTypesToTypesX env arg_tys
; res_ty' <- zonkTcTypeToTypeX env res_ty
; return (MG { mg_alts = L l ms'
, mg_ext = MatchGroupTc arg_tys' res_ty'
@@ -1043,7 +1040,7 @@ zonkCoFn env (WpCompose c1 c2) = do { (env1, c1') <- zonkCoFn env c1
; return (env2, WpCompose c1' c2') }
zonkCoFn env (WpFun c1 c2 t1 d) = do { (env1, c1') <- zonkCoFn env c1
; (env2, c2') <- zonkCoFn env1 c2
- ; t1' <- zonkTcTypeToTypeX env2 t1
+ ; t1' <- zonkScaledTcTypeToTypeX env2 t1
; return (env2, WpFun c1' c2' t1' d) }
zonkCoFn env (WpCast co) = do { co' <- zonkCoToCo env co
; return (env, WpCast co') }
@@ -1058,6 +1055,8 @@ zonkCoFn env (WpTyApp ty) = do { ty' <- zonkTcTypeToTypeX env ty
; return (env, WpTyApp ty') }
zonkCoFn env (WpLet bs) = do { (env1, bs') <- zonkTcEvBinds env bs
; return (env1, WpLet bs') }
+zonkCoFn env (WpMultCoercion co) = do { co' <- zonkCoToCo env co
+ ; return (env, WpMultCoercion co') }
-------------------------------------------------------------------------
zonkOverLit :: ZonkEnv -> HsOverLit GhcTcId -> TcM (HsOverLit GhcTc)
@@ -1199,6 +1198,7 @@ zonkStmt env _ (LetStmt x (L l binds))
zonkStmt env zBody (BindStmt xbs pat body)
= do { (env1, new_bind) <- zonkSyntaxExpr env (xbstc_bindOp xbs)
+ ; new_w <- zonkTcTypeToTypeX env1 (xbstc_boundResultMult xbs)
; new_bind_ty <- zonkTcTypeToTypeX env1 (xbstc_boundResultType xbs)
; new_body <- zBody env1 body
; (env2, new_pat) <- zonkPat env1 pat
@@ -1209,6 +1209,7 @@ zonkStmt env zBody (BindStmt xbs pat body)
, BindStmt (XBindStmtTc
{ xbstc_bindOp = new_bind
, xbstc_boundResultType = new_bind_ty
+ , xbstc_boundResultMult = new_w
, xbstc_failOp = new_fail
})
new_pat new_body) }
@@ -1617,10 +1618,11 @@ zonkEvTypeable env (EvTypeableTyApp t1 t2)
= do { t1' <- zonkEvTerm env t1
; t2' <- zonkEvTerm env t2
; return (EvTypeableTyApp t1' t2') }
-zonkEvTypeable env (EvTypeableTrFun t1 t2)
- = do { t1' <- zonkEvTerm env t1
+zonkEvTypeable env (EvTypeableTrFun tm t1 t2)
+ = do { tm' <- zonkEvTerm env tm
+ ; t1' <- zonkEvTerm env t1
; t2' <- zonkEvTerm env t2
- ; return (EvTypeableTrFun t1' t2') }
+ ; return (EvTypeableTrFun tm' t1' t2') }
zonkEvTypeable env (EvTypeableTyLit t1)
= do { t1' <- zonkEvTerm env t1
; return (EvTypeableTyLit t1') }
@@ -1805,6 +1807,9 @@ commitFlexi flexi tv zonked_kind
| isRuntimeRepTy zonked_kind
-> do { traceTc "Defaulting flexi tyvar to LiftedRep:" (pprTyVar tv)
; return liftedRepTy }
+ | isMultiplicityTy zonked_kind
+ -> do { traceTc "Defaulting flexi tyvar to Many:" (pprTyVar tv)
+ ; return manyDataConTy }
| otherwise
-> do { traceTc "Defaulting flexi tyvar to Any:" (pprTyVar tv)
; return (anyTypeOfKind zonked_kind) }
@@ -1871,12 +1876,20 @@ zonkTcTypeToType ty = initZonkEnv $ \ ze -> zonkTcTypeToTypeX ze ty
zonkTcTypesToTypes :: [TcType] -> TcM [Type]
zonkTcTypesToTypes tys = initZonkEnv $ \ ze -> zonkTcTypesToTypesX ze tys
+zonkScaledTcTypeToTypeX :: ZonkEnv -> Scaled TcType -> TcM (Scaled TcType)
+zonkScaledTcTypeToTypeX env (Scaled m ty) = Scaled <$> zonkTcTypeToTypeX env m
+ <*> zonkTcTypeToTypeX env ty
+
zonkTcTypeToTypeX :: ZonkEnv -> TcType -> TcM Type
zonkTcTypesToTypesX :: ZonkEnv -> [TcType] -> TcM [Type]
zonkCoToCo :: ZonkEnv -> Coercion -> TcM Coercion
(zonkTcTypeToTypeX, zonkTcTypesToTypesX, zonkCoToCo, _)
= mapTyCoX zonk_tycomapper
+zonkScaledTcTypesToTypesX :: ZonkEnv -> [Scaled TcType] -> TcM [Scaled Type]
+zonkScaledTcTypesToTypesX env scaled_tys =
+ mapM (zonkScaledTcTypeToTypeX env) scaled_tys
+
zonkTcMethInfoToMethInfoX :: ZonkEnv -> TcMethInfo -> TcM MethInfo
zonkTcMethInfoToMethInfoX ze (name, ty, gdm_spec)
= do { ty' <- zonkTcTypeToTypeX ze ty
diff --git a/compiler/GHC/Tc/Validity.hs b/compiler/GHC/Tc/Validity.hs
index 32dfc16ea3..c9eec9838f 100644
--- a/compiler/GHC/Tc/Validity.hs
+++ b/compiler/GHC/Tc/Validity.hs
@@ -34,7 +34,7 @@ import GHC.Core.TyCo.FVs
import GHC.Core.TyCo.Rep
import GHC.Core.TyCo.Ppr
import GHC.Tc.Utils.TcType hiding ( sizeType, sizeTypes )
-import GHC.Builtin.Types ( heqTyConName, eqTyConName, coercibleTyConName )
+import GHC.Builtin.Types ( heqTyConName, eqTyConName, coercibleTyConName, manyDataConTy )
import GHC.Builtin.Names
import GHC.Core.Type
import GHC.Core.Unify ( tcMatchTyX_BM, BindFlag(..) )
@@ -711,7 +711,7 @@ check_type ve@(ValidityEnv{ ve_tidy_env = env, ve_ctxt = ctxt
(theta, tau) = tcSplitPhiTy phi
(env', tvbs') = tidyTyCoVarBinders env tvbs
-check_type (ve@ValidityEnv{ve_rank = rank}) (FunTy _ arg_ty res_ty)
+check_type (ve@ValidityEnv{ve_rank = rank}) (FunTy _ _ arg_ty res_ty)
= do { check_type (ve{ve_rank = arg_rank}) arg_ty
; check_type (ve{ve_rank = res_rank}) res_ty }
where
@@ -1635,17 +1635,24 @@ tcInstHeadTyNotSynonym :: Type -> Bool
tcInstHeadTyNotSynonym ty
= case ty of -- Do not use splitTyConApp,
-- because that expands synonyms!
- TyConApp tc _ -> not (isTypeSynonymTyCon tc)
+ TyConApp tc _ -> not (isTypeSynonymTyCon tc) || tc == unrestrictedFunTyCon
+ -- Allow (->), e.g. instance Category (->),
+ -- even though it's a type synonym for FUN 'Many
_ -> True
tcInstHeadTyAppAllTyVars :: Type -> Bool
-- Used in Haskell-98 mode, for the argument types of an instance head
-- These must be a constructor applied to type variable arguments
-- or a type-level literal.
--- But we allow kind instantiations.
+-- But we allow
+-- 1) kind instantiations
+-- 2) the type (->) = FUN 'Many, even though it's not in this form.
tcInstHeadTyAppAllTyVars ty
| Just (tc, tys) <- tcSplitTyConApp_maybe (dropCasts ty)
- = ok (filterOutInvisibleTypes tc tys) -- avoid kinds
+ = let tys' = filterOutInvisibleTypes tc tys -- avoid kinds
+ tys'' | tc == funTyCon, tys_h:tys_t <- tys', tys_h `eqType` manyDataConTy = tys_t
+ | otherwise = tys'
+ in ok tys''
| LitTy _ <- ty = True -- accept type literals (#13833)
| otherwise
= False
@@ -1663,7 +1670,7 @@ dropCasts :: Type -> Type
-- To consider: drop only HoleCo casts
dropCasts (CastTy ty _) = dropCasts ty
dropCasts (AppTy t1 t2) = mkAppTy (dropCasts t1) (dropCasts t2)
-dropCasts ty@(FunTy _ t1 t2) = ty { ft_arg = dropCasts t1, ft_res = dropCasts t2 }
+dropCasts ty@(FunTy _ w t1 t2) = ty { ft_mult = dropCasts w, ft_arg = dropCasts t1, ft_res = dropCasts t2 }
dropCasts (TyConApp tc tys) = mkTyConApp tc (map dropCasts tys)
dropCasts (ForAllTy b ty) = ForAllTy (dropCastsB b) (dropCasts ty)
dropCasts ty = ty -- LitTy, TyVarTy, CoercionTy
@@ -2831,7 +2838,7 @@ fvType (TyVarTy tv) = [tv]
fvType (TyConApp _ tys) = fvTypes tys
fvType (LitTy {}) = []
fvType (AppTy fun arg) = fvType fun ++ fvType arg
-fvType (FunTy _ arg res) = fvType arg ++ fvType res
+fvType (FunTy _ w arg res) = fvType w ++ fvType arg ++ fvType res
fvType (ForAllTy (Bndr tv _) ty)
= fvType (tyVarKind tv) ++
filter (/= tv) (fvType ty)
@@ -2848,7 +2855,7 @@ sizeType (TyVarTy {}) = 1
sizeType (TyConApp tc tys) = 1 + sizeTyConAppArgs tc tys
sizeType (LitTy {}) = 1
sizeType (AppTy fun arg) = sizeType fun + sizeType arg
-sizeType (FunTy _ arg res) = sizeType arg + sizeType res + 1
+sizeType (FunTy _ w arg res) = sizeType w + sizeType arg + sizeType res + 1
sizeType (ForAllTy _ ty) = sizeType ty
sizeType (CastTy ty _) = sizeType ty
sizeType (CoercionTy _) = 0