summaryrefslogtreecommitdiff
path: root/compiler/GHC/Tc/Instance
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/Instance
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/Instance')
-rw-r--r--compiler/GHC/Tc/Instance/Class.hs13
-rw-r--r--compiler/GHC/Tc/Instance/Typeable.hs13
2 files changed, 15 insertions, 11 deletions
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