summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsheaf <sam.derbyshire@gmail.com>2021-06-09 20:43:42 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-06-10 13:54:05 -0400
commit472c2bf003e9f3bb93b82265f2a0a7124f944421 (patch)
tree74767fe0b48521254b22350d4b1f34a3957adc06
parent61c51c00b6e12e309bc5643e89330b93d86f5449 (diff)
downloadhaskell-472c2bf003e9f3bb93b82265f2a0a7124f944421.tar.gz
Reword: representation instead of levity
fixes #19756, updates haddock submodule
-rw-r--r--compiler/GHC/Builtin/PrimOps.hs22
-rw-r--r--compiler/GHC/Builtin/Types.hs2
-rw-r--r--compiler/GHC/Builtin/primops.txt.pp7
-rw-r--r--compiler/GHC/Core.hs28
-rw-r--r--compiler/GHC/Core/Lint.hs39
-rw-r--r--compiler/GHC/Core/Opt/Arity.hs4
-rw-r--r--compiler/GHC/Core/Opt/SetLevels.hs4
-rw-r--r--compiler/GHC/Core/Opt/Simplify.hs18
-rw-r--r--compiler/GHC/Core/Opt/Simplify/Utils.hs4
-rw-r--r--compiler/GHC/Core/Opt/WorkWrap/Utils.hs2
-rw-r--r--compiler/GHC/Core/TyCon.hs24
-rw-r--r--compiler/GHC/Core/Type.hs29
-rw-r--r--compiler/GHC/Core/Utils.hs18
-rw-r--r--compiler/GHC/HsToCore.hs6
-rw-r--r--compiler/GHC/HsToCore/Arrows.hs2
-rw-r--r--compiler/GHC/HsToCore/Binds.hs4
-rw-r--r--compiler/GHC/HsToCore/Errors/Ppr.hs9
-rw-r--r--compiler/GHC/HsToCore/Expr.hs75
-rw-r--r--compiler/GHC/HsToCore/Foreign/Call.hs6
-rw-r--r--compiler/GHC/HsToCore/Foreign/Decl.hs4
-rw-r--r--compiler/GHC/HsToCore/ListComp.hs6
-rw-r--r--compiler/GHC/HsToCore/Monad.hs68
-rw-r--r--compiler/GHC/HsToCore/Pmc/Solver.hs2
-rw-r--r--compiler/GHC/HsToCore/Utils.hs8
-rw-r--r--compiler/GHC/Iface/Syntax.hs2
-rw-r--r--compiler/GHC/Iface/Type.hs4
-rw-r--r--compiler/GHC/IfaceToCore.hs2
-rw-r--r--compiler/GHC/Rename/Expr.hs8
-rw-r--r--compiler/GHC/StgToByteCode.hs19
-rw-r--r--compiler/GHC/Tc/Deriv/Utils.hs2
-rw-r--r--compiler/GHC/Tc/Errors/Ppr.hs4
-rw-r--r--compiler/GHC/Tc/Gen/Sig.hs2
-rw-r--r--compiler/GHC/Tc/Module.hs3
-rw-r--r--compiler/GHC/Tc/TyCl.hs18
-rw-r--r--compiler/GHC/Tc/TyCl/Instance.hs2
-rw-r--r--compiler/GHC/Tc/Types/Constraint.hs2
-rw-r--r--compiler/GHC/Tc/Types/Evidence.hs4
-rw-r--r--compiler/GHC/Tc/Utils/TcMType.hs8
-rw-r--r--compiler/GHC/Tc/Utils/Unify.hs2
-rw-r--r--compiler/GHC/Tc/Utils/Zonk.hs9
-rw-r--r--compiler/GHC/Types/Id.hs10
-rw-r--r--compiler/GHC/Types/Id/Info.hs20
-rw-r--r--compiler/GHC/Types/Id/Make.hs32
-rw-r--r--compiler/GHC/Types/RepType.hs4
-rw-r--r--docs/users_guide/exts/linear_types.rst2
-rw-r--r--docs/users_guide/exts/poly_kinds.rst3
-rw-r--r--docs/users_guide/exts/primitives.rst6
-rw-r--r--docs/users_guide/exts/representation_polymorphism.rst (renamed from docs/users_guide/exts/levity_polymorphism.rst)57
-rw-r--r--docs/users_guide/exts/types.rst2
-rw-r--r--libraries/base/GHC/Base.hs2
-rw-r--r--libraries/base/GHC/Conc/Sync.hs2
-rw-r--r--libraries/base/Unsafe/Coerce.hs6
-rw-r--r--libraries/ghc-prim/GHC/Magic.hs4
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs2
-rw-r--r--libraries/template-haskell/Language/Haskell/TH/Syntax.hs8
-rw-r--r--testsuite/tests/codeGen/should_fail/T13233.stderr18
-rw-r--r--testsuite/tests/codeGen/should_fail/T13233_elab.stderr8
-rw-r--r--testsuite/tests/dependent/should_fail/T11473.stderr2
-rw-r--r--testsuite/tests/ghci/should_run/UnboxedTuples/Common.hs-incl2
-rw-r--r--testsuite/tests/ghci/should_run/UnboxedTuples/UnboxedTuples.hs2
-rw-r--r--testsuite/tests/polykinds/T14561.hs2
-rw-r--r--testsuite/tests/polykinds/T14561.stderr9
-rw-r--r--testsuite/tests/th/T19709a.stderr2
-rw-r--r--testsuite/tests/th/T19709b.hs4
-rw-r--r--testsuite/tests/th/T19709b.stderr2
-rw-r--r--testsuite/tests/typecheck/should_fail/LevPolyLet.stderr2
-rw-r--r--testsuite/tests/typecheck/should_fail/T11724.stderr2
-rw-r--r--testsuite/tests/typecheck/should_fail/T12709.stderr8
-rw-r--r--testsuite/tests/typecheck/should_fail/T12973.stderr4
-rw-r--r--testsuite/tests/typecheck/should_fail/T13105.stderr2
-rw-r--r--testsuite/tests/typecheck/should_fail/T13929.stderr8
-rw-r--r--testsuite/tests/typecheck/should_fail/T17021.stderr12
-rw-r--r--testsuite/tests/typecheck/should_fail/T17360.stderr2
-rw-r--r--testsuite/tests/typecheck/should_fail/T17817.stderr9
-rw-r--r--testsuite/tests/typecheck/should_fail/T17817_elab.stderr4
-rw-r--r--testsuite/tests/typecheck/should_fail/T18534.stderr2
-rw-r--r--testsuite/tests/typecheck/should_fail/T19615.stderr2
-rw-r--r--testsuite/tests/typecheck/should_fail/UnliftedNewtypesCoerceFail.stderr9
-rw-r--r--testsuite/tests/typecheck/should_fail/UnliftedNewtypesLevityBinder.stderr9
-rw-r--r--testsuite/tests/typecheck/should_run/EtaExpandLevPoly.hs4
m---------utils/haddock0
81 files changed, 413 insertions, 359 deletions
diff --git a/compiler/GHC/Builtin/PrimOps.hs b/compiler/GHC/Builtin/PrimOps.hs
index 067f0e0d7c..45e570d34c 100644
--- a/compiler/GHC/Builtin/PrimOps.hs
+++ b/compiler/GHC/Builtin/PrimOps.hs
@@ -640,10 +640,9 @@ The Id for the wrapper of a primop can be found using
to link primops; it rather does a rather hacky symbol lookup (see
GHC.ByteCode.Linker.primopToCLabel). TODO: Perhaps this should be changed?
-Note that these wrappers aren't *quite*
-as expressive as their unwrapped breathern in that they may exhibit less levity
-polymorphism. For instance, consider the case of mkWeakNoFinalizer# which has
-type:
+Note that these wrappers aren't *quite* as expressive as their unwrapped
+breathren, in that they may exhibit less representation polymorphism.
+For instance, consider the case of mkWeakNoFinalizer#, which has type:
mkWeakNoFinalizer# :: forall (r :: RuntimeRep) (k :: TYPE r) (v :: Type).
k -> v
@@ -655,10 +654,10 @@ Naively we could generate a wrapper of the form,
mkWeakNoFinalizer# k v s = GHC.Prim.mkWeakNoFinalizer# k v s
-However, this would require that 'k' bind the levity-polymorphic key,
-which is disallowed by our levity polymorphism validity checks (see Note
-[Levity polymorphism invariants] in GHC.Core). Consequently, we give the
-wrapper the simpler, less polymorphic type
+However, this would require that 'k' bind the representation-polymorphic key,
+which is disallowed by our representation polymorphism validity checks
+(see Note [Representation polymorphism invariants] in GHC.Core).
+Consequently, we give the wrapper the simpler, less polymorphic type
mkWeakNoFinalizer# :: forall (k :: Type) (v :: Type).
k -> v
@@ -666,8 +665,8 @@ wrapper the simpler, less polymorphic type
-> (# State# RealWorld, Weak# v #)
This simplification tends to be good enough for GHCi uses given that there are
-few levity polymorphic primops and we do little simplification on interpreted
-code anyways.
+few representation-polymorphic primops, and we do little simplification
+on interpreted code anyways.
TODO: This behavior is actually wrong; a program becomes ill-typed upon
replacing a real primop occurrence with one of its wrapper due to the fact that
@@ -678,7 +677,8 @@ Note [Eta expanding primops]
STG requires that primop applications be saturated. This makes code generation
significantly simpler since otherwise we would need to define a calling
-convention for curried applications that can accommodate levity polymorphism.
+convention for curried applications that can accommodate representation
+polymorphism.
To ensure saturation, CorePrep eta expands expand all primop applications as
described in Note [Eta expansion of hasNoBinding things in CorePrep] in
diff --git a/compiler/GHC/Builtin/Types.hs b/compiler/GHC/Builtin/Types.hs
index dd0c8f4a0b..880aec299c 100644
--- a/compiler/GHC/Builtin/Types.hs
+++ b/compiler/GHC/Builtin/Types.hs
@@ -1415,7 +1415,7 @@ mk_ctuple_class tycon sc_theta sc_sel_ids
* *
********************************************************************* -}
-{- Multiplicity polymorphism is implemented very similarly to levity
+{- Multiplicity polymorphism is implemented very similarly to representation
polymorphism. We write in the multiplicity kind and the One and Many
types which can appear in user programs. These are defined properly in GHC.Types.
diff --git a/compiler/GHC/Builtin/primops.txt.pp b/compiler/GHC/Builtin/primops.txt.pp
index f56687c351..77869cab20 100644
--- a/compiler/GHC/Builtin/primops.txt.pp
+++ b/compiler/GHC/Builtin/primops.txt.pp
@@ -3274,8 +3274,9 @@ primtype FUN m a b
producing outputs of type {\tt b}. The multiplicity of the input is
{\tt m}.
- Note that {\tt FUN m a b} permits levity-polymorphism in both {\tt a} and
- {\tt b}, so that types like {\tt Int\# -> Int\#} can still be well-kinded.
+ Note that {\tt FUN m a b} permits representation polymorphism in both
+ {\tt a} and {\tt b}, so that types like {\tt Int\# -> Int\#} can still be
+ well-kinded.
}
pseudoop "realWorld#"
@@ -3416,7 +3417,7 @@ pseudoop "coerce"
more complicated settings, e.g. converting a list of newtypes to a list of
concrete types.
- This function is runtime-representation polymorphic, but the
+ This function is representation-polymorphic, but the
{\tt RuntimeRep} type argument is marked as {\tt Inferred}, meaning
that it is not available for visible type application. This means
the typechecker will accept {\tt coerce @Int @Age 42}.
diff --git a/compiler/GHC/Core.hs b/compiler/GHC/Core.hs
index f91468baf5..05df4a7a7d 100644
--- a/compiler/GHC/Core.hs
+++ b/compiler/GHC/Core.hs
@@ -178,10 +178,10 @@ These data types are the heart of the compiler
--
-- * Applications: note that the argument may be a 'Type'.
-- See Note [Core let/app invariant]
--- See Note [Levity polymorphism invariants]
+-- See Note [Representation polymorphism invariants]
--
-- * Lambda abstraction
--- See Note [Levity polymorphism invariants]
+-- See Note [Representation polymorphism invariants]
--
-- * Recursive and non recursive @let@s. Operationally
-- this corresponds to allocating a thunk for the things
@@ -189,7 +189,7 @@ These data types are the heart of the compiler
--
-- See Note [Core letrec invariant]
-- See Note [Core let/app invariant]
--- See Note [Levity polymorphism invariants]
+-- See Note [Representation polymorphism invariants]
-- See Note [Core type and coercion invariant]
--
-- * Case expression. Operationally this corresponds to evaluating
@@ -547,24 +547,30 @@ Note [Core case invariants]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
See Note [Case expression invariants]
-Note [Levity polymorphism invariants]
+Note [Representation polymorphism invariants]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The levity-polymorphism invariants are these (as per "Levity Polymorphism",
-PLDI '17):
+The representation polymorphism invariants are described as follows,
+according to the paper "Levity Polymorphism", PLDI '17.
-* The type of a term-binder must not be levity-polymorphic,
+* The type of a term-binder must not be representation-polymorphic,
unless it is a let(rec)-bound join point
(see Note [Invariants on join points])
-* The type of the argument of an App must not be levity-polymorphic.
+* The type of the argument of an App must not be representation-polymorphic.
-A type (t::TYPE r) is "levity polymorphic" if 'r' has any free variables.
+A type (t::TYPE r) is "representation-polymorphic" if 'r' has any free variables,
+and "levity-polymorphic" if it is of the form (t::TYPE (BoxedRep v))
+and 'v' has free variables (levity polymorphism is a special case of
+representation polymorphism).
+Note that the aforementioned "Levity Polymorphism" paper conflates both these
+types of polymorphism; a more precise distinction was only made possible
+with the introduction of BoxedRep.
For example
\(r::RuntimeRep). \(a::TYPE r). \(x::a). e
is illegal because x's type has kind (TYPE r), which has 'r' free.
-See Note [Levity polymorphism checking] in GHC.HsToCore.Monad to see where these
+See Note [Representation polymorphism checking] in GHC.HsToCore.Monad to see where these
invariants are established for user-written code.
Note [Core let goal]
@@ -707,7 +713,7 @@ However, join points have simpler invariants in other ways
ok-for-speculation (i.e. drop the let/app invariant)
e.g. let j :: Int# = factorial x in ...
- 6. A join point can have a levity-polymorphic RHS
+ 6. A join point can have a representation-polymorphic RHS
e.g. let j :: r :: TYPE l = fail void# in ...
This happened in an intermediate program #13394
diff --git a/compiler/GHC/Core/Lint.hs b/compiler/GHC/Core/Lint.hs
index f8dbce7652..45115bfb45 100644
--- a/compiler/GHC/Core/Lint.hs
+++ b/compiler/GHC/Core/Lint.hs
@@ -482,10 +482,10 @@ lintCoreBindings dflags pass local_in_scope binds
, lf_check_levity_poly = check_levity }
-- In the output of the desugarer, before optimisation,
- -- we have eta-expanded data constructors with levity-polymorphic
+ -- we have eta-expanded data constructors with representation-polymorphic
-- bindings; so we switch off the lev-poly checks. The very simple
-- optimiser will beta-reduce them away.
- -- See Note [Checking levity-polymorphic data constructors]
+ -- See Note [Checking representation-polymorphic data constructors]
-- in GHC.HsToCore.Expr.
check_levity = case pass of
CoreDesugar -> False
@@ -563,7 +563,7 @@ lintUnfolding is_compulsory dflags locn var_set expr
vars = nonDetEltsUniqSet var_set
(_warns, errs) = initL dflags (defaultLintFlags dflags) vars $
if is_compulsory
- -- See Note [Checking for levity polymorphism]
+ -- See Note [Checking for representation polymorphism]
then noLPChecks linter
else linter
linter = addLoc (ImportedUnfolding locn) $
@@ -749,7 +749,8 @@ lintIdUnfolding bndr bndr_ty uf
, Just rhs <- maybeUnfoldingTemplate uf
= do { ty <- fst <$> (if isCompulsoryUnfolding uf
then noLPChecks $ lintRhs bndr rhs
- -- See Note [Checking for levity polymorphism]
+ -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ -- See Note [Checking for representation polymorphism]
else lintRhs bndr rhs)
; ensureEqTys bndr_ty ty (mkRhsMsg bndr (text "unfolding") ty) }
lintIdUnfolding _ _ _
@@ -766,18 +767,18 @@ that form a mutually recursive group. Only after a round of
simplification are they unravelled. So we suppress the test for
the desugarer.
-Note [Checking for levity polymorphism]
+Note [Checking for representation polymorphism]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We ordinarily want to check for bad levity polymorphism. See
-Note [Levity polymorphism invariants] in GHC.Core. However, we do *not*
+We ordinarily want to check for bad representation polymorphism. See
+Note [Representation polymorphism invariants] in GHC.Core. However, we do *not*
want to do this in a compulsory unfolding. Compulsory unfoldings arise
only internally, for things like newtype wrappers, dictionaries, and
-(notably) unsafeCoerce#. These might legitimately be levity-polymorphic;
-indeed levity-polyorphic unfoldings are a primary reason for the
+(notably) unsafeCoerce#. These might legitimately be representation-polymorphic;
+indeed representation-polyorphic unfoldings are a primary reason for the
very existence of compulsory unfoldings (we can't compile code for
-the original, levity-poly, binding).
+the original, representation-polymorphic, binding).
-It is vitally important that we do levity-polymorphism checks *after*
+It is vitally important that we do representation polymorphism checks *after*
performing the unfolding, but not beforehand. This is all safe because
we will check any unfolding after it has been unfolded; checking the
unfolding beforehand is merely an optimization, and one that actively
@@ -1186,14 +1187,14 @@ lintCoreArg (fun_ty, ue) (Type arg_ty)
lintCoreArg (fun_ty, fun_ue) arg
= do { (arg_ty, arg_ue) <- markAllJoinsBad $ lintCoreExpr arg
- -- See Note [Levity polymorphism invariants] in GHC.Core
+ -- See Note [Representation polymorphism invariants] in GHC.Core
; flags <- getLintFlags
; when (lf_check_levity_poly flags) $
-- Only do these checks if lf_check_levity_poly is on,
-- because otherwise isUnliftedType panics
do { checkL (not (isTypeLevPoly arg_ty))
- (text "Levity-polymorphic argument:"
+ (text "Representation-polymorphic argument:"
<+> ppr arg <+> dcolon
<+> parens (ppr arg_ty <+> dcolon <+> ppr (typeKind arg_ty)))
@@ -1541,10 +1542,10 @@ lintIdBndr top_lvl bind_site id thing_inside
; checkL (not (isExternalName (Var.varName id)) || is_top_lvl)
(mkNonTopExternalNameMsg id)
- -- See Note [Levity polymorphism invariants] in GHC.Core
+ -- See Note [Representation polymorphism invariants] in GHC.Core
; lintL (isJoinId id || not (lf_check_levity_poly flags)
|| not (isTypeLevPoly id_ty)) $
- text "Levity-polymorphic binder:" <+> ppr id <+> dcolon <+>
+ text "Representation-polymorphic binder:" <+> ppr id <+> dcolon <+>
parens (ppr id_ty <+> dcolon <+> ppr (typeKind id_ty))
-- Check that a join-id is a not-top-level let-binding
@@ -2114,9 +2115,9 @@ lintCoercion co@(UnivCo prov r ty1 ty2)
= return () -- Skip kind checks
| otherwise
= do { checkWarnL (not lev_poly1)
- (report "left-hand type is levity-polymorphic")
+ (report "left-hand type is representation-polymorphic")
; checkWarnL (not lev_poly2)
- (report "right-hand type is levity-polymorphic")
+ (report "right-hand type is representation-polymorphic")
; when (not (lev_poly1 || lev_poly2)) $
do { checkWarnL (reps1 `equalLength` reps2)
(report "between values with different # of reps")
@@ -2551,7 +2552,7 @@ data LintFlags
, lf_check_static_ptrs :: StaticPtrCheck -- ^ See Note [Checking StaticPtrs]
, lf_report_unsat_syns :: Bool -- ^ See Note [Linting type synonym applications]
, lf_check_linearity :: Bool -- ^ See Note [Linting linearity]
- , lf_check_levity_poly :: Bool -- See Note [Checking for levity polymorphism]
+ , lf_check_levity_poly :: Bool -- See Note [Checking for representation polymorphism]
}
-- See Note [Checking StaticPtrs]
@@ -2728,7 +2729,7 @@ setReportUnsat ru thing_inside
let env' = env { le_flags = (le_flags env) { lf_report_unsat_syns = ru } }
in unLintM thing_inside env' errs
--- See Note [Checking for levity polymorphism]
+-- See Note [Checking for representation polymorphism]
noLPChecks :: LintM a -> LintM a
noLPChecks thing_inside
= LintM $ \env errs ->
diff --git a/compiler/GHC/Core/Opt/Arity.hs b/compiler/GHC/Core/Opt/Arity.hs
index 9985a14f0e..021af2d503 100644
--- a/compiler/GHC/Core/Opt/Arity.hs
+++ b/compiler/GHC/Core/Opt/Arity.hs
@@ -1526,7 +1526,7 @@ mkEtaWW orig_oss ppr_orig_expr in_scope orig_ty
----------- Function types (t1 -> t2)
| Just (mult, arg_ty, res_ty) <- splitFunTy_maybe ty
, not (isTypeLevPoly arg_ty)
- -- See Note [Levity polymorphism invariants] in GHC.Core
+ -- See Note [Representation polymorphism invariants] in GHC.Core
-- See also test case typecheck/should_run/EtaExpandLevPoly
, (subst', eta_id) <- freshEtaId n subst (Scaled mult arg_ty)
@@ -1551,7 +1551,7 @@ mkEtaWW orig_oss ppr_orig_expr in_scope orig_ty
| otherwise -- We have an expression of arity > 0,
-- but its type isn't a function, or a binder
- -- is levity-polymorphic
+ -- is representation-polymorphic
= warnPprTrace True ((ppr orig_oss <+> ppr orig_ty) $$ ppr_orig_expr)
(getTCvInScope subst, reverse eis)
-- This *can* legitimately happen:
diff --git a/compiler/GHC/Core/Opt/SetLevels.hs b/compiler/GHC/Core/Opt/SetLevels.hs
index ca74c65ef2..b1298c6b50 100644
--- a/compiler/GHC/Core/Opt/SetLevels.hs
+++ b/compiler/GHC/Core/Opt/SetLevels.hs
@@ -666,8 +666,8 @@ lvlMFE env strict_ctxt ann_expr
|| hasFreeJoin env fvs -- If there is a free join, don't float
-- See Note [Free join points]
|| isExprLevPoly expr
- -- We can't let-bind levity polymorphic expressions
- -- See Note [Levity polymorphism invariants] in GHC.Core
+ -- We can't let-bind representation-polymorphic expressions
+ -- See Note [Representation polymorphism invariants] in GHC.Core
|| notWorthFloating expr abs_vars
|| not float_me
= -- Don't float it out
diff --git a/compiler/GHC/Core/Opt/Simplify.hs b/compiler/GHC/Core/Opt/Simplify.hs
index b799c1df59..be8b72ace4 100644
--- a/compiler/GHC/Core/Opt/Simplify.hs
+++ b/compiler/GHC/Core/Opt/Simplify.hs
@@ -425,10 +425,10 @@ simplNonRecX env bndr new_rhs
; completeNonRecX NotTopLevel env' (isStrictId bndr') bndr bndr' new_rhs }
-- NotTopLevel: simplNonRecX is only used for NotTopLevel things
--
- -- isStrictId: use bndr' because in a levity-polymorphic setting
- -- the InId bndr might have a levity-polymorphic type, which
- -- which isStrictId doesn't expect
- -- c.f. Note [Dark corner with levity polymorphism]
+ -- isStrictId: use bndr' because in a representation-polymorphic
+ -- setting, the InId bndr might have a representation-polymorphic
+ -- type, which isStrictId doesn't expect
+ -- c.f. Note [Dark corner with representation polymorphism]
--------------------------
completeNonRecX :: TopLevelFlag -> SimplEnv
@@ -1484,7 +1484,7 @@ simplCast env body co0 cont0
levity_ok MRefl = True
levity_ok (MCo co) = not $ isTypeLevPoly $ coercionRKind co
-- Without this check, we get a lev-poly arg
- -- See Note [Levity polymorphism invariants] in GHC.Core
+ -- See Note [Representation polymorphism invariants] in GHC.Core
-- test: typecheck/should_run/EtaExpandLevPoly
simplArg :: SimplEnv -> DupFlag -> StaticEnv -> CoreExpr
@@ -1593,7 +1593,7 @@ simplNonRecE env bndr (rhs, rhs_se) (bndrs, body) cont
= do { (env1, bndr1) <- simplNonRecBndr env bndr
-- Deal with strict bindings
- -- See Note [Dark corner with levity polymorphism]
+ -- See Note [Dark corner with representation polymorphism]
; if isStrictId bndr1 && sm_case_case (getMode env)
then simplExprF (rhs_se `setInScopeFromE` env) rhs
(StrictBind { sc_bndr = bndr, sc_bndrs = bndrs, sc_body = body
@@ -1625,17 +1625,17 @@ simplRecE env pairs body cont
; (floats2, expr') <- simplExprF env2 body cont
; return (floats1 `addFloats` floats2, expr') }
-{- Note [Dark corner with levity polymorphism]
+{- Note [Dark corner with representation polymorphism]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In `simplNonRecE`, the call to `isStrictId` will fail if the binder
-has a levity-polymorphic type, of kind (TYPE r). So we are careful to
+has a representation-polymorphic type, of kind (TYPE r). So we are careful to
call `isStrictId` on the OutId, not the InId, in case we have
((\(r::RuntimeRep) \(x::Type r). blah) Lifted arg)
That will lead to `simplNonRecE env (x::Type r) arg`, and we can't tell
if x is lifted or unlifted from that.
We only get such redexes from the compulsory inlining of a wired-in,
-levity-polymorphic function like `rightSection` (see
+representation-polymorphic function like `rightSection` (see
GHC.Types.Id.Make). Mind you, SimpleOpt should probably have inlined
such compulsory inlinings already, but belt and braces does no harm.
diff --git a/compiler/GHC/Core/Opt/Simplify/Utils.hs b/compiler/GHC/Core/Opt/Simplify/Utils.hs
index 9bf26f54d8..085ba41dbd 100644
--- a/compiler/GHC/Core/Opt/Simplify/Utils.hs
+++ b/compiler/GHC/Core/Opt/Simplify/Utils.hs
@@ -587,8 +587,8 @@ mkArgInfo env fun rules n_val_args call_cont
Just False -> strictifyDmd dmd
_ -> dmd
= dmd' : add_type_strictness fun_ty' rest_dmds
- -- If the type is levity-polymorphic, we can't know whether it's
- -- strict. isLiftedType_maybe will return Just False only when
+ -- If the type is representation-polymorphic, we can't know whether
+ -- it's strict. isLiftedType_maybe will return Just False only when
-- we're sure the type is unlifted.
| otherwise
diff --git a/compiler/GHC/Core/Opt/WorkWrap/Utils.hs b/compiler/GHC/Core/Opt/WorkWrap/Utils.hs
index 8416718c99..878bcdd068 100644
--- a/compiler/GHC/Core/Opt/WorkWrap/Utils.hs
+++ b/compiler/GHC/Core/Opt/WorkWrap/Utils.hs
@@ -334,7 +334,7 @@ mkWorkerArgs wrap_id fun_to_thunk args res_ty
-- Might the result be lifted?
-- False => definitely lifted
-- True => might be unlifted
- -- We may encounter a levity-polymorphic result, in which case we
+ -- We may encounter a representation-polymorphic result, in which case we
-- conservatively assume that we have laziness that needs
-- preservation. See #15186.
might_be_unlifted = case isLiftedType_maybe res_ty of
diff --git a/compiler/GHC/Core/TyCon.hs b/compiler/GHC/Core/TyCon.hs
index 675206b1a7..512ac4737c 100644
--- a/compiler/GHC/Core/TyCon.hs
+++ b/compiler/GHC/Core/TyCon.hs
@@ -390,7 +390,7 @@ These extra tyvars (q and r) cause some delicate processing around tuples,
where we need to manually insert RuntimeRep arguments.
The same situation happens with unboxed sums: each alternative
has its own RuntimeRep.
-For boxed tuples, there is no levity polymorphism, and therefore
+For boxed tuples, there is no representation polymorphism, and therefore
we add RuntimeReps only for the unboxed version.
Type constructor (no kind arguments)
@@ -1085,15 +1085,16 @@ data AlgTyConRhs
-- Watch out! If any newtypes become transparent
-- again check #1072.
nt_lev_poly :: Bool
- -- 'True' if the newtype can be levity polymorphic when
- -- fully applied to its arguments, 'False' otherwise.
+ -- 'True' if the newtype can be
+ -- representation-polymorphic when fully applied to its
+ -- arguments, 'False' otherwise.
-- This can only ever be 'True' with UnliftedNewtypes.
--
-- Invariant: nt_lev_poly nt = isTypeLevPoly (nt_rhs nt)
--
-- This is cached to make it cheaper to check if a
- -- variable binding is levity polymorphic, as used by
- -- isTcLevPoly.
+ -- variable binding is representation-polymorphic,
+ -- as used by isTcLevPoly.
}
mkSumTyConRhs :: [DataCon] -> AlgTyConRhs
@@ -1860,7 +1861,7 @@ noTcTyConScopedTyVars = []
-- | Create an unlifted primitive 'TyCon', such as @Int#@.
mkPrimTyCon :: Name -> [TyConBinder]
- -> Kind -- ^ /result/ kind, never levity-polymorphic
+ -> Kind -- ^ /result/ kind, never representation-polymorphic
-> [Role] -> TyCon
mkPrimTyCon name binders res_kind roles
= mkPrimTyCon' name binders res_kind roles True (Just $ mkPrelTyConRepName name)
@@ -1883,9 +1884,9 @@ mkLiftedPrimTyCon name binders res_kind roles
where rep_nm = mkPrelTyConRepName name
mkPrimTyCon' :: Name -> [TyConBinder]
- -> Kind -- ^ /result/ kind, never levity-polymorphic
- -- (If you need a levity-polymorphic PrimTyCon, change
- -- isTcLevPoly.)
+ -> Kind -- ^ /result/ kind, never representation-polymorphic
+ -- (If you need a representation-polymorphic PrimTyCon,
+ -- change isTcLevPoly.)
-> [Role]
-> Bool -> Maybe TyConRepName -> TyCon
mkPrimTyCon' name binders res_kind roles is_unlifted rep_nm
@@ -2358,7 +2359,7 @@ setTcTyConKind tc@(TcTyCon {}) kind = let tc' = tc { tyConKind = kind
in tc'
setTcTyConKind tc _ = pprPanic "setTcTyConKind" (ppr tc)
--- | Could this TyCon ever be levity-polymorphic when fully applied?
+-- | Could this TyCon ever be representation-polymorphic when fully applied?
-- True is safe. False means we're sure. Does only a quick check
-- based on the TyCon's category.
-- Precondition: The fully-applied TyCon has kind (TYPE blah)
@@ -2368,7 +2369,8 @@ isTcLevPoly (AlgTyCon { algTcParent = parent, algTcRhs = rhs })
| UnboxedAlgTyCon _ <- parent
= True
| NewTyCon { nt_lev_poly = lev_poly } <- rhs
- = lev_poly -- Newtypes can be levity polymorphic with UnliftedNewtypes (#17360)
+ = lev_poly -- Newtypes can be representation-polymorphic
+ -- with UnliftedNewtypes (#17360)
| otherwise
= False
isTcLevPoly SynonymTyCon{} = True
diff --git a/compiler/GHC/Core/Type.hs b/compiler/GHC/Core/Type.hs
index da3715406b..8a5dc691ec 100644
--- a/compiler/GHC/Core/Type.hs
+++ b/compiler/GHC/Core/Type.hs
@@ -620,7 +620,7 @@ kindRep_maybe kind
-- | Returns True if the kind classifies types which are allocated on
-- the GC'd heap and False otherwise. Note that this returns False for
--- levity-polymorphic kinds, which may be specialized to a kind that
+-- representation-polymorphic kinds, which may be specialized to a kind that
-- classifies AddrRep or even unboxed kinds.
isBoxedTypeKind :: Kind -> Bool
isBoxedTypeKind kind
@@ -661,8 +661,8 @@ pickyIsLiftedTypeKind kind
| otherwise = False
-- | Returns True if the kind classifies unlifted types (like 'Int#') and False
--- otherwise. Note that this returns False for levity-polymorphic kinds, which
--- may be specialized to a kind that classifies unlifted types.
+-- otherwise. Note that this returns False for representation-polymorphic
+-- kinds, which may be specialized to a kind that classifies unlifted types.
isUnliftedTypeKind :: Kind -> Bool
isUnliftedTypeKind kind
= case kindRep_maybe kind of
@@ -2243,18 +2243,18 @@ buildSynTyCon name binders res_kind roles rhs
-- | Returns Just True if this type is surely lifted, Just False
-- if it is surely unlifted, Nothing if we can't be sure (i.e., it is
--- levity polymorphic), and panics if the kind does not have the shape
+-- representation-polymorphic), and panics if the kind does not have the shape
-- TYPE r.
isLiftedType_maybe :: HasDebugCallStack => Type -> Maybe Bool
isLiftedType_maybe ty = case coreFullView (getRuntimeRep ty) of
ty' | isLiftedRuntimeRep ty' -> Just True
TyConApp {} -> Just False -- Everything else is unlifted
- _ -> Nothing -- levity polymorphic
+ _ -> Nothing -- representation-polymorphic
-- | See "Type#type_classification" for what an unlifted type is.
--- Panics on levity polymorphic types; See 'mightBeUnliftedType' for
+-- Panics on representation-polymorphic types; See 'mightBeUnliftedType' for
-- a more approximate predicate that behaves better in the presence of
--- levity polymorphism.
+-- representation polymorphism.
isUnliftedType :: HasDebugCallStack => Type -> Bool
-- isUnliftedType returns True for forall'd unlifted types:
-- x :: forall a. Int#
@@ -2268,7 +2268,8 @@ isUnliftedType ty
-- | Returns:
--
-- * 'False' if the type is /guaranteed/ lifted or
--- * 'True' if it is unlifted, OR we aren't sure (e.g. in a levity-polymorphic case)
+-- * 'True' if it is unlifted, OR we aren't sure
+-- (e.g. in a representation-polymorphic case)
mightBeUnliftedType :: Type -> Bool
mightBeUnliftedType ty
= case isLiftedType_maybe ty of
@@ -2276,9 +2277,9 @@ mightBeUnliftedType ty
Nothing -> True
-- | See "Type#type_classification" for what a boxed type is.
--- Panics on levity polymorphic types; See 'mightBeUnliftedType' for
+-- Panics on representation-polymorphic types; See 'mightBeUnliftedType' for
-- a more approximate predicate that behaves better in the presence of
--- levity polymorphism.
+-- representation polymorphism.
isBoxedType :: Type -> Bool
isBoxedType ty = isBoxedRuntimeRep (getRuntimeRep ty)
@@ -2339,7 +2340,8 @@ isDataFamilyAppType ty = case tyConAppTyCon_maybe ty of
-- | Computes whether an argument (or let right hand side) should
-- be computed strictly or lazily, based only on its type.
--- Currently, it's just 'isUnliftedType'. Panics on levity-polymorphic types.
+-- Currently, it's just 'isUnliftedType'.
+-- Panics on representation-polymorphic types.
isStrictType :: HasDebugCallStack => Type -> Bool
isStrictType = isUnliftedType
@@ -2914,7 +2916,7 @@ typeLiteralKind (NumTyLit {}) = naturalTy
typeLiteralKind (StrTyLit {}) = typeSymbolKind
typeLiteralKind (CharTyLit {}) = charTy
--- | Returns True if a type is levity polymorphic. Should be the same
+-- | Returns True if a type is representation-polymorphic. Should be the same
-- as (isKindLevPoly . typeKind) but much faster.
-- Precondition: The type has kind (TYPE blah)
isTypeLevPoly :: Type -> Bool
@@ -2932,7 +2934,8 @@ isTypeLevPoly = go
check_kind = isKindLevPoly . typeKind
--- | Looking past all pi-types, is the end result potentially levity polymorphic?
+-- | Looking past all pi-types, is the end result potentially
+-- representation-polymorphic?
-- Example: True for (forall r (a :: TYPE r). String -> a)
-- Example: False for (forall r1 r2 (a :: TYPE r1) (b :: TYPE r2). a -> b -> Type)
resultIsLevPoly :: Type -> Bool
diff --git a/compiler/GHC/Core/Utils.hs b/compiler/GHC/Core/Utils.hs
index b18e93c951..3ec00d76be 100644
--- a/compiler/GHC/Core/Utils.hs
+++ b/compiler/GHC/Core/Utils.hs
@@ -186,14 +186,14 @@ mkFunctionType mult arg_ty res_ty
mkLamTypes vs ty = foldr mkLamType ty vs
--- | Is this expression levity polymorphic? This should be the
+-- | Is this expression representation-polymorphic? This should be the
-- same as saying (isKindLevPoly . typeKind . exprType) but
-- much faster.
isExprLevPoly :: CoreExpr -> Bool
isExprLevPoly = go
where
- go (Var _) = False -- no levity-polymorphic binders
- go (Lit _) = False -- no levity-polymorphic literals
+ go (Var _) = False -- no representation-poly binders
+ go (Lit _) = False -- no representation-poly literals
go e@(App f _) | not (go_app f) = False
| otherwise = check_type e
go (Lam _ _) = False
@@ -209,9 +209,10 @@ isExprLevPoly = go
-- if the function is a variable (common case), check its
-- levityInfo. This might mean we don't need to look up and compute
-- on the type. Spec of these functions: return False if there is
- -- no possibility, ever, of this expression becoming levity polymorphic,
- -- no matter what it's applied to; return True otherwise.
- -- returning True is always safe. See also Note [Levity info] in
+ -- no possibility, ever, of this expression becoming
+ -- representation-polymorphic, no matter what it's applied to;
+ -- return True otherwise.
+ -- Returning True is always safe. See also Note [Levity info] in
-- IdInfo
go_app (Var id) = not (isNeverLevPolyId id)
go_app (Lit _) = False
@@ -1955,8 +1956,9 @@ exprIsTopLevelBindable :: CoreExpr -> Type -> Bool
-- see Note [Core top-level string literals] in "GHC.Core"
exprIsTopLevelBindable expr ty
= not (mightBeUnliftedType ty)
- -- Note that 'expr' may be levity polymorphic here consequently we must use
- -- 'mightBeUnliftedType' rather than 'isUnliftedType' as the latter would panic.
+ -- Note that 'expr' may be representation-polymorphic here, consequently
+ -- we must use 'mightBeUnliftedType' rather than 'isUnliftedType',
+ -- as the latter would panic.
|| exprIsTickedString expr
-- | Check if the expression is zero or more Ticks wrapped around a literal
diff --git a/compiler/GHC/HsToCore.hs b/compiler/GHC/HsToCore.hs
index 7ea0619733..1c11c17ac1 100644
--- a/compiler/GHC/HsToCore.hs
+++ b/compiler/GHC/HsToCore.hs
@@ -645,9 +645,9 @@ or (Core)
(x |> (GRefl :: a ~# (a |> TYPE co1)) ; co2)
It looks like we can write this in Haskell directly, but we can't:
-the levity polymorphism checks defeat us. Note that `x` is a levity-
-polymorphic variable. So we must wire it in with a compulsory
-unfolding, like other levity-polymorphic primops.
+the reprsentation polymorphism checks defeat us. Note that `x` is a
+representation-polymorphic variable. So we must wire it in with a
+compulsory unfolding, like other representation-polymorphic primops.
The challenge is that UnsafeEquality is a GADT, and wiring in a GADT
is *hard*: it has a worker separate from its wrapper, with all manner
diff --git a/compiler/GHC/HsToCore/Arrows.hs b/compiler/GHC/HsToCore/Arrows.hs
index 4a31b9fc8d..2b7b96f118 100644
--- a/compiler/GHC/HsToCore/Arrows.hs
+++ b/compiler/GHC/HsToCore/Arrows.hs
@@ -1102,7 +1102,7 @@ dsfixCmdStmts
dsfixCmdStmts ids local_vars out_ids stmts
= trimInput (dsCmdStmts ids local_vars out_ids stmts)
- -- TODO: Add levity polymorphism check for the resulting expression.
+ -- TODO: Add representation polymorphism check for the resulting expression.
-- But I (Richard E.) don't know enough about arrows to do so.
dsCmdStmts
diff --git a/compiler/GHC/HsToCore/Binds.hs b/compiler/GHC/HsToCore/Binds.hs
index c5a47f388a..50a3c319f9 100644
--- a/compiler/GHC/HsToCore/Binds.hs
+++ b/compiler/GHC/HsToCore/Binds.hs
@@ -616,8 +616,8 @@ Note [Strict binds checks]
There are several checks around properly formed strict bindings. They
all link to this Note. These checks must be here in the desugarer because
we cannot know whether or not a type is unlifted until after zonking, due
-to levity polymorphism. These checks all used to be handled in the typechecker
-in checkStrictBinds (before Jan '17).
+to representation polymorphism. These checks all used to be handled in the
+typechecker in checkStrictBinds (before Jan '17).
We define an "unlifted bind" to be any bind that binds an unlifted id. Note that
diff --git a/compiler/GHC/HsToCore/Errors/Ppr.hs b/compiler/GHC/HsToCore/Errors/Ppr.hs
index 87846bb8f2..0d8dbcc9a9 100644
--- a/compiler/GHC/HsToCore/Errors/Ppr.hs
+++ b/compiler/GHC/HsToCore/Errors/Ppr.hs
@@ -199,14 +199,15 @@ instance Diagnostic DsMessage where
2 (vcat (map ppr binds))
DsCannotUseFunWithPolyArgs orig_hs_expr ty bad_tys
-> mkSimpleDecorated $
- vcat [ hang (text "Cannot use function with levity-polymorphic arguments:")
+ vcat [ hang (text "Cannot use function with representation-polymorphic arguments:")
2 (hang (ppr orig_hs_expr) 2 (dcolon <+> pprWithTYPE ty))
, ppUnlessOption sdocPrintTypecheckerElaboration $ vcat
- [ text "(Note that levity-polymorphic primops such as 'coerce' and unboxed tuples"
- , text "are eta-expanded internally because they must occur fully saturated."
+ [ text "(Note that representation-polymorphic primops,"
+ , text "such as 'coerce' and unboxed tuples, are eta-expanded"
+ , text "internally because they must occur fully saturated."
, text "Use -fprint-typechecker-elaboration to display the full expression.)"
]
- , hang (text "Levity-polymorphic arguments:")
+ , hang (text "Representation-polymorphic arguments:")
2 $ vcat $ map
(\t -> pprWithTYPE t <+> dcolon <+> pprWithTYPE (typeKind t))
bad_tys
diff --git a/compiler/GHC/HsToCore/Expr.hs b/compiler/GHC/HsToCore/Expr.hs
index 602950bf3e..6bf900da89 100644
--- a/compiler/GHC/HsToCore/Expr.hs
+++ b/compiler/GHC/HsToCore/Expr.hs
@@ -240,11 +240,11 @@ dsLExpr :: LHsExpr GhcTc -> DsM CoreExpr
dsLExpr (L loc e) =
putSrcSpanDsA loc $ dsExpr e
--- | Variant of 'dsLExpr' that ensures that the result is not levity
--- polymorphic. This should be used when the resulting expression will
--- be an argument to some other function.
--- See Note [Levity polymorphism checking] in "GHC.HsToCore.Monad"
--- See Note [Levity polymorphism invariants] in "GHC.Core"
+-- | Variant of 'dsLExpr' that ensures that the result is not
+-- representation- polymorphic. This should be used when the resulting
+-- expression will be an argument to some other function.
+-- See Note [Representation polymorphism checking] in "GHC.HsToCore.Monad"
+-- See Note [Representation polymorphism invariants] in "GHC.Core"
dsLExprNoLP :: LHsExpr GhcTc -> DsM CoreExpr
dsLExprNoLP (L loc e)
= putSrcSpanDsA loc $
@@ -1056,7 +1056,7 @@ dsConLike con tvbs tys
= do { ds_con <- dsHsConLike con
; ids <- newSysLocalsDs tys
-- newSysLocalDs: /can/ be lev-poly; see
- -- Note [Checking levity-polymorphic data constructors]
+ -- Note [Checking representation-polymorphic data constructors]
; return (mkLams tvs $
mkLams ids $
ds_con `mkTyApps` mkTyVarTys tvs
@@ -1106,21 +1106,21 @@ warnDiscardedDoBindings rhs rhs_ty
{-
************************************************************************
* *
- Levity polymorphism checks
+ Representation polymorphism checks
* *
************************************************************************
-Note [Checking for levity-polymorphic functions]
+Note [Checking for representation-polymorphic functions]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We cannot have levity polymorphic function arguments. See
-Note [Levity polymorphism invariants] in GHC.Core. That is
+We cannot have representation-polymorphic function arguments. See
+Note [Representation polymorphism invariants] in GHC.Core. That is
checked by dsLExprNoLP.
But what about
const True (unsafeCoerce# :: forall r1 r2 (a :: TYPE r1) (b :: TYPE r2). a -> b)
Since `unsafeCoerce#` has no binding, it has a compulsory unfolding.
-But that compulsory unfolding is a levity-polymorphic lambda, which
+But that compulsory unfolding is a representation-polymorphic lambda, which
is no good. So we want to reject this. On the other hand
const True (unsafeCoerce# @LiftedRep @UnliftedRep)
is absolutely fine.
@@ -1140,13 +1140,14 @@ that are a problem. See checkLevPolyFunction.
Interestingly, this approach does not look to see whether the Id in
question will be eta expanded. The logic is this:
* Either the Id in question is saturated or not.
- * If it is, then it surely can't have levity polymorphic arguments.
- If its wrapped type contains levity polymorphic arguments, reject.
- * If it's not, then it can't be eta expanded with levity polymorphic
- argument. If its wrapped type contains levity polymorphic arguments, reject.
+ * If it is, then it surely can't have representation-polymorphic arguments.
+ If its wrapped type contains representation-polymorphic arguments, reject.
+ * If it's not, then it can't be eta expanded with representation-polymorphic
+ argument. If its wrapped type contains representation-polymorphic arguments,
+ reject.
So, either way, we're good to reject.
-Note [Nasty wrinkle in levity-polymorphic function check]
+Note [Nasty wrinkle in representation-polymorphic function check]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A nasty wrinkle came up in T13244
type family Rep x
@@ -1163,7 +1164,7 @@ Here the function I# is wrapped in a /cast/, thus
If we look only at final type of the expression,
namely: Unboxed Int -> Int,
the kind of the argument type is TYPE (Rep Int), and that needs
-type-family reduction to say whether it is lifted or unlifted.
+type-family reduction to determine the runtime representation.
So we split the wrapper into the instantiating part (which is what
we really want) and everything else; see splitWrapper. This is
@@ -1178,12 +1179,12 @@ But it also improves the error message in an example like T13233_elab:
quux = obscure (#,#)
Around the (#,#) we'll get some type /abstractions/ wrapping some type
-/instantiations/. In the levity-poly error message we really only want
-to report the instantiations. Hence passing (mkHsWrap w_inner e) to
-checkLevPolyArgs.
+/instantiations/. In the representation polymorphism error message,
+we really only want to report the instantiations.
+Hence passing (mkHsWrap w_inner e) to checkLevPolyArgs.
-Note [Checking levity-polymorphic data constructors]
+Note [Checking representation-polymorphic data constructors]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Similarly, generated by a newtype data constructor, we might get this:
(/\(r :: RuntimeRep) (a :: TYPE r) \(x::a). K r a x) @LiftedRep Int 4
@@ -1191,12 +1192,14 @@ Similarly, generated by a newtype data constructor, we might get this:
which we want to accept. See Note [Typechecking data constructors] in
GHC.Tc.Gen.Head.
-Because we want to accept this, we switch off Lint's levity-poly checks
-when Lint checks the output of the desugarer; see the lf_check_levity_poly
-flag in GHC.Core.Lint.lintCoreBindings.
+Because we want to accept this, we switch off Lint's
+representation polymorphism checks when Lint checks the output of the
+desugarer; see the lf_check_levity_poly flag in
+GHC.Core.Lint.lintCoreBindings.
-We can get this situation both for levity-polymorphic newtype constructors
-(T18481), and for levity-polymorphic algebraic data types, e.g (T18481a)
+We can get this situation both for representation-polymorphic
+newtype constructors (T18481), and for representation-polymorphic
+algebraic data types, e.g (T18481a)
type T :: TYPE (BoxedRep r) -> TYPE (BoxedRep r)
data T a = MkT Int
@@ -1208,7 +1211,7 @@ We can get this situation both for levity-polymorphic newtype constructors
dsHsWrapped :: HsExpr GhcTc -> DsM CoreExpr
-- Looks for a function 'f' wrapped in type applications (HsAppType)
-- or wrappers (HsWrap), and checks that any hasNoBinding function
--- is not levity polymorphic, *after* instantiation with those wrappers
+-- is not representation-polymorphic, *after* instantiation with those wrappers
dsHsWrapped orig_hs_expr
= go idHsWrapper orig_hs_expr
where
@@ -1255,7 +1258,7 @@ splitWrapper :: HsWrapper -> (HsWrapper, HsWrapper)
-- Split a wrapper w into (outer_wrap <.> inner_wrap), where
-- inner_wrap does instantiation (type and evidence application)
-- and outer_wrap is everything else, such as a final cast
--- See Note [Nasty wrinkle in levity-polymorphic function check]
+-- See Note [Nasty wrinkle in representation-polymorphic function check]
splitWrapper wrap
= go WpHole wrap
where
@@ -1366,7 +1369,7 @@ These requirements are implemented in the guards in ds_withDict's definition.
Some further observations about `withDict`:
* Every use of `withDict` must be instantiated at a /particular/ class C.
- It's a bit like levity polymorphism: we don't allow class-polymorphic
+ It's a bit like representation polymorphism: we don't allow class-polymorphic
calls of `withDict`. We check this in the desugarer -- and then we
can immediately replace this invocation of `withDict` with appropriate
class-specific Core code.
@@ -1378,8 +1381,8 @@ Some further observations about `withDict`:
* For examples of how `withDict` is used in the `base` library, see `withSNat`
in GHC.TypeNats, as well as `withSChar` and `withSSymbol` n GHC.TypeLits.
-* The `r` is levity polymorphic to support things like `withTypeable` in
- `Data.Typeable.Internal`.
+* The `r` is representation-polymorphic,
+ to support things like `withTypeable` in `Data.Typeable.Internal`.
* As an alternative to `withDict`, one could define functions like `withT`
above in terms of `unsafeCoerce`. This is more error-prone, however.
@@ -1431,8 +1434,8 @@ Some further observations about `withDict`:
-- | Takes a (pretty-printed) expression, a function, and its
-- instantiated type. If the function is a hasNoBinding op, and the
--- type has levity-polymorphic arguments, issue an error.
--- Note [Checking for levity-polymorphic functions]
+-- type has representation-polymorphic arguments, issue an error.
+-- Note [Checking for representation-polymorphic functions]
checkLevPolyFunction :: Outputable e => e -> Id -> Type -> DsM ()
checkLevPolyFunction orig_hs_expr var ty
| hasNoBinding var
@@ -1441,13 +1444,13 @@ checkLevPolyFunction orig_hs_expr var ty
= return ()
checkLevPolyArgs :: Outputable e => e -> Type -> DsM ()
--- Check that there are no levity-polymorphic arguments in
+-- Check that there are no representation-polymorphic arguments in
-- the supplied type
-- E.g. Given (forall a. t1 -> t2 -> blah), ensure that t1,t2
--- are not levity-polymorhic
+-- are not representation-polymorhic
--
-- Pass orig_hs_expr, so that the user can see entire thing
--- Note [Checking for levity-polymorphic functions]
+-- Note [Checking for representation-polymorphic functions]
checkLevPolyArgs orig_hs_expr ty
| let (binders, _) = splitPiTys ty
arg_tys = mapMaybe binderRelevantType_maybe binders
diff --git a/compiler/GHC/HsToCore/Foreign/Call.hs b/compiler/GHC/HsToCore/Foreign/Call.hs
index ed8853eb71..80f878ef02 100644
--- a/compiler/GHC/HsToCore/Foreign/Call.hs
+++ b/compiler/GHC/HsToCore/Foreign/Call.hs
@@ -88,7 +88,7 @@ follows:
dsCCall :: CLabelString -- C routine to invoke
-> [CoreExpr] -- Arguments (desugared)
- -- Precondition: none have levity-polymorphic types
+ -- Precondition: none have representation-polymorphic types
-> Safety -- Safety of the call
-> Type -- Type of the result: IO t
-> DsM CoreExpr -- Result, of type ???
@@ -127,7 +127,7 @@ mkFCall dflags uniq the_fcall val_args res_ty
ty = mkInfForAllTys tyvars body_ty
the_fcall_id = mkFCallId dflags uniq the_fcall ty
-unboxArg :: CoreExpr -- The supplied argument, not levity-polymorphic
+unboxArg :: CoreExpr -- The supplied argument, not representation-polymorphic
-> DsM (CoreExpr, -- To pass as the actual argument
CoreExpr -> CoreExpr -- Wrapper to unbox the arg
)
@@ -135,7 +135,7 @@ unboxArg :: CoreExpr -- The supplied argument, not levity-pol
-- (x#::Int#, \W. case x of I# x# -> W)
-- where W is a CoreExpr that probably mentions x#
--- always returns a non-levity-polymorphic expression
+-- always returns a non-representation-polymorphic expression
unboxArg arg
-- Primitive types: nothing to unbox
diff --git a/compiler/GHC/HsToCore/Foreign/Decl.hs b/compiler/GHC/HsToCore/Foreign/Decl.hs
index 0b0d1dc21d..8eae17e414 100644
--- a/compiler/GHC/HsToCore/Foreign/Decl.hs
+++ b/compiler/GHC/HsToCore/Foreign/Decl.hs
@@ -218,7 +218,7 @@ dsFCall fn_id co fcall mDeclHeader = do
(tv_bndrs, rho) = tcSplitForAllTyVarBinders ty
(arg_tys, io_res_ty) = tcSplitFunTys rho
- args <- newSysLocalsDs arg_tys -- no FFI levity-polymorphism
+ args <- newSysLocalsDs arg_tys -- no FFI representation polymorphism
(val_args, arg_wrappers) <- mapAndUnzipM unboxArg (map Var args)
let
@@ -323,7 +323,7 @@ dsPrimCall fn_id co fcall = do
(tvs, fun_ty) = tcSplitForAllInvisTyVars ty
(arg_tys, io_res_ty) = tcSplitFunTys fun_ty
- args <- newSysLocalsDs arg_tys -- no FFI levity-polymorphism
+ args <- newSysLocalsDs arg_tys -- no FFI representation polymorphism
ccall_uniq <- newUnique
dflags <- getDynFlags
diff --git a/compiler/GHC/HsToCore/ListComp.hs b/compiler/GHC/HsToCore/ListComp.hs
index ee5edd8ac5..6c988ee047 100644
--- a/compiler/GHC/HsToCore/ListComp.hs
+++ b/compiler/GHC/HsToCore/ListComp.hs
@@ -278,8 +278,8 @@ deBindComp pat core_list1 quals core_list2 = do
let res_ty = exprType core_list2
h_ty = u1_ty `mkVisFunTyMany` res_ty
- -- no levity polymorphism here, as list comprehensions don't work
- -- with RebindableSyntax. NB: These are *not* monad comps.
+ -- no representation polymorphism here, as list comprehensions
+ -- don't work with RebindableSyntax. NB: These are *not* monad comps.
[h, u1, u2, u3] <- newSysLocalsDs $ map unrestricted [h_ty, u1_ty, u2_ty, u3_ty]
-- the "fail" value ...
@@ -647,7 +647,7 @@ dsInnerMonadComp stmts bndrs ret_op
mkMcUnzipM :: TransForm
-> HsExpr GhcTc -- fmap
-> Id -- Of type n (a,b,c)
- -> [Type] -- [a,b,c] (not levity-polymorphic)
+ -> [Type] -- [a,b,c] (not representation-polymorphic)
-> DsM CoreExpr -- Of type (n a, n b, n c)
mkMcUnzipM ThenForm _ ys _
= return (Var ys) -- No unzipping to do
diff --git a/compiler/GHC/HsToCore/Monad.hs b/compiler/GHC/HsToCore/Monad.hs
index 91cb41c46c..721ef1074e 100644
--- a/compiler/GHC/HsToCore/Monad.hs
+++ b/compiler/GHC/HsToCore/Monad.hs
@@ -48,7 +48,7 @@ module GHC.HsToCore.Monad (
DsMatchContext(..),
EquationInfo(..), MatchResult (..), runMatchResult, DsWrapper, idDsWrapper,
- -- Levity polymorphism
+ -- Representation polymorphism
dsNoLevPoly, dsNoLevPolyExpr, dsWhenNoErrs,
-- Trace injection
@@ -363,29 +363,36 @@ grab one or more names. @newLocalDs@ isn't exported---exported
functions are defined with it. The difference in name-strings makes
it easier to read debugging output.
-Note [Levity polymorphism checking]
+Note [Representation polymorphism checking]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-According to the "Levity Polymorphism" paper (PLDI '17), levity
-polymorphism is forbidden in precisely two places: in the type of a bound
-term-level argument and in the type of an argument to a function. The paper
-explains it more fully, but briefly: expressions in these contexts need to be
-stored in registers, and it's hard (read, impossible) to store something
-that's levity polymorphic.
-
-We cannot check for bad levity polymorphism conveniently in the type checker,
-because we can't tell, a priori, which levity metavariables will be solved.
+According to the "Levity Polymorphism" paper (PLDI '17),
+representation polymorphism is forbidden in precisely two places:
+in the type of a bound term-level argument, and in the type of an argument
+to a function.
+Note that the paper doesn't distinguish levity polymorphism, such as
+ \(v::Levity). \(a::TYPE (BoxedRep v)). \(x::a). expr
+from the more general representation polymorphism, as the BoxedRep
+constructor of RuntimeRep didn't exist at the time.
+
+The paper explains the restrictions more fully, but briefly:
+expressions in these contexts need to be stored in registers, and it's
+hard (read: impossible) to store something that's representation-polymorphic.
+
+We cannot check for bad representation polymorphism conveniently
+in the type checker, because we can't tell, a priori, which
+representation metavariables will be solved.
At one point, I (Richard) thought we could check in the zonker, but it's hard
to know where precisely are the abstracted variables and the arguments. So
we check in the desugarer, the only place where we can see the Core code and
still report respectable syntax to the user. This covers the vast majority
of cases; see calls to GHC.HsToCore.Monad.dsNoLevPoly and friends.
-Levity polymorphism is also prohibited in the types of binders, and the
+Representation polymorphism is also prohibited in the types of binders, and the
desugarer checks for this in GHC-generated Ids. (The zonker handles
the user-writted ids in zonkIdBndr.) This is done in newSysLocalDsNoLP.
The newSysLocalDs variant is used in the vast majority of cases where
-the binder is obviously not levity polymorphic, omitting the check.
-It would be nice to ASSERT that there is no levity polymorphism here,
+the binder is obviously not representation-polymorphic, omitting the check.
+It would be nice to ASSERT that there is no representation polymorphism here,
but we can't, because of the fixM in GHC.HsToCore.Arrows. It's all OK, though:
Core Lint will catch an error here.
@@ -396,10 +403,10 @@ in the appropriate HsWrappers (e.g. WpFun) that we can print out in the
desugarer.
There are a few more checks in places where Core is generated outside the
-desugarer. For example, in datatype and class declarations, where levity
-polymorphism is checked for during validity checking. It would be nice to
-have one central place for all this, but that doesn't seem possible while
-still reporting nice error messages.
+desugarer. For example, in datatype and class declarations, where
+representation polymorphism is checked for during validity checking.
+It would be nice to have one central place for all this, but that doesn't
+seem possible while still reporting nice error messages.
-}
@@ -420,12 +427,13 @@ newSysLocalDsNoLP, newSysLocalDs, newFailLocalDs :: Mult -> Type -> DsM Id
newSysLocalDsNoLP = mk_local (fsLit "ds")
-- this variant should be used when the caller can be sure that the variable type
--- is not levity-polymorphic. It is necessary when the type is knot-tied because
--- of the fixM used in GHC.HsToCore.Arrows. See Note [Levity polymorphism checking]
+-- is not representation-polymorphic. It is necessary when the type
+-- is knot-tied because of the fixM used in GHC.HsToCore.Arrows.
+-- See Note [Representation polymorphism checking]
newSysLocalDs = mkSysLocalM (fsLit "ds")
newFailLocalDs = mkSysLocalM (fsLit "fail")
-- the fail variable is used only in a situation where we can tell that
- -- levity-polymorphism is impossible.
+ -- representation polymorphism is impossible.
newSysLocalsDsNoLP, newSysLocalsDs :: [Scaled Type] -> DsM [Id]
newSysLocalsDsNoLP = mapM (\(Scaled w t) -> newSysLocalDsNoLP w t)
@@ -587,26 +595,26 @@ discardWarningsDs thing_inside
; return result }
--- | Fail with an error message if the type is levity polymorphic.
+-- | Fail with an error message if the type is representation-polymorphic.
dsNoLevPoly :: Type -> LevityCheckProvenance -> DsM ()
--- See Note [Levity polymorphism checking]
+-- See Note [Representation polymorphism checking]
dsNoLevPoly ty provenance =
checkForLevPolyX (\ty -> failWithDs . DsLevityPolyInType ty) provenance ty
--- | Check an expression for levity polymorphism, failing if it is
--- levity polymorphic.
+-- | Check an expression for representation polymorphism, failing if it is
+-- representation-polymorphic.
dsNoLevPolyExpr :: CoreExpr -> LevityExprProvenance -> DsM ()
--- See Note [Levity polymorphism checking]
+-- See Note [Representation polymorphism checking]
dsNoLevPolyExpr e provenance
| isExprLevPoly e = diagnosticDs (DsLevityPolyInExpr e provenance)
| otherwise = return ()
-- | Runs the thing_inside. If there are no errors, then returns the expr
-- given. Otherwise, returns unitExpr. This is useful for doing a bunch
--- of levity polymorphism checks and then avoiding making a core App.
--- (If we make a core App on a levity polymorphic argument, detecting how
--- to handle the let/app invariant might call isUnliftedType, which panics
--- on a levity polymorphic type.)
+-- of representation polymorphism checks and then avoiding making a core App.
+-- (If we make a core App on a representation-polymorphic argument, detecting
+-- how to handle the let/app invariant might call isUnliftedType, which panics
+-- on a representation-polymorphic type.)
-- See #12709 for an example of why this machinery is necessary.
dsWhenNoErrs :: DsM a -> (a -> CoreExpr) -> DsM CoreExpr
dsWhenNoErrs thing_inside mk_expr
diff --git a/compiler/GHC/HsToCore/Pmc/Solver.hs b/compiler/GHC/HsToCore/Pmc/Solver.hs
index 6efd44a5aa..1b6121f31f 100644
--- a/compiler/GHC/HsToCore/Pmc/Solver.hs
+++ b/compiler/GHC/HsToCore/Pmc/Solver.hs
@@ -1342,7 +1342,7 @@ isDataConTriviallyInhabited dc =
dataConUnliftedFieldTys :: DataCon -> [Type]
dataConUnliftedFieldTys =
- -- A levity polymorphic field requires an inhabitation test, hence compare to
+ -- A representation-polymorphic field requires an inhabitation test, hence compare to
-- @Just True@
filter ((== Just True) . isLiftedType_maybe) . map scaledThing . dataConOrigArgTys
diff --git a/compiler/GHC/HsToCore/Utils.hs b/compiler/GHC/HsToCore/Utils.hs
index d5cbed2e36..020775c91c 100644
--- a/compiler/GHC/HsToCore/Utils.hs
+++ b/compiler/GHC/HsToCore/Utils.hs
@@ -428,13 +428,13 @@ This case expression accounts for linear variables by assigning bottom usage
(See Note [Bottom as a usage] in GHC.Core.Multiplicity).
This is done in mkFailExpr.
We use '()' instead of the original return type ('a' in this case)
-because there might be levity polymorphism, e.g. in
+because there might be representation polymorphism, e.g. in
g :: forall (a :: TYPE r). (() -> a) %1 -> Bool -> a
g x True = x ()
adding 'g x False = case error "Non-exhaustive pattern" :: a of {}'
-would create an illegal levity-polymorphic case binder.
+would create an illegal representation-polymorphic case binder.
This is important for pattern synonym matchers, which often look like this 'g'.
Similarly, a hole
@@ -536,7 +536,7 @@ There are a few subtleties in the desugaring of `seq`:
which stupidly tries to bind the datacon 'True'.
-}
--- NB: Make sure the argument is not levity polymorphic
+-- NB: Make sure the argument is not representation-polymorphic
mkCoreAppDs :: SDoc -> CoreExpr -> CoreExpr -> CoreExpr
mkCoreAppDs _ (Var f `App` Type _r `App` Type ty1 `App` Type ty2 `App` arg1) arg2
| f `hasKey` seqIdKey -- Note [Desugaring seq], points (1) and (2)
@@ -556,7 +556,7 @@ mkCoreAppDs _ (Var f `App` Type _r) arg
mkCoreAppDs s fun arg = mkCoreApp s fun arg -- The rest is done in GHC.Core.Make
--- NB: No argument can be levity polymorphic
+-- NB: No argument can be representation-polymorphic
mkCoreAppsDs :: SDoc -> CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreAppsDs s fun args = foldl' (mkCoreAppDs s) fun args
diff --git a/compiler/GHC/Iface/Syntax.hs b/compiler/GHC/Iface/Syntax.hs
index d1ecf388cd..b2aaad5e23 100644
--- a/compiler/GHC/Iface/Syntax.hs
+++ b/compiler/GHC/Iface/Syntax.hs
@@ -350,7 +350,7 @@ data IfaceInfoItem
| HsUnfold Bool -- True <=> isStrongLoopBreaker is true
IfaceUnfolding -- See Note [Expose recursive functions]
| HsNoCafRefs
- | HsLevity -- Present <=> never levity polymorphic
+ | HsLevity -- Present <=> never representation-polymorphic
| HsLFInfo IfaceLFInfo
-- NB: Specialisations and rules come in separately and are
diff --git a/compiler/GHC/Iface/Type.hs b/compiler/GHC/Iface/Type.hs
index 3477fcf552..58410467d3 100644
--- a/compiler/GHC/Iface/Type.hs
+++ b/compiler/GHC/Iface/Type.hs
@@ -818,8 +818,8 @@ Note [Printing type abbreviations]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Normally, we pretty-print `TYPE 'LiftedRep` as `Type` (or `*`) and
`FUN 'Many` as `(->)`.
-This way, error messages don't refer to levity polymorphism or linearity
-if it is not necessary.
+This way, error messages don't refer to representation polymorphism
+or linearity if it is not necessary.
However, when printing the definition of Type or (->) with :info,
this would give confusing output: `type (->) = (->)` (#18594).
diff --git a/compiler/GHC/IfaceToCore.hs b/compiler/GHC/IfaceToCore.hs
index b5f3618003..b275c74713 100644
--- a/compiler/GHC/IfaceToCore.hs
+++ b/compiler/GHC/IfaceToCore.hs
@@ -1747,7 +1747,7 @@ an unfolding that isn't going to be looked at.
-}
tcPragExpr :: Bool -- Is this unfolding compulsory?
- -- See Note [Checking for levity polymorphism] in GHC.Core.Lint
+ -- See Note [Checking for representation polymorphism] in GHC.Core.Lint
-> TopLevelFlag -> Name -> IfaceExpr -> IfL (Maybe CoreExpr)
tcPragExpr is_compulsory toplvl name expr
= forkM_maybe doc $ do
diff --git a/compiler/GHC/Rename/Expr.hs b/compiler/GHC/Rename/Expr.hs
index aff3ce3dbd..a85103d8ed 100644
--- a/compiler/GHC/Rename/Expr.hs
+++ b/compiler/GHC/Rename/Expr.hs
@@ -130,7 +130,7 @@ but several have a little bit of special treatment:
* SectionL and SectionR (left and right sections)
(`op` e) ==> rightSection op e
(e `op`) ==> leftSection (op e)
- where `leftSection` and `rightSection` are levity-polymorphic
+ where `leftSection` and `rightSection` are representation-polymorphic
wired-in Ids. See Note [Left and right sections]
* It's a bit painful to transform `OpApp e1 op e2` to a `HsExpansion`
@@ -613,19 +613,19 @@ Note the wrinkles:
sections , but only to eliminate special-purpose code paths in the
renamer and desugarer.
-* leftSection and rightSection must be levity-polymorphic, to allow
+* leftSection and rightSection must be representation-polymorphic, to allow
(+# 4#) and (4# +#) to work. See GHC.Types.Id.Make.
Note [Wired-in Ids for rebindable syntax] in
* leftSection and rightSection must be multiplicity-polymorphic.
(Test linear/should_compile/OldList showed this up.)
-* Because they are levity-polymorphic, we have to define them
+* Because they are representation-polymorphic, we have to define them
as wired-in Ids, with compulsory inlining. See
GHC.Types.Id.Make.leftSectionId, rightSectionId.
* leftSection is just ($) really; but unlike ($) it is
- levity polymorphic in the result type, so we can write
+ representation-polymorphic in the result type, so we can write
`(x +#)`, say.
* The type of leftSection must have an arrow in its first argument,
diff --git a/compiler/GHC/StgToByteCode.hs b/compiler/GHC/StgToByteCode.hs
index a67c42bf91..7dad6a87da 100644
--- a/compiler/GHC/StgToByteCode.hs
+++ b/compiler/GHC/StgToByteCode.hs
@@ -777,18 +777,19 @@ never used as an argument to another function, and it is called only
in tail position. See Note [Join points] and Note [Invariants on join points],
both in GHC.Core. Because join points do not compile to true, red-blooded
variables (with, e.g., registers allocated to them), they are allowed
-to be levity-polymorphic. (See invariant #6 in Note [Invariants on join points]
-in GHC.Core.)
+to be representation-polymorphic.
+(See invariant #6 in Note [Invariants on join points] in GHC.Core.)
However, in this byte-code generator, join points *are* treated just as
ordinary variables. There is no check whether a binding is for a join point
or not; they are all treated uniformly. (Perhaps there is a missed optimization
opportunity here, but that is beyond the scope of my (Richard E's) Thursday.)
-We thus must have *some* strategy for dealing with levity-polymorphic and
-unlifted join points. Levity-polymorphic variables are generally not allowed
-(though levity-polymorphic join points *are*; see Note [Invariants on join points]
-in GHC.Core, point 6), and we don't wish to evaluate unlifted join points eagerly.
+We thus must have *some* strategy for dealing with representation-polymorphic
+and unlifted join points. Representation-polymorphic variables are generally
+not allowed (though representation -polymorphic join points *are*; see
+Note [Invariants on join points] in GHC.Core, point 6), and we don't wish to
+evaluate unlifted join points eagerly.
The questionable join points are *not-necessarily-lifted join points*
(NNLJPs). (Not having such a strategy led to #16509, which panicked in the
isUnliftedType check in the AnnVar case of schemeE.) Here is the strategy:
@@ -797,9 +798,9 @@ isUnliftedType check in the AnnVar case of schemeE.) Here is the strategy:
2. When binding an NNLJP, add a `\ (_ :: (# #)) ->` to its RHS, and modify the
type to tack on a `(# #) ->`.
- Note that functions are never levity-polymorphic, so this transformation
- changes an NNLJP to a non-levity-polymorphic join point. This is done
- in bcPrepSingleBind.
+ Note that functions are never representation-polymorphic, so this
+ transformation changes an NNLJP to a non-representation-polymorphic
+ join point. This is done in bcPrepSingleBind.
3. At an occurrence of an NNLJP, add an application to void# (called voidPrimId),
being careful to note the new type of the NNLJP. This is done in the AnnVar
diff --git a/compiler/GHC/Tc/Deriv/Utils.hs b/compiler/GHC/Tc/Deriv/Utils.hs
index d6f0a2b474..444b372ada 100644
--- a/compiler/GHC/Tc/Deriv/Utils.hs
+++ b/compiler/GHC/Tc/Deriv/Utils.hs
@@ -909,7 +909,7 @@ cond_args cls _ _ rep_tc
| cls_key == eqClassKey = check_in arg_ty ordOpTbl
| cls_key == ordClassKey = check_in arg_ty ordOpTbl
| cls_key == showClassKey = check_in arg_ty boxConTbl
- | cls_key == liftClassKey = True -- Lift is levity-polymorphic
+ | cls_key == liftClassKey = True -- Lift is representation-polymorphic
| otherwise = False -- Read, Ix etc
check_in :: Type -> [(Type,a)] -> Bool
diff --git a/compiler/GHC/Tc/Errors/Ppr.hs b/compiler/GHC/Tc/Errors/Ppr.hs
index a44309eaf6..d538862e50 100644
--- a/compiler/GHC/Tc/Errors/Ppr.hs
+++ b/compiler/GHC/Tc/Errors/Ppr.hs
@@ -85,10 +85,10 @@ dodgy_msg_insert tc = IEThingAll noAnn ii
ii :: LIEWrappedName (IdP (GhcPass p))
ii = noLocA (IEName $ noLocA tc)
-formatLevPolyErr :: Type -- levity-polymorphic type
+formatLevPolyErr :: Type -- representation-polymorphic type
-> SDoc
formatLevPolyErr ty
- = hang (text "A levity-polymorphic type is not allowed here:")
+ = hang (text "A representation-polymorphic type is not allowed here:")
2 (vcat [ text "Type:" <+> pprWithTYPE tidy_ty
, text "Kind:" <+> pprWithTYPE tidy_ki ])
where
diff --git a/compiler/GHC/Tc/Gen/Sig.hs b/compiler/GHC/Tc/Gen/Sig.hs
index 6edb614884..42d5300d1e 100644
--- a/compiler/GHC/Tc/Gen/Sig.hs
+++ b/compiler/GHC/Tc/Gen/Sig.hs
@@ -444,7 +444,7 @@ tcPatSynSig name sig_ty@(L _ (HsSig{sig_bndrs = hs_outer_bndrs, sig_body = hs_ty
build_patsyn_type implicit_bndrs univ_bndrs req ex_bndrs prov body_ty
-- arguments become the types of binders. We thus cannot allow
- -- levity polymorphism here
+ -- representation polymorphism here
; let (arg_tys, _) = tcSplitFunTys body_ty
; mapM_ (checkForLevPoly LevityCheckPatSynSig . scaledThing) arg_tys
diff --git a/compiler/GHC/Tc/Module.hs b/compiler/GHC/Tc/Module.hs
index 3fdc33c5a0..56c3071ea5 100644
--- a/compiler/GHC/Tc/Module.hs
+++ b/compiler/GHC/Tc/Module.hs
@@ -2139,7 +2139,8 @@ tcRnStmt hsc_env rdr_stmt
zonked_expr <- zonkTopLExpr tc_expr ;
zonked_ids <- zonkTopBndrs bound_ids ;
- failIfErrsM ; -- we can't do the next step if there are levity polymorphism errors
+ failIfErrsM ; -- we can't do the next step if there are
+ -- representation polymorphism errors
-- test case: ghci/scripts/T13202{,a}
-- None of the Ids should be of unboxed type, because we
diff --git a/compiler/GHC/Tc/TyCl.hs b/compiler/GHC/Tc/TyCl.hs
index 8c23fef1cf..1af410fd7b 100644
--- a/compiler/GHC/Tc/TyCl.hs
+++ b/compiler/GHC/Tc/TyCl.hs
@@ -4168,7 +4168,7 @@ Some notes:
to add to the context. The problem is that this also grabs data con
wrapper Ids. These could be filtered out. But, painfully, getting
the wrapper Ids checks the DataConRep, and forcing the DataConRep
- can panic if there is a levity-polymorphic argument. This is #18534.
+ can panic if there is a representation-polymorphic argument. This is #18534.
We don't need the wrapper Ids here anyway. So the code just takes what
it needs, via child_tycons.
-}
@@ -4363,16 +4363,16 @@ checkValidDataCon dflags existential_ok tc con
-- Reason: it's really the argument of an equality constraint
; checkValidMonoType orig_res_ty
- -- If we are dealing with a newtype, we allow levity polymorphism
- -- regardless of whether or not UnliftedNewtypes is enabled. A
- -- later check in checkNewDataCon handles this, producing a
- -- better error message than checkForLevPoly would.
+ -- If we are dealing with a newtype, we allow representation
+ -- polymorphism regardless of whether or not UnliftedNewtypes
+ -- is enabled. A later check in checkNewDataCon handles this,
+ -- producing a better error message than checkForLevPoly would.
; unless (isNewTyCon tc) $
checkNoErrs $
mapM_ (checkForLevPoly LevityCheckInValidDataCon) (map scaledThing $ dataConOrigArgTys con)
-- the checkNoErrs is to prevent a panic in isVanillaDataCon
-- (called a a few lines down), which can fall over if there is a
- -- bang on a levity-polymorphic argument. This is #18534,
+ -- bang on a representation-polymorphic argument. This is #18534,
-- typecheck/should_fail/T18534
-- Extra checks for newtype data constructors. Importantly, these
@@ -4569,11 +4569,11 @@ checkValidClass cls
-- newBoard :: MonadState b m => m ()
-- Here, MonadState has a fundep m->b, so newBoard is fine
- -- a method cannot be levity polymorphic, as we have to store the
- -- method in a dictionary
+ -- a method cannot be representation-polymorphic, as we have to
+ -- store the method in a dictionary
-- example of what this prevents:
-- class BoundedX (a :: TYPE r) where minBound :: a
- -- See Note [Levity polymorphism checking] in GHC.HsToCore.Monad
+ -- See Note [Representation polymorphism checking] in GHC.HsToCore.Monad
; checkForLevPoly LevityCheckInValidClass tau1
; unless constrained_class_methods $
diff --git a/compiler/GHC/Tc/TyCl/Instance.hs b/compiler/GHC/Tc/TyCl/Instance.hs
index bbaa4cee6d..e0bff637a7 100644
--- a/compiler/GHC/Tc/TyCl/Instance.hs
+++ b/compiler/GHC/Tc/TyCl/Instance.hs
@@ -1330,7 +1330,7 @@ addDFunPrags dfun_id sc_meth_ids
con_app = mkLams dfun_bndrs $
mkApps (Var (dataConWrapId dict_con)) dict_args
-- mkApps is OK because of the checkForLevPoly call in checkValidClass
- -- See Note [Levity polymorphism checking] in GHC.HsToCore.Monad
+ -- See Note [Representation polymorphism checking] in GHC.HsToCore.Monad
dict_args = map Type inst_tys ++
[mkVarApps (Var id) dfun_bndrs | id <- sc_meth_ids]
diff --git a/compiler/GHC/Tc/Types/Constraint.hs b/compiler/GHC/Tc/Types/Constraint.hs
index 0422835ac0..0567211bfb 100644
--- a/compiler/GHC/Tc/Types/Constraint.hs
+++ b/compiler/GHC/Tc/Types/Constraint.hs
@@ -527,7 +527,7 @@ field by the type checker. The desugarer simply dereferences to get the CoreExpr
Prior to fixing #17812, we used to invent an Id to hold the erroring
expression, and then bind it during type-checking. But this does not support
-levity-polymorphic out-of-scope identifiers. See
+representation-polymorphic out-of-scope identifiers. See
typecheck/should_compile/T17812. We thus use the mutable-CoreExpr approach
described above.
diff --git a/compiler/GHC/Tc/Types/Evidence.hs b/compiler/GHC/Tc/Types/Evidence.hs
index d173fc0a23..4bda7e5354 100644
--- a/compiler/GHC/Tc/Types/Evidence.hs
+++ b/compiler/GHC/Tc/Types/Evidence.hs
@@ -231,8 +231,8 @@ data HsWrapper
-- because we can't use 'sym' to flip around these HsWrappers
-- The TcType is the "from" type of the first wrapper
-- The SDoc explains the circumstances under which we have created this
- -- WpFun, in case we run afoul of levity polymorphism restrictions in
- -- the desugarer. See Note [Levity polymorphism checking] in GHC.HsToCore.Monad
+ -- WpFun, in case we run afoul of representation polymorphism restrictions in
+ -- the desugarer. See Note [Representation polymorphism checking] in GHC.HsToCore.Monad
| WpCast TcCoercionR -- A cast: [] `cast` co
-- Guaranteed not the identity coercion
diff --git a/compiler/GHC/Tc/Utils/TcMType.hs b/compiler/GHC/Tc/Utils/TcMType.hs
index 66a05aa30e..3172a6791a 100644
--- a/compiler/GHC/Tc/Utils/TcMType.hs
+++ b/compiler/GHC/Tc/Utils/TcMType.hs
@@ -92,7 +92,7 @@ module GHC.Tc.Utils.TcMType (
candidateKindVars, partitionCandidates,
------------------------------
- -- Levity polymorphism
+ -- Representation polymorphism
ensureNotLevPoly, checkForLevPoly, checkForLevPolyX,
) where
@@ -2607,11 +2607,11 @@ tidySigSkol env cx ty tv_prs
{-
%************************************************************************
%* *
- Levity polymorphism checks
+ Representation polymorphism checks
* *
*************************************************************************
-See Note [Levity polymorphism checking] in GHC.HsToCore.Monad
+See Note [Representation polymorphism checking] in GHC.HsToCore.Monad
-}
@@ -2632,7 +2632,7 @@ ensureNotLevPoly ty provenance
-- forall a. a. See, for example, test ghci/scripts/T9140
checkForLevPoly provenance ty
- -- See Note [Levity polymorphism checking] in GHC.HsToCore.Monad
+ -- See Note [Representation polymorphism checking] in GHC.HsToCore.Monad
checkForLevPoly :: LevityCheckProvenance -> Type -> TcM ()
checkForLevPoly = checkForLevPolyX (\ty -> addDetailedDiagnostic . TcLevityPolyInType ty)
diff --git a/compiler/GHC/Tc/Utils/Unify.hs b/compiler/GHC/Tc/Utils/Unify.hs
index 633b1c17bf..4b12595f72 100644
--- a/compiler/GHC/Tc/Utils/Unify.hs
+++ b/compiler/GHC/Tc/Utils/Unify.hs
@@ -789,7 +789,7 @@ 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 is precedent for
-type errors during desuraging (such as the levity polymorphism
+type errors during desuraging (such as the representation polymorphism
restriction). An alternative would be to have a kind of constraint which can
only produce trivial evidence, then this check would happen in the constraint
solver.
diff --git a/compiler/GHC/Tc/Utils/Zonk.hs b/compiler/GHC/Tc/Utils/Zonk.hs
index b7d6f9cd27..2a38a54460 100644
--- a/compiler/GHC/Tc/Utils/Zonk.hs
+++ b/compiler/GHC/Tc/Utils/Zonk.hs
@@ -593,8 +593,8 @@ zonk_bind env (AbsBinds { abs_tvs = tyvars, abs_ev_vars = evs
, fun_matches = ms
, fun_ext = co_fn })) <- lbind
= do { new_mono_id <- updateIdTypeAndMultM (zonkTcTypeToTypeX env) mono_id
- -- Specifically /not/ zonkIdBndr; we do not
- -- want to complain about a levity-polymorphic binder
+ -- Specifically /not/ zonkIdBndr; we do not want to
+ -- complain about a representation-polymorphic binder
; (env', new_co_fn) <- zonkCoFn env co_fn
; new_ms <- zonkMatchGroup env' zonkLExpr ms
; return $ L loc $
@@ -1054,7 +1054,7 @@ zonk_cmd_top env (HsCmdTop (CmdTopTc stack_tys ty ids) cmd)
new_ids <- mapSndM (zonkExpr env) ids
massert (isLiftedTypeKind (tcTypeKind new_stack_tys))
- -- desugarer assumes that this is not levity polymorphic...
+ -- desugarer assumes that this is not representation-polymorphic...
-- but indeed it should always be lifted due to the typing
-- rules for arrows
@@ -1410,7 +1410,8 @@ zonk_pat env p@(ConPat { pat_con = L _ con
do { new_tys <- mapM (zonkTcTypeToTypeX env) tys
-- an unboxed tuple pattern (but only an unboxed tuple pattern)
- -- might have levity-polymorphic arguments. Check for this badness.
+ -- might have representation-polymorphic arguments.
+ -- Check for this badness.
; case con of
RealDataCon dc
| isUnboxedTupleTyCon (dataConTyCon dc)
diff --git a/compiler/GHC/Types/Id.hs b/compiler/GHC/Types/Id.hs
index 8a75ced92c..55ff3f9335 100644
--- a/compiler/GHC/Types/Id.hs
+++ b/compiler/GHC/Types/Id.hs
@@ -569,7 +569,7 @@ hasNoBinding id = case Var.idDetails id of
FCallId _ -> True
DataConWorkId dc -> isUnboxedTupleDataCon dc || isUnboxedSumDataCon dc
_ -> isCompulsoryUnfolding (idUnfolding id)
- -- See Note [Levity-polymorphic Ids]
+ -- See Note [Representation-polymorphic Ids]
isImplicitId :: Id -> Bool
-- ^ 'isImplicitId' tells whether an 'Id's info is implied by other
@@ -591,20 +591,20 @@ isImplicitId id
idIsFrom :: Module -> Id -> Bool
idIsFrom mod id = nameIsLocalOrFrom mod (idName id)
-{- Note [Levity-polymorphic Ids]
+{- Note [Representation-polymorphic Ids]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Some levity-polymorphic Ids must be applied and inlined, not left
+Some representation-polymorphic Ids must be applied and inlined, not left
un-saturated. Example:
unsafeCoerceId :: forall r1 r2 (a::TYPE r1) (b::TYPE r2). a -> b
This has a compulsory unfolding because we can't lambda-bind those
-arguments. But the compulsory unfolding may leave levity-polymorphic
+arguments. But the compulsory unfolding may leave representation-polymorphic
lambdas if it is not applied to enough arguments; e.g. (#14561)
bad :: forall (a :: TYPE r). a -> a
bad = unsafeCoerce#
The desugar has special magic to detect such cases: GHC.HsToCore.Expr.badUseOfLevPolyPrimop.
-And we want that magic to apply to levity-polymorphic compulsory-inline things.
+And we want that magic to apply to representation-polymorphic compulsory-inline things.
The easiest way to do this is for hasNoBinding to return True of all things
that have compulsory unfolding. Some Ids with a compulsory unfolding also
have a binding, but it does not harm to say they don't here, and its a very
diff --git a/compiler/GHC/Types/Id/Info.hs b/compiler/GHC/Types/Id/Info.hs
index 027c162198..e0204330d9 100644
--- a/compiler/GHC/Types/Id/Info.hs
+++ b/compiler/GHC/Types/Id/Info.hs
@@ -344,7 +344,7 @@ bitfieldSetArityInfo info (BitField bits) =
-- Getters
--- | When applied, will this Id ever have a levity-polymorphic type?
+-- | When applied, will this Id ever have a representation-polymorphic type?
levityInfo :: IdInfo -> LevityInfo
levityInfo = bitfieldGetLevityInfo . bitfield
@@ -719,12 +719,12 @@ instance Outputable TickBoxOp where
Note [Levity info]
~~~~~~~~~~~~~~~~~~
-Ids store whether or not they can be levity-polymorphic at any amount
-of saturation. This is helpful in optimizing the levity-polymorphism check
-done in the desugarer, where we can usually learn that something is not
-levity-polymorphic without actually figuring out its type. See
-isExprLevPoly in GHC.Core.Utils for where this info is used. Storing
-this is required to prevent perf/compiler/T5631 from blowing up.
+Ids store whether or not they can be representation-polymorphic at any amount
+of saturation. This is helpful in optimizing the representation polymorphism
+check done in the desugarer, where we can usually learn that something is not
+representation-polymorphic without actually figuring out its type.
+See isExprLevPoly in GHC.Core.Utils for where this info is used.
+Storing this is required to prevent perf/compiler/T5631 from blowing up.
-}
@@ -737,9 +737,9 @@ instance Outputable LevityInfo where
ppr NoLevityInfo = text "NoLevityInfo"
ppr NeverLevityPolymorphic = text "NeverLevityPolymorphic"
--- | Marks an IdInfo describing an Id that is never levity polymorphic (even when
--- applied). The Type is only there for checking that it's really never levity
--- polymorphic
+-- | Marks an IdInfo describing an Id that is never representation-polymorphic
+-- (even when applied). The Type is only there for checking that it's really
+-- never representation-polymorphic.
setNeverLevPoly :: HasDebugCallStack => IdInfo -> Type -> IdInfo
setNeverLevPoly info ty
= assertPpr (not (resultIsLevPoly ty)) (ppr ty) $
diff --git a/compiler/GHC/Types/Id/Make.hs b/compiler/GHC/Types/Id/Make.hs
index d179c53ed3..581e8a83dd 100644
--- a/compiler/GHC/Types/Id/Make.hs
+++ b/compiler/GHC/Types/Id/Make.hs
@@ -361,23 +361,23 @@ effect whether a wrapper is present or not:
We'd like 'map Age' to match the LHS. For this to happen, Age
must be unfolded, otherwise we'll be stuck. This is tested in T16208.
-It also allows for the posssibility of levity polymorphic newtypes
+It also allows for the posssibility of representation-polymorphic newtypes
with wrappers (with -XUnliftedNewtypes):
newtype N (a :: TYPE r) = MkN a
-With -XUnliftedNewtypes, this is allowed -- even though MkN is levity-
+With -XUnliftedNewtypes, this is allowed -- even though MkN is representation-
polymorphic. It's OK because MkN evaporates in the compiled code, becoming
just a cast. That is, it has a compulsory unfolding. As long as its
-argument is not levity-polymorphic (which it can't be, according to
-Note [Levity polymorphism invariants] in GHC.Core), and it's saturated,
-no levity-polymorphic code ends up in the code generator. The saturation
-condition is effectively checked by Note [Detecting forced eta expansion]
-in GHC.HsToCore.Expr.
+argument is not representation-polymorphic (which it can't be, according to
+Note [Representation polymorphism invariants] in GHC.Core), and it's saturated,
+no representation-polymorphic code ends up in the code generator.
+The saturation condition is effectively checked by
+Note [Detecting forced eta expansion] in GHC.HsToCore.Expr.
However, if we make a *wrapper* for a newtype, we get into trouble.
The saturation condition is no longer checked (because hasNoBinding
-returns False) and indeed we generate a forbidden levity-polymorphic
+returns False) and indeed we generate a forbidden representation-polymorphic
binding.
The solution is simple, though: just make the newtype wrappers
@@ -1529,14 +1529,14 @@ oneShotId = pcMiscPrelId oneShotName ty info
{- Note [Wired-in Ids for rebindable syntax]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The functions leftSectionId, rightSectionId are
-wired in here ONLY because they are use in a levity-polymorphic way
+wired in here ONLY because they are use in a representation-polymorphic way
by the rebindable syntax mechanism. See GHC.Rename.Expr
Note [Handling overloaded and rebindable constructs].
Alas, we can't currenly give Haskell definitions for
-levity-polymorphic functions.
+representation-polymorphic functions.
-They have Compulsory unfoldings to so that the levity polymorphism
+They have Compulsory unfoldings, so that the representation polymorphism
does not linger for long.
-}
@@ -1635,9 +1635,9 @@ Historical note:
In GHC.Tc.Gen.Expr we used to need a special typing rule for 'seq', to handle calls
whose second argument had an unboxed type, e.g. x `seq` 3#
- However, with levity polymorphism we can now give seq the type seq ::
- forall (r :: RuntimeRep) a (b :: TYPE r). a -> b -> b which handles this
- case without special treatment in the typechecker.
+ However, with representation polymorphism we can now give seq the type
+ seq :: forall (r :: RuntimeRep) a (b :: TYPE r). a -> b -> b
+ which handles this case without special treatment in the typechecker.
Note [User-defined RULES for seq]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1764,8 +1764,8 @@ and Note [Left folds via right fold]) it was determined that it would be useful
if library authors could explicitly tell the compiler that a certain lambda is
called at most once. The oneShot function allows that.
-'oneShot' is levity-polymorphic, i.e. the type variables can refer to unlifted
-types as well (#10744); e.g.
+'oneShot' is representation-polymorphic, i.e. the type variables can refer
+to unlifted types as well (#10744); e.g.
oneShot (\x:Int# -> x +# 1#)
Like most magic functions it has a compulsory unfolding, so there is no need
diff --git a/compiler/GHC/Types/RepType.hs b/compiler/GHC/Types/RepType.hs
index ec2c604e61..a1ad6b8317 100644
--- a/compiler/GHC/Types/RepType.hs
+++ b/compiler/GHC/Types/RepType.hs
@@ -318,8 +318,8 @@ fitsIn ty1 ty2
Note [RuntimeRep and PrimRep]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This Note describes the relationship between GHC.Types.RuntimeRep
-(of levity-polymorphism fame) and GHC.Core.TyCon.PrimRep, as these types
-are closely related.
+(of levity/representation polymorphism fame) and GHC.Core.TyCon.PrimRep,
+as these types are closely related.
A "primitive entity" is one that can be
* stored in one register
diff --git a/docs/users_guide/exts/linear_types.rst b/docs/users_guide/exts/linear_types.rst
index 30c7968854..8029d0ad2f 100644
--- a/docs/users_guide/exts/linear_types.rst
+++ b/docs/users_guide/exts/linear_types.rst
@@ -130,7 +130,7 @@ an error.
Printing multiplicity-polymorphic types
---------------------------------------
If :extension:`LinearTypes` is disabled, multiplicity variables in types are defaulted
-to ``Many`` when printing, in the same manner as described in :ref:`printing-levity-polymorphic-types`.
+to ``Many`` when printing, in the same manner as described in :ref:`printing-representation-polymorphic-types`.
In other words, without :extension:`LinearTypes`, multiplicity-polymorphic functions
``a %m -> b`` are printed as normal Haskell2010 functions ``a -> b``. This allows
existing libraries to be generalized to linear types in a backwards-compatible
diff --git a/docs/users_guide/exts/poly_kinds.rst b/docs/users_guide/exts/poly_kinds.rst
index 37068125de..edd1856759 100644
--- a/docs/users_guide/exts/poly_kinds.rst
+++ b/docs/users_guide/exts/poly_kinds.rst
@@ -991,7 +991,7 @@ in GADT-syntax (see :extension:`GADTSyntax`). For example::
There are a number of restrictions around these *return kinds*. The text below
considers :extension:`UnliftedNewtypes` and data families (enabled by :extension:`TypeFamilies`).
-The discussion also assumes familiarity with :ref:`levity polymorphism <runtime-rep>`.
+The discussion also assumes familiarity with :ref:`representation polymorphism <runtime-rep>`.
1. ``data`` and ``data instance`` declarations must have return kinds that
end in ``TYPE LiftedRep``. (Recall that ``Type`` is just a synonym for
@@ -1055,5 +1055,6 @@ Examples::
.. index::
single: TYPE
single: levity polymorphism
+ single: representation polymorphism
diff --git a/docs/users_guide/exts/primitives.rst b/docs/users_guide/exts/primitives.rst
index 80041dd6ad..620b12c24e 100644
--- a/docs/users_guide/exts/primitives.rst
+++ b/docs/users_guide/exts/primitives.rst
@@ -327,8 +327,8 @@ lifted types. In either of the equivalent formulations of ``A`` given above,
users would additionally have access to a coercion between ``A`` and ``Int#``.
As a consequence of the
-`levity-polymorphic binder restriction <#levity-polymorphic-restrictions>`__,
-levity-polymorphic fields are disallowed in data constructors
+`representation-polymorphic binder restriction <#representation-polymorphism-restrictions>`__,
+representation-polymorphic fields are disallowed in data constructors
of data types declared using ``data``. However, since ``newtype`` data
constructor application is implemented as a coercion instead of as function
application, this restriction does not apply to the field inside a ``newtype``
@@ -422,7 +422,7 @@ You may even declare levity-polymorphic data types: ::
While ``f`` above could reasonably be levity-polymorphic (as it evaluates its
argument either way), GHC currently disallows the more general type
``PEither @l Int Bool -> Bool``. This is a consequence of the
-`levity-polymorphic binder restriction <#levity-polymorphic-restrictions>`__,
+`representation-polymorphic binder restriction <#representation-polymorphism-restrictions>`__,
Due to `ticket 19487 <https://gitlab.haskell.org/ghc/ghc/-/issues/19487>`, it's
currently not possible to declare levity-polymorphic data types with nullary
diff --git a/docs/users_guide/exts/levity_polymorphism.rst b/docs/users_guide/exts/representation_polymorphism.rst
index 80a544e54b..3e6d250d27 100644
--- a/docs/users_guide/exts/levity_polymorphism.rst
+++ b/docs/users_guide/exts/representation_polymorphism.rst
@@ -1,12 +1,12 @@
.. _runtime-rep:
-Levity polymorphism
-===================
+Representation polymorphism
+===========================
In order to allow full flexibility in how kinds are used, it is necessary
to use the kind system to differentiate between boxed, lifted types
(normal, everyday types like ``Int`` and ``[Bool]``) and unboxed, primitive
-types (:ref:`primitives`) like ``Int#``. We thus have so-called levity
+types (:ref:`primitives`) like ``Int#``. We thus have so-called representation
polymorphism.
Here are the key definitions, all available from ``GHC.Exts``: ::
@@ -34,10 +34,25 @@ thus say that ``->`` has type
``TYPE r1 -> TYPE r2 -> TYPE LiftedRep``. The result is always lifted
because all functions are lifted in GHC.
-.. _levity-polymorphic-restrictions:
+Levity polymorphism
+-------------------
+
+A special case of representation polymorphism is levity polymorphism,
+where we abstract over a variable of kind ``Levity``, such as: ::
+
+ example :: forall (l :: Levity) (a :: TYPE (BoxedRep l)). (Int -> a) -> a
+ example f = f 42
+
+With :extension:`UnliftedDatatypes`, we can even declare levity-polymorphic
+data types: ::
+
+ type PEither :: Type -> Type -> TYPE (BoxedRep l)
+ data PEither l r = PLeft l | PRight r
+
+.. _representation-polymorphism-restrictions:
-No levity-polymorphic variables or arguments
---------------------------------------------
+No representation-polymorphic variables or arguments
+----------------------------------------------------
If GHC didn't have to compile programs that run in the real world, that
would be the end of the story. But representation polymorphism can cause
@@ -54,10 +69,10 @@ In particular, when we call ``bad``, we must somehow pass ``x`` into
``bad``. How wide (that is, how many bits) is ``x``? Is it a pointer?
What kind of register (floating-point or integral) should ``x`` go in?
It's all impossible to say, because ``x``'s type, ``a :: TYPE r1`` is
-levity polymorphic. We thus forbid such constructions, via the
+representation-polymorphic. We thus forbid such constructions, via the
following straightforward rule:
- No variable may have a levity-polymorphic type.
+ No variable may have a representation-polymorphic type.
This eliminates ``bad`` because the variable ``x`` would have a
representation-polymorphic type.
@@ -68,20 +83,20 @@ However, not all is lost. We can still do this: ::
(a -> b) -> a -> b
f $ x = f x
-Here, only ``b`` is levity polymorphic. There are no variables
-with a levity-polymorphic type. And the code generator has no
+Here, only ``b`` is representation-polymorphic. There are no variables
+with a representation-polymorphic type. And the code generator has no
trouble with this. Indeed, this is the true type of GHC's ``$`` operator,
slightly more general than the Haskell 98 version.
Because the code generator must store and move arguments as well
as variables, the logic above applies equally well to function arguments,
-which may not be levity-polymorphic.
+which may not be representation-polymorphic.
-Levity-polymorphic bottoms
---------------------------
+Representation-polymorphic bottoms
+----------------------------------
-We can use levity polymorphism to good effect with ``error``
+We can use representation polymorphism to good effect with ``error``
and ``undefined``, whose types are given here: ::
undefined :: forall (r :: RuntimeRep) (a :: TYPE r).
@@ -89,14 +104,14 @@ and ``undefined``, whose types are given here: ::
error :: forall (r :: RuntimeRep) (a :: TYPE r).
HasCallStack => String -> a
-These functions do not bind a levity-polymorphic variable, and
+These functions do not bind a representation-polymorphic variable, and
so are accepted. Their polymorphism allows users to use these to conveniently
stub out functions that return unboxed types.
-.. _printing-levity-polymorphic-types:
+.. _printing-representation-polymorphic-types:
-Printing levity-polymorphic types
----------------------------------
+Printing representation-polymorphic types
+-----------------------------------------
.. ghc-flag:: -fprint-explicit-runtime-reps
:shortdesc: Print ``RuntimeRep`` variables in types which are
@@ -108,14 +123,14 @@ Printing levity-polymorphic types
Print ``RuntimeRep`` parameters as they appear; otherwise, they are
defaulted to ``LiftedRep``.
-Most GHC users will not need to worry about levity polymorphism
-or unboxed types. For these users, seeing the levity polymorphism
+Most GHC users will not need to worry about representation polymorphism
+or unboxed types. For these users, seeing the representation polymorphism
in the type of ``$`` is unhelpful. And thus, by default, it is suppressed,
by supposing all type variables of type ``RuntimeRep`` to be ``LiftedRep``
when printing, and printing ``TYPE LiftedRep`` as ``Type`` (or ``*`` when
:extension:`StarIsType` is on).
-Should you wish to see levity polymorphism in your types, enable
+Should you wish to see representation polymorphism in your types, enable
the flag :ghc-flag:`-fprint-explicit-runtime-reps`. For example,
.. code-block:: none
diff --git a/docs/users_guide/exts/types.rst b/docs/users_guide/exts/types.rst
index 2cd9d059f5..23f0c118ab 100644
--- a/docs/users_guide/exts/types.rst
+++ b/docs/users_guide/exts/types.rst
@@ -17,7 +17,7 @@ Types
type_families
data_kinds
poly_kinds
- levity_polymorphism
+ representation_polymorphism
type_literals
type_applications
rank_polymorphism
diff --git a/libraries/base/GHC/Base.hs b/libraries/base/GHC/Base.hs
index 5eb0da3ea1..b037951fa8 100644
--- a/libraries/base/GHC/Base.hs
+++ b/libraries/base/GHC/Base.hs
@@ -1514,7 +1514,7 @@ flip f x y = f y x
-- It is also useful in higher-order situations, such as @'map' ('$' 0) xs@,
-- or @'Data.List.zipWith' ('$') fs xs@.
--
--- Note that @('$')@ is levity-polymorphic in its result type, so that
+-- Note that @('$')@ is representation-polymorphic in its result type, so that
-- @foo '$' True@ where @foo :: Bool -> Int#@ is well-typed.
{-# INLINE ($) #-}
($) :: forall r a (b :: TYPE r). (a -> b) -> a -> b
diff --git a/libraries/base/GHC/Conc/Sync.hs b/libraries/base/GHC/Conc/Sync.hs
index 353b0ac3f2..e27b40dbbd 100644
--- a/libraries/base/GHC/Conc/Sync.hs
+++ b/libraries/base/GHC/Conc/Sync.hs
@@ -629,7 +629,7 @@ newStablePtrPrimMVar (MVar m) = IO $ \s0 ->
case makeStablePtr# (unsafeCoerce# m :: PrimMVar) s0 of
-- Coerce unlifted m :: MVar# RealWorld ()
-- to lifted PrimMVar
- -- apparently because mkStablePtr is not levity-polymorphic
+ -- apparently because mkStablePtr is not representation-polymorphic
(# s1, sp #) -> (# s1, StablePtr sp #)
-----------------------------------------------------------------------------
diff --git a/libraries/base/Unsafe/Coerce.hs b/libraries/base/Unsafe/Coerce.hs
index 5ebc9c637e..0b35eeca1b 100644
--- a/libraries/base/Unsafe/Coerce.hs
+++ b/libraries/base/Unsafe/Coerce.hs
@@ -189,7 +189,7 @@ There are yet more wrinkles
and similarly for unsafeCoerceAddr, unsafeCoerceInt, etc.
-(U10) We also want a levity-polymorphic unsafeCoerce#:
+(U10) We also want a representation-polymorphic unsafeCoerce#:
unsafeCoerce# :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep)
(a :: TYPE r1) (b :: TYPE r2).
@@ -271,11 +271,11 @@ unsafeCoerce :: forall (a :: Type) (b :: Type) . a -> b
unsafeCoerce x = case unsafeEqualityProof @a @b of UnsafeRefl -> x
unsafeCoerceUnlifted :: forall (a :: TYPE ('BoxedRep 'Unlifted)) (b :: TYPE ('BoxedRep 'Unlifted)) . a -> b
--- Kind-homogeneous, but levity monomorphic (TYPE UnliftedRep)
+-- Kind-homogeneous, but representation-monomorphic (TYPE UnliftedRep)
unsafeCoerceUnlifted x = case unsafeEqualityProof @a @b of UnsafeRefl -> x
unsafeCoerceAddr :: forall (a :: TYPE 'AddrRep) (b :: TYPE 'AddrRep) . a -> b
--- Kind-homogeneous, but levity monomorphic (TYPE AddrRep)
+-- Kind-homogeneous, but representation-monomorphic (TYPE AddrRep)
unsafeCoerceAddr x = case unsafeEqualityProof @a @b of UnsafeRefl -> x
-- | Highly, terribly dangerous coercion from one representation type
diff --git a/libraries/ghc-prim/GHC/Magic.hs b/libraries/ghc-prim/GHC/Magic.hs
index cd9474271d..b032056ed3 100644
--- a/libraries/ghc-prim/GHC/Magic.hs
+++ b/libraries/ghc-prim/GHC/Magic.hs
@@ -94,7 +94,7 @@ lazy x = x
-- that would otherwise be shared are re-evaluated every time they are used. Otherwise,
-- the use of `oneShot` is safe.
--
--- 'oneShot' is representation polymorphic: the type variables may refer to lifted
+-- 'oneShot' is representation-polymorphic: the type variables may refer to lifted
-- or unlifted types.
oneShot :: forall (q :: RuntimeRep) (r :: RuntimeRep)
(a :: TYPE q) (b :: TYPE r).
@@ -108,7 +108,7 @@ oneShot f = f
-- semantically undesirable floating. `runRW#` is inlined, but only very late
-- in compilation after all floating is complete.
--- 'runRW#' is representation polymorphic: the result may have a lifted or
+-- 'runRW#' is levity-polymorphic: the result may have a lifted or
-- unlifted type.
runRW# :: forall (r :: RuntimeRep) (o :: TYPE r).
diff --git a/libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs b/libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs
index 706d4a8c6a..472a4f8557 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs
@@ -30,7 +30,7 @@ import Prelude
-- * Type synonyms
----------------------------------------------------------
--- | Levity-polymorphic since /template-haskell-2.17.0.0/.
+-- | Representation-polymorphic since /template-haskell-2.17.0.0/.
type TExpQ :: TYPE r -> Kind.Type
type TExpQ a = Q (TExp a)
diff --git a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
index ff14ea747b..5e0c75151e 100644
--- a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
+++ b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs
@@ -351,12 +351,12 @@ newtype TExp (a :: TYPE (r :: RuntimeRep)) = TExp
-- In the expression: [|| "foo" ||]
-- In the Template Haskell splice $$([|| "foo" ||])
--
--- Levity-polymorphic since /template-haskell-2.16.0.0/.
+-- Representation-polymorphic since /template-haskell-2.16.0.0/.
-- | Discard the type annotation and produce a plain Template Haskell
-- expression
--
--- Levity-polymorphic since /template-haskell-2.16.0.0/.
+-- Representation-polymorphic since /template-haskell-2.16.0.0/.
unTypeQ :: forall (r :: RuntimeRep) (a :: TYPE r) m . Quote m => m (TExp a) -> m Exp
unTypeQ m = do { TExp e <- m
; return e }
@@ -366,7 +366,7 @@ unTypeQ m = do { TExp e <- m
-- This is unsafe because GHC cannot check for you that the expression
-- really does have the type you claim it has.
--
--- Levity-polymorphic since /template-haskell-2.16.0.0/.
+-- Representation-polymorphic since /template-haskell-2.16.0.0/.
unsafeTExpCoerce :: forall (r :: RuntimeRep) (a :: TYPE r) m .
Quote m => m Exp -> m (TExp a)
unsafeTExpCoerce m = do { e <- m
@@ -913,7 +913,7 @@ sequenceQ = sequence
-- > data Bar a = Bar1 a (Bar a) | Bar2 String
-- > deriving Lift
--
--- Levity-polymorphic since /template-haskell-2.16.0.0/.
+-- Representation-polymorphic since /template-haskell-2.16.0.0/.
class Lift (t :: TYPE r) where
-- | Turn a value into a Template Haskell expression, suitable for use in
-- a splice.
diff --git a/testsuite/tests/codeGen/should_fail/T13233.stderr b/testsuite/tests/codeGen/should_fail/T13233.stderr
index 2609e41d97..a00ccd536a 100644
--- a/testsuite/tests/codeGen/should_fail/T13233.stderr
+++ b/testsuite/tests/codeGen/should_fail/T13233.stderr
@@ -1,20 +1,22 @@
T13233.hs:14:11: error:
- Cannot use function with levity-polymorphic arguments:
+ Cannot use function with representation-polymorphic arguments:
(#,#) :: a -> a -> (# a, a #)
- (Note that levity-polymorphic primops such as 'coerce' and unboxed tuples
- are eta-expanded internally because they must occur fully saturated.
+ (Note that representation-polymorphic primops,
+ such as 'coerce' and unboxed tuples, are eta-expanded
+ internally because they must occur fully saturated.
Use -fprint-typechecker-elaboration to display the full expression.)
- Levity-polymorphic arguments:
+ Representation-polymorphic arguments:
a :: TYPE rep
a :: TYPE rep
T13233.hs:22:16: error:
- Cannot use function with levity-polymorphic arguments:
+ Cannot use function with representation-polymorphic arguments:
(#,#) :: a -> b -> (# a, b #)
- (Note that levity-polymorphic primops such as 'coerce' and unboxed tuples
- are eta-expanded internally because they must occur fully saturated.
+ (Note that representation-polymorphic primops,
+ such as 'coerce' and unboxed tuples, are eta-expanded
+ internally because they must occur fully saturated.
Use -fprint-typechecker-elaboration to display the full expression.)
- Levity-polymorphic arguments:
+ Representation-polymorphic arguments:
a :: TYPE rep1
b :: TYPE rep2
diff --git a/testsuite/tests/codeGen/should_fail/T13233_elab.stderr b/testsuite/tests/codeGen/should_fail/T13233_elab.stderr
index 1b84b9bf95..6242873514 100644
--- a/testsuite/tests/codeGen/should_fail/T13233_elab.stderr
+++ b/testsuite/tests/codeGen/should_fail/T13233_elab.stderr
@@ -1,14 +1,14 @@
T13233_elab.hs:17:11: error:
- Cannot use function with levity-polymorphic arguments:
+ Cannot use function with representation-polymorphic arguments:
(#,#) @rep @rep @a @a :: a -> a -> (# a, a #)
- Levity-polymorphic arguments:
+ Representation-polymorphic arguments:
a :: TYPE rep
a :: TYPE rep
T13233_elab.hs:25:16: error:
- Cannot use function with levity-polymorphic arguments:
+ Cannot use function with representation-polymorphic arguments:
(#,#) @rep1 @rep2 @a @b :: a -> b -> (# a, b #)
- Levity-polymorphic arguments:
+ Representation-polymorphic arguments:
a :: TYPE rep1
b :: TYPE rep2
diff --git a/testsuite/tests/dependent/should_fail/T11473.stderr b/testsuite/tests/dependent/should_fail/T11473.stderr
index 3252452eb2..431c2dff92 100644
--- a/testsuite/tests/dependent/should_fail/T11473.stderr
+++ b/testsuite/tests/dependent/should_fail/T11473.stderr
@@ -1,6 +1,6 @@
T11473.hs:19:7: error:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: a
Kind: TYPE r
In the type of binder ‘x’
diff --git a/testsuite/tests/ghci/should_run/UnboxedTuples/Common.hs-incl b/testsuite/tests/ghci/should_run/UnboxedTuples/Common.hs-incl
index 6931397f09..46cefa025e 100644
--- a/testsuite/tests/ghci/should_run/UnboxedTuples/Common.hs-incl
+++ b/testsuite/tests/ghci/should_run/UnboxedTuples/Common.hs-incl
@@ -305,7 +305,7 @@ tuple_v6_a :: TV6 -> Int -> Double -> Int -> Double
tuple_v6_a f x y z w = case f x y z w of (# x', _, y', _, z', _, w', _ #) ->
(I# x', D# y', I# z', D# w')
--- some levity polymorphic things
+-- some representation-polymorphic things
{-# NOINLINE lev_poly #-}
lev_poly :: forall r a (b :: TYPE r).
(a -> a -> a -> a ->
diff --git a/testsuite/tests/ghci/should_run/UnboxedTuples/UnboxedTuples.hs b/testsuite/tests/ghci/should_run/UnboxedTuples/UnboxedTuples.hs
index 1bbaf39837..ae6dc4dd3d 100644
--- a/testsuite/tests/ghci/should_run/UnboxedTuples/UnboxedTuples.hs
+++ b/testsuite/tests/ghci/should_run/UnboxedTuples/UnboxedTuples.hs
@@ -118,7 +118,7 @@ main = do
B.tuple_v6 O.tuple_v6
(\f -> f 601 602 603 604)
- -- levity polymorphic
+ -- representation-polymorphic
print $ B.lev_poly_a B.lev_poly B.tuple3 991
print $ B.lev_poly_a B.lev_poly O.tuple3 992
print $ B.lev_poly_a O.lev_poly B.tuple3 993
diff --git a/testsuite/tests/polykinds/T14561.hs b/testsuite/tests/polykinds/T14561.hs
index 4be0812c68..dede8ba2f8 100644
--- a/testsuite/tests/polykinds/T14561.hs
+++ b/testsuite/tests/polykinds/T14561.hs
@@ -10,7 +10,7 @@ import Unsafe.Coerce
badId :: forall r (a :: TYPE r). a -> a
badId = unsafeCoerce#
--- Un-saturated application of a levity-polymorphic
+-- Un-saturated application of a representation-polymorphic
-- function that must be eta-expanded
goodId :: forall (a :: Type). a -> a
diff --git a/testsuite/tests/polykinds/T14561.stderr b/testsuite/tests/polykinds/T14561.stderr
index 16e3be33b2..098a31127f 100644
--- a/testsuite/tests/polykinds/T14561.stderr
+++ b/testsuite/tests/polykinds/T14561.stderr
@@ -1,8 +1,9 @@
T14561.hs:12:9: error:
- Cannot use function with levity-polymorphic arguments:
+ Cannot use function with representation-polymorphic arguments:
unsafeCoerce# :: a -> a
- (Note that levity-polymorphic primops such as 'coerce' and unboxed tuples
- are eta-expanded internally because they must occur fully saturated.
+ (Note that representation-polymorphic primops,
+ such as 'coerce' and unboxed tuples, are eta-expanded
+ internally because they must occur fully saturated.
Use -fprint-typechecker-elaboration to display the full expression.)
- Levity-polymorphic arguments: a :: TYPE r
+ Representation-polymorphic arguments: a :: TYPE r
diff --git a/testsuite/tests/th/T19709a.stderr b/testsuite/tests/th/T19709a.stderr
index 4cb72aeed7..6594949d2b 100644
--- a/testsuite/tests/th/T19709a.stderr
+++ b/testsuite/tests/th/T19709a.stderr
@@ -1,6 +1,6 @@
T19709a.hs:8:14: error:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: a
Kind: TYPE r
In the type of binder ‘x’
diff --git a/testsuite/tests/th/T19709b.hs b/testsuite/tests/th/T19709b.hs
index afc9ed5769..629172a892 100644
--- a/testsuite/tests/th/T19709b.hs
+++ b/testsuite/tests/th/T19709b.hs
@@ -6,7 +6,7 @@ import GHC.Exts
import Language.Haskell.TH
$( let levfun :: forall (r :: RuntimeRep) (a :: TYPE r). a -> ()
- levfun = error "e1" -- NB: this, so far, is OK: no levity-polymorphic binder
+ levfun = error "e1" -- NB: this, so far, is OK: no representation-polymorphic binder
- in levfun (error @Any "e2") -- but this is very naughty: levity-polymorphic argument
+ in levfun (error @Any "e2") -- but this is very naughty: representation-polymorphic argument
`seq` return [] )
diff --git a/testsuite/tests/th/T19709b.stderr b/testsuite/tests/th/T19709b.stderr
index 78405ebaea..fb2d55a917 100644
--- a/testsuite/tests/th/T19709b.stderr
+++ b/testsuite/tests/th/T19709b.stderr
@@ -1,6 +1,6 @@
T19709b.hs:11:14: error:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: Any
Kind: TYPE Any
In the type of expression: (error @Any "e2")
diff --git a/testsuite/tests/typecheck/should_fail/LevPolyLet.stderr b/testsuite/tests/typecheck/should_fail/LevPolyLet.stderr
index 8d01f4028b..73d37dae84 100644
--- a/testsuite/tests/typecheck/should_fail/LevPolyLet.stderr
+++ b/testsuite/tests/typecheck/should_fail/LevPolyLet.stderr
@@ -1,5 +1,5 @@
LevPolyLet.hs:18:7:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: a
Kind: TYPE ('BoxedRep v)
In the type of binder ‘x’
diff --git a/testsuite/tests/typecheck/should_fail/T11724.stderr b/testsuite/tests/typecheck/should_fail/T11724.stderr
index dbdbb6fdef..2971b27597 100644
--- a/testsuite/tests/typecheck/should_fail/T11724.stderr
+++ b/testsuite/tests/typecheck/should_fail/T11724.stderr
@@ -1,6 +1,6 @@
T11724.hs:7:44: error:
- • A levity-polymorphic type is not allowed here:
+ • A representation-polymorphic type is not allowed here:
Type: a
Kind: TYPE r
• In the definition of data constructor ‘Foo’
diff --git a/testsuite/tests/typecheck/should_fail/T12709.stderr b/testsuite/tests/typecheck/should_fail/T12709.stderr
index 9d79d8dd0c..f8da5ea120 100644
--- a/testsuite/tests/typecheck/should_fail/T12709.stderr
+++ b/testsuite/tests/typecheck/should_fail/T12709.stderr
@@ -1,24 +1,24 @@
T12709.hs:28:13: error:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: a
Kind: TYPE rep
In the type of expression: 1
T12709.hs:28:17: error:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: a
Kind: TYPE rep
In the type of expression: 2
T12709.hs:28:21: error:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: a
Kind: TYPE rep
In the type of expression: 3
T12709.hs:28:25: error:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: a
Kind: TYPE rep
In the type of expression: 4
diff --git a/testsuite/tests/typecheck/should_fail/T12973.stderr b/testsuite/tests/typecheck/should_fail/T12973.stderr
index a6d97009cd..f062b1e222 100644
--- a/testsuite/tests/typecheck/should_fail/T12973.stderr
+++ b/testsuite/tests/typecheck/should_fail/T12973.stderr
@@ -1,12 +1,12 @@
T12973.hs:13:7: error:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: a
Kind: TYPE r
In the type of expression: 3
T12973.hs:13:11: error:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: a
Kind: TYPE r
In the type of expression: 4
diff --git a/testsuite/tests/typecheck/should_fail/T13105.stderr b/testsuite/tests/typecheck/should_fail/T13105.stderr
index c54327ef70..5d2c74a85d 100644
--- a/testsuite/tests/typecheck/should_fail/T13105.stderr
+++ b/testsuite/tests/typecheck/should_fail/T13105.stderr
@@ -1,6 +1,6 @@
T13105.hs:22:8: error:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: Rep Int
Kind: TYPE (RepRep Int)
In the type of binder ‘n’
diff --git a/testsuite/tests/typecheck/should_fail/T13929.stderr b/testsuite/tests/typecheck/should_fail/T13929.stderr
index d1e1f63dd9..8fc7edab78 100644
--- a/testsuite/tests/typecheck/should_fail/T13929.stderr
+++ b/testsuite/tests/typecheck/should_fail/T13929.stderr
@@ -1,24 +1,24 @@
T13929.hs:29:27: error:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: GUnboxed f rf
Kind: TYPE rf
In the type of expression: gunbox x
T13929.hs:29:37: error:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: GUnboxed g rg
Kind: TYPE rg
In the type of expression: gunbox y
T13929.hs:33:24:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: GUnboxed f rf
Kind: TYPE rf
In the type of expression: gunbox l
T13929.hs:34:26:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: GUnboxed g rg
Kind: TYPE rg
In the type of expression: gunbox r
diff --git a/testsuite/tests/typecheck/should_fail/T17021.stderr b/testsuite/tests/typecheck/should_fail/T17021.stderr
index 52f48d2bed..8944876b3f 100644
--- a/testsuite/tests/typecheck/should_fail/T17021.stderr
+++ b/testsuite/tests/typecheck/should_fail/T17021.stderr
@@ -1,14 +1,16 @@
T17021.hs:18:5: error:
- Cannot use function with levity-polymorphic arguments:
+ Cannot use function with representation-polymorphic arguments:
MkT :: Int -> T
- (Note that levity-polymorphic primops such as 'coerce' and unboxed tuples
- are eta-expanded internally because they must occur fully saturated.
+ (Note that representation-polymorphic primops,
+ such as 'coerce' and unboxed tuples, are eta-expanded
+ internally because they must occur fully saturated.
Use -fprint-typechecker-elaboration to display the full expression.)
- Levity-polymorphic arguments: Int :: TYPE (Id ('BoxedRep 'Lifted))
+ Representation-polymorphic arguments:
+ Int :: TYPE (Id ('BoxedRep 'Lifted))
T17021.hs:18:9: error:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: Int
Kind: TYPE (Id ('BoxedRep 'Lifted))
In the type of expression: 42
diff --git a/testsuite/tests/typecheck/should_fail/T17360.stderr b/testsuite/tests/typecheck/should_fail/T17360.stderr
index 9eccd7fe29..e3ed36f381 100644
--- a/testsuite/tests/typecheck/should_fail/T17360.stderr
+++ b/testsuite/tests/typecheck/should_fail/T17360.stderr
@@ -1,6 +1,6 @@
T17360.hs:11:5: error:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: Id a
Kind: TYPE r
In the type of binder ‘x’
diff --git a/testsuite/tests/typecheck/should_fail/T17817.stderr b/testsuite/tests/typecheck/should_fail/T17817.stderr
index 56753cb34b..8d1548e2c8 100644
--- a/testsuite/tests/typecheck/should_fail/T17817.stderr
+++ b/testsuite/tests/typecheck/should_fail/T17817.stderr
@@ -1,13 +1,14 @@
T17817.hs:16:10: error:
- Cannot use function with levity-polymorphic arguments:
+ Cannot use function with representation-polymorphic arguments:
mkWeak#
:: a
-> b
-> (State# RealWorld -> (# State# RealWorld, c #))
-> State# RealWorld
-> (# State# RealWorld, Weak# b #)
- (Note that levity-polymorphic primops such as 'coerce' and unboxed tuples
- are eta-expanded internally because they must occur fully saturated.
+ (Note that representation-polymorphic primops,
+ such as 'coerce' and unboxed tuples, are eta-expanded
+ internally because they must occur fully saturated.
Use -fprint-typechecker-elaboration to display the full expression.)
- Levity-polymorphic arguments: a :: TYPE ('BoxedRep l)
+ Representation-polymorphic arguments: a :: TYPE ('BoxedRep l)
diff --git a/testsuite/tests/typecheck/should_fail/T17817_elab.stderr b/testsuite/tests/typecheck/should_fail/T17817_elab.stderr
index aaa48448d2..0a03cf6080 100644
--- a/testsuite/tests/typecheck/should_fail/T17817_elab.stderr
+++ b/testsuite/tests/typecheck/should_fail/T17817_elab.stderr
@@ -1,10 +1,10 @@
T17817_elab.hs:17:10: error:
- Cannot use function with levity-polymorphic arguments:
+ Cannot use function with representation-polymorphic arguments:
mkWeak# @l @a @b @c
:: a
-> b
-> (State# RealWorld -> (# State# RealWorld, c #))
-> State# RealWorld
-> (# State# RealWorld, Weak# b #)
- Levity-polymorphic arguments: a :: TYPE ('BoxedRep l)
+ Representation-polymorphic arguments: a :: TYPE ('BoxedRep l)
diff --git a/testsuite/tests/typecheck/should_fail/T18534.stderr b/testsuite/tests/typecheck/should_fail/T18534.stderr
index cd78fbf819..b5db0f02bc 100644
--- a/testsuite/tests/typecheck/should_fail/T18534.stderr
+++ b/testsuite/tests/typecheck/should_fail/T18534.stderr
@@ -1,6 +1,6 @@
T18534.hs:7:27: error:
- • A levity-polymorphic type is not allowed here:
+ • A representation-polymorphic type is not allowed here:
Type: a
Kind: TYPE r
• In the definition of data constructor ‘Test’
diff --git a/testsuite/tests/typecheck/should_fail/T19615.stderr b/testsuite/tests/typecheck/should_fail/T19615.stderr
index b2e4f40231..c4a82800d2 100644
--- a/testsuite/tests/typecheck/should_fail/T19615.stderr
+++ b/testsuite/tests/typecheck/should_fail/T19615.stderr
@@ -1,6 +1,6 @@
T19615.hs:17:20: error:
- A levity-polymorphic type is not allowed here:
+ A representation-polymorphic type is not allowed here:
Type: b
Kind: TYPE r'
In the type of expression: (f x)
diff --git a/testsuite/tests/typecheck/should_fail/UnliftedNewtypesCoerceFail.stderr b/testsuite/tests/typecheck/should_fail/UnliftedNewtypesCoerceFail.stderr
index 1c39c9133b..9867100a63 100644
--- a/testsuite/tests/typecheck/should_fail/UnliftedNewtypesCoerceFail.stderr
+++ b/testsuite/tests/typecheck/should_fail/UnliftedNewtypesCoerceFail.stderr
@@ -1,8 +1,9 @@
UnliftedNewtypesCoerceFail.hs:15:8: error:
- Cannot use function with levity-polymorphic arguments:
+ Cannot use function with representation-polymorphic arguments:
coerce :: x -> y
- (Note that levity-polymorphic primops such as 'coerce' and unboxed tuples
- are eta-expanded internally because they must occur fully saturated.
+ (Note that representation-polymorphic primops,
+ such as 'coerce' and unboxed tuples, are eta-expanded
+ internally because they must occur fully saturated.
Use -fprint-typechecker-elaboration to display the full expression.)
- Levity-polymorphic arguments: x :: TYPE rep
+ Representation-polymorphic arguments: x :: TYPE rep
diff --git a/testsuite/tests/typecheck/should_fail/UnliftedNewtypesLevityBinder.stderr b/testsuite/tests/typecheck/should_fail/UnliftedNewtypesLevityBinder.stderr
index 70746fd60a..d82a35d122 100644
--- a/testsuite/tests/typecheck/should_fail/UnliftedNewtypesLevityBinder.stderr
+++ b/testsuite/tests/typecheck/should_fail/UnliftedNewtypesLevityBinder.stderr
@@ -1,8 +1,9 @@
UnliftedNewtypesLevityBinder.hs:16:7: error:
- Cannot use function with levity-polymorphic arguments:
+ Cannot use function with representation-polymorphic arguments:
IdentC :: a -> Ident a
- (Note that levity-polymorphic primops such as 'coerce' and unboxed tuples
- are eta-expanded internally because they must occur fully saturated.
+ (Note that representation-polymorphic primops,
+ such as 'coerce' and unboxed tuples, are eta-expanded
+ internally because they must occur fully saturated.
Use -fprint-typechecker-elaboration to display the full expression.)
- Levity-polymorphic arguments: a :: TYPE r
+ Representation-polymorphic arguments: a :: TYPE r
diff --git a/testsuite/tests/typecheck/should_run/EtaExpandLevPoly.hs b/testsuite/tests/typecheck/should_run/EtaExpandLevPoly.hs
index 82553b4ff2..cd011a71c9 100644
--- a/testsuite/tests/typecheck/should_run/EtaExpandLevPoly.hs
+++ b/testsuite/tests/typecheck/should_run/EtaExpandLevPoly.hs
@@ -8,7 +8,7 @@ import GHC.Exts
data G a where
MkG :: G (TupleRep [BoxedRep Lifted, IntRep])
--- tests that we don't eta-expand functions that are levity-polymorphic
+-- tests that we don't eta-expand functions that are representation-polymorphic
-- see CoreArity.mkEtaWW
foo :: forall a (b :: TYPE a). G a -> b -> b
foo MkG = (\x -> x) :: forall (c :: TYPE (TupleRep [BoxedRep Lifted, IntRep])). c -> c
@@ -16,7 +16,7 @@ foo MkG = (\x -> x) :: forall (c :: TYPE (TupleRep [BoxedRep Lifted, IntRep])).
data H a where
MkH :: H IntRep
--- tests that we don't push coercions that make args levity-polymorphic
+-- tests that we don't push coercions that make args representation-polymorphic
-- see Simplify.simplCast
bar :: forall (r :: RuntimeRep) (a :: TYPE r). H r -> (a -> a -> (# a, a #)) -> a -> (# a, a #)
bar MkH = (\f x -> f x x) :: forall (b :: TYPE IntRep). (b -> b -> (# b, b #)) -> b -> (# b, b #)
diff --git a/utils/haddock b/utils/haddock
-Subproject caee7fce3032ac08c38a591de5e31f37eedf681
+Subproject 126beaef07cdcbe8aeea248cc555e8a3057de82