Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
-
56b32c5a
by sheaf at 2025-08-12T10:00:19-04:00
26 changed files:
- compiler/GHC/Builtin/PrimOps/Ids.hs
- compiler/GHC/HsToCore.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Concrete.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Types/Id/Make.hs
- testsuite/tests/corelint/LintEtaExpand.stderr
- testsuite/tests/indexed-types/should_fail/T5439.stderr
- testsuite/tests/partial-sigs/should_compile/T10403.stderr
- testsuite/tests/partial-sigs/should_fail/T10615.stderr
- + testsuite/tests/rep-poly/NoEtaRequired.hs
- testsuite/tests/rep-poly/T21906.stderr
- testsuite/tests/rep-poly/all.T
- + testsuite/tests/typecheck/should_compile/T26225.hs
- + testsuite/tests/typecheck/should_compile/T26225b.hs
- testsuite/tests/typecheck/should_compile/all.T
- − testsuite/tests/typecheck/should_fail/T12563.stderr
- testsuite/tests/typecheck/should_fail/T14618.stderr
- testsuite/tests/typecheck/should_fail/T6022.stderr
- testsuite/tests/typecheck/should_fail/T8883.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/typecheck/should_fail/tcfail140.stderr
Changes:
| ... | ... | @@ -99,7 +99,7 @@ computePrimOpConcTyVarsFromType nm tyvars arg_tys _res_ty = mkNameEnv concs |
| 99 | 99 | | tv `elem` [ runtimeRep1TyVar, runtimeRep2TyVar, runtimeRep3TyVar
|
| 100 | 100 | , levity1TyVar, levity2TyVar ]
|
| 101 | 101 | = listToMaybe $
|
| 102 | - mapMaybe (\ (i,arg) -> Argument i <$> positiveKindPos_maybe tv arg)
|
|
| 102 | + mapMaybe (\ (i,arg) -> mkArgPos i <$> positiveKindPos_maybe tv arg)
|
|
| 103 | 103 | (zip [1..] arg_tys)
|
| 104 | 104 | | otherwise
|
| 105 | 105 | = Nothing
|
| ... | ... | @@ -124,7 +124,7 @@ negativeKindPos_maybe tv ty |
| 124 | 124 | )
|
| 125 | 125 | where
|
| 126 | 126 | recur (pos, scaled_ty)
|
| 127 | - = Argument pos <$> positiveKindPos_maybe tv (scaledThing scaled_ty)
|
|
| 127 | + = mkArgPos pos <$> positiveKindPos_maybe tv (scaledThing scaled_ty)
|
|
| 128 | 128 | -- (assumes we don't have any function types nested inside other types)
|
| 129 | 129 | |
| 130 | 130 | -- | Does this type variable appear in a kind in a positive position in the
|
| ... | ... | @@ -145,7 +145,7 @@ positiveKindPos_maybe tv ty |
| 145 | 145 | )
|
| 146 | 146 | where
|
| 147 | 147 | recur (pos, scaled_ty)
|
| 148 | - = Argument pos <$> negativeKindPos_maybe tv (scaledThing scaled_ty)
|
|
| 148 | + = mkArgPos pos <$> negativeKindPos_maybe tv (scaledThing scaled_ty)
|
|
| 149 | 149 | -- (assumes we don't have any function types nested inside other types)
|
| 150 | 150 | finish ty
|
| 151 | 151 | | tv `elemVarSet` tyCoVarsOfType (typeKind ty)
|
| ... | ... | @@ -39,7 +39,7 @@ import GHC.HsToCore.Coverage |
| 39 | 39 | import GHC.HsToCore.Docs
|
| 40 | 40 | |
| 41 | 41 | import GHC.Tc.Types
|
| 42 | -import GHC.Tc.Types.Origin ( Position(..) )
|
|
| 42 | +import GHC.Tc.Types.Origin ( Position(..), mkArgPos )
|
|
| 43 | 43 | import GHC.Tc.Utils.Monad ( finalSafeMode, fixSafeInstances )
|
| 44 | 44 | import GHC.Tc.Module ( runTcInteractive )
|
| 45 | 45 | |
| ... | ... | @@ -780,7 +780,7 @@ mkUnsafeCoercePrimPair _old_id old_expr |
| 780 | 780 | arity = 1
|
| 781 | 781 | |
| 782 | 782 | concs = mkRepPolyIdConcreteTyVars
|
| 783 | - [((mkTyVarTy openAlphaTyVar, Argument 1 Top), runtimeRep1TyVar)]
|
|
| 783 | + [((mkTyVarTy openAlphaTyVar, mkArgPos 1 Top), runtimeRep1TyVar)]
|
|
| 784 | 784 | unsafeCoercePrimName
|
| 785 | 785 | |
| 786 | 786 | id = mkExportedLocalId (RepPolyId concs) unsafeCoercePrimName ty `setIdInfo` info
|
| ... | ... | @@ -430,7 +430,8 @@ tcApp rn_expr exp_res_ty |
| 430 | 430 | -- Step 5.2: typecheck the arguments, and monomorphise
|
| 431 | 431 | -- any un-unified instantiation variables
|
| 432 | 432 | ; tc_args <- tcValArgs DoQL inst_args
|
| 433 | - -- Step 5.3: typecheck the arguments
|
|
| 433 | + -- Step 5.3: zonk to expose the polymophism hidden under
|
|
| 434 | + -- QuickLook instantiation variables in `app_res_rho`
|
|
| 434 | 435 | ; app_res_rho <- liftZonkM $ zonkTcType app_res_rho
|
| 435 | 436 | -- Step 5.4: subsumption check against the expected type
|
| 436 | 437 | ; res_wrap <- checkResultTy rn_expr tc_head inst_args
|
| ... | ... | @@ -463,6 +464,8 @@ finishApp tc_head@(tc_fun,_) tc_args app_res_rho res_wrap |
| 463 | 464 | ; traceTc "End tcApp }" (ppr tc_fun)
|
| 464 | 465 | ; return (mkHsWrap res_wrap res_expr) }
|
| 465 | 466 | |
| 467 | +-- | Connect up the inferred type of an application with the expected type.
|
|
| 468 | +-- This is usually just a unification, but with deep subsumption there is more to do.
|
|
| 466 | 469 | checkResultTy :: HsExpr GhcRn
|
| 467 | 470 | -> (HsExpr GhcTc, AppCtxt) -- Head
|
| 468 | 471 | -> [HsExprArg p] -- Arguments, just error messages
|
| ... | ... | @@ -470,11 +473,29 @@ checkResultTy :: HsExpr GhcRn |
| 470 | 473 | -- expose foralls, but maybe not deeply instantiated
|
| 471 | 474 | -> ExpRhoType -- Expected type; this is deeply skolemised
|
| 472 | 475 | -> TcM HsWrapper
|
| 473 | --- Connect up the inferred type of the application with the expected type
|
|
| 474 | --- This is usually just a unification, but with deep subsumption there is more to do
|
|
| 475 | -checkResultTy _ _ _ app_res_rho (Infer inf_res)
|
|
| 476 | - = do { co <- fillInferResult app_res_rho inf_res
|
|
| 477 | - ; return (mkWpCastN co) }
|
|
| 476 | +checkResultTy rn_expr _fun _inst_args app_res_rho (Infer inf_res)
|
|
| 477 | + = fillInferResultDS (exprCtOrigin rn_expr) app_res_rho inf_res
|
|
| 478 | + -- See Note [Deeply instantiate in checkResultTy when inferring]
|
|
| 479 | + |
|
| 480 | +{- Note [Deeply instantiate in checkResultTy when inferring]
|
|
| 481 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 482 | +To accept the following program (T26225b) with -XDeepSubsumption, we need to
|
|
| 483 | +deeply instantiate when inferring in checkResultTy:
|
|
| 484 | + |
|
| 485 | + f :: Int -> (forall a. a->a)
|
|
| 486 | + g :: Int -> Bool -> Bool
|
|
| 487 | + |
|
| 488 | + test b =
|
|
| 489 | + case b of
|
|
| 490 | + True -> f
|
|
| 491 | + False -> g
|
|
| 492 | + |
|
| 493 | +If we don't deeply instantiate in the branches of the case expression, we will
|
|
| 494 | +try to unify the type of 'f' with that of 'g', which fails. If we instead
|
|
| 495 | +deeply instantiate 'f', we will fill the 'InferResult' with 'Int -> alpha -> alpha'
|
|
| 496 | +which then successfully unifies with the type of 'g' when we come to fill the
|
|
| 497 | +'InferResult' hole a second time for the second case branch.
|
|
| 498 | +-}
|
|
| 478 | 499 | |
| 479 | 500 | checkResultTy rn_expr (tc_fun, fun_ctxt) inst_args app_res_rho (Check res_ty)
|
| 480 | 501 | -- Unify with expected type from the context
|
| ... | ... | @@ -502,8 +523,6 @@ checkResultTy rn_expr (tc_fun, fun_ctxt) inst_args app_res_rho (Check res_ty) |
| 502 | 523 | -- Even though both app_res_rho and res_ty are rho-types,
|
| 503 | 524 | -- they may have nested polymorphism, so if deep subsumption
|
| 504 | 525 | -- is on we must call tcSubType.
|
| 505 | - -- Zonk app_res_rho first, because QL may have instantiated some
|
|
| 506 | - -- delta variables to polytypes, and tcSubType doesn't expect that
|
|
| 507 | 526 | do { wrap <- tcSubTypeDS rn_expr app_res_rho res_ty
|
| 508 | 527 | ; traceTc "checkResultTy 2 }" (ppr app_res_rho $$ ppr res_ty)
|
| 509 | 528 | ; return wrap } }
|
| ... | ... | @@ -1056,7 +1056,8 @@ tcSynArgA orig op sigma_ty arg_shapes res_shape thing_inside |
| 1056 | 1056 | tc_syn_arg _ (SynFun {}) _
|
| 1057 | 1057 | = pprPanic "tcSynArgA hits a SynFun" (ppr orig)
|
| 1058 | 1058 | tc_syn_arg res_ty (SynType the_ty) thing_inside
|
| 1059 | - = do { wrap <- tcSubType orig GenSigCtxt res_ty the_ty
|
|
| 1059 | + = do { wrap <- addSubTypeCtxt res_ty the_ty $
|
|
| 1060 | + tcSubType orig GenSigCtxt Nothing res_ty the_ty
|
|
| 1060 | 1061 | ; result <- thing_inside []
|
| 1061 | 1062 | ; return (result, wrap) }
|
| 1062 | 1063 |
| ... | ... | @@ -946,7 +946,7 @@ Terms are eagerly instantiated. This means that if you say |
| 946 | 946 | |
| 947 | 947 | then `id` gets instantiated to have type alpha -> alpha. The variable
|
| 948 | 948 | alpha is then unconstrained and regeneralized. So we may well end up with
|
| 949 | - x = /\x. id @a
|
|
| 949 | + x = /\a. id @a
|
|
| 950 | 950 | But we cannot do this in types, as we have no type-level lambda.
|
| 951 | 951 | |
| 952 | 952 | So, we must be careful only to instantiate at the last possible moment, when
|
| ... | ... | @@ -954,9 +954,15 @@ we're sure we're never going to want the lost polymorphism again. This is done |
| 954 | 954 | in calls to `tcInstInvisibleTyBinders`; a particular case in point is in
|
| 955 | 955 | `checkExpectedKind`.
|
| 956 | 956 | |
| 957 | +For example, suppose we have:
|
|
| 958 | + Actual: ∀ k2 k. k -> k2 -> k
|
|
| 959 | + Expected: ∀ k. k -> Type -> k
|
|
| 960 | +We must very delicately instantiate just k2 to kappa, and then unify
|
|
| 961 | + (∀ k. k -> Type -> k) ~ (∀ k. k -> kappa -> k)
|
|
| 962 | + |
|
| 957 | 963 | Otherwise, we are careful /not/ to instantiate. For example:
|
| 958 | -* at a variable in `tcTyVar`
|
|
| 959 | -* in `tcInferLHsTypeUnsaturated`, which is used by :kind in GHCi.
|
|
| 964 | + * at a variable in `tcTyVar`
|
|
| 965 | + * in `tcInferLHsTypeUnsaturated`, which is used by :kind in GHCi.
|
|
| 960 | 966 | |
| 961 | 967 | ************************************************************************
|
| 962 | 968 | * *
|
| ... | ... | @@ -1977,6 +1983,8 @@ checkExpKind :: HsType GhcRn -> TcType -> TcKind -> ExpKind -> TcM TcType |
| 1977 | 1983 | checkExpKind rn_ty ty ki (Check ki') =
|
| 1978 | 1984 | checkExpectedKind rn_ty ty ki ki'
|
| 1979 | 1985 | checkExpKind _rn_ty ty ki (Infer cell) = do
|
| 1986 | + -- NB: do not instantiate.
|
|
| 1987 | + -- See Note [Do not always instantiate eagerly in types]
|
|
| 1980 | 1988 | co <- fillInferResult ki cell
|
| 1981 | 1989 | pure (ty `mkCastTy` co)
|
| 1982 | 1990 |
| ... | ... | @@ -199,28 +199,44 @@ instance Monoid HsWrapper where |
| 199 | 199 | mempty = WpHole
|
| 200 | 200 | |
| 201 | 201 | (<.>) :: HsWrapper -> HsWrapper -> HsWrapper
|
| 202 | -WpHole <.> c = c
|
|
| 203 | -c <.> WpHole = c
|
|
| 204 | -c1 <.> c2 = c1 `WpCompose` c2
|
|
| 205 | - |
|
| 206 | --- | Smart constructor to create a 'WpFun' 'HsWrapper'.
|
|
| 202 | +WpHole <.> c = c
|
|
| 203 | +c <.> WpHole = c
|
|
| 204 | +WpCast c1 <.> WpCast c2 = WpCast (c1 `mkTransCo` c2)
|
|
| 205 | + -- If we can represent the HsWrapper as a cast, try to do so: this may avoid
|
|
| 206 | + -- unnecessary eta-expansion (see 'mkWpFun').
|
|
| 207 | +c1 <.> c2 = c1 `WpCompose` c2
|
|
| 208 | + |
|
| 209 | +-- | Smart constructor to create a 'WpFun' 'HsWrapper', which avoids introducing
|
|
| 210 | +-- a lambda abstraction if the two supplied wrappers are either identities or
|
|
| 211 | +-- casts.
|
|
| 212 | +--
|
|
| 213 | +-- PRECONDITION: either:
|
|
| 207 | 214 | --
|
| 208 | --- PRECONDITION: the "from" type of the first wrapper must have a syntactically
|
|
| 209 | --- fixed RuntimeRep (see Note [Fixed RuntimeRep] in GHC.Tc.Utils.Concrete).
|
|
| 215 | +-- 1. both of the 'HsWrapper's are identities or casts, or
|
|
| 216 | +-- 2. both the "from" and "to" types of the first wrapper have a syntactically
|
|
| 217 | +-- fixed RuntimeRep (see Note [Fixed RuntimeRep] in GHC.Tc.Utils.Concrete).
|
|
| 210 | 218 | mkWpFun :: HsWrapper -> HsWrapper
|
| 211 | 219 | -> Scaled TcTypeFRR -- ^ the "from" type of the first wrapper
|
| 212 | - -- MUST have a fixed RuntimeRep
|
|
| 213 | 220 | -> TcType -- ^ Either "from" type or "to" type of the second wrapper
|
| 214 | 221 | -- (used only when the second wrapper is the identity)
|
| 215 | 222 | -> HsWrapper
|
| 216 | - -- NB: we can't check that the argument type has a fixed RuntimeRep with an assertion,
|
|
| 217 | - -- because of [Wrinkle: Typed Template Haskell] in Note [hasFixedRuntimeRep]
|
|
| 218 | - -- in GHC.Tc.Utils.Concrete.
|
|
| 219 | 223 | mkWpFun WpHole WpHole _ _ = WpHole
|
| 220 | 224 | mkWpFun WpHole (WpCast co2) (Scaled w t1) _ = WpCast (mk_wp_fun_co w (mkRepReflCo t1) co2)
|
| 221 | 225 | mkWpFun (WpCast co1) WpHole (Scaled w _) t2 = WpCast (mk_wp_fun_co w (mkSymCo co1) (mkRepReflCo t2))
|
| 222 | 226 | mkWpFun (WpCast co1) (WpCast co2) (Scaled w _) _ = WpCast (mk_wp_fun_co w (mkSymCo co1) co2)
|
| 223 | -mkWpFun co1 co2 t1 _ = WpFun co1 co2 t1
|
|
| 227 | +mkWpFun w_arg w_res t1 _ =
|
|
| 228 | + -- In this case, we will desugar to a lambda
|
|
| 229 | + --
|
|
| 230 | + -- \x. w_res[ e w_arg[x] ]
|
|
| 231 | + --
|
|
| 232 | + -- To satisfy Note [Representation polymorphism invariants] in GHC.Core,
|
|
| 233 | + -- it must be the case that both the lambda bound variable x and the function
|
|
| 234 | + -- argument w_arg[x] have a fixed runtime representation, i.e. that both the
|
|
| 235 | + -- "from" and "to" types of the first wrapper "w_arg" have a fixed runtime representation.
|
|
| 236 | + --
|
|
| 237 | + -- Unfortunately, we can't check this with an assertion here, because of
|
|
| 238 | + -- [Wrinkle: Typed Template Haskell] in Note [hasFixedRuntimeRep] in GHC.Tc.Utils.Concrete.
|
|
| 239 | + WpFun w_arg w_res t1
|
|
| 224 | 240 | |
| 225 | 241 | mkWpEta :: [Id] -> HsWrapper -> HsWrapper
|
| 226 | 242 | -- (mkWpEta [x1, x2] wrap) [e]
|
| 1 | 1 | {-# LANGUAGE DataKinds #-}
|
| 2 | +{-# LANGUAGE DerivingStrategies #-}
|
|
| 2 | 3 | {-# LANGUAGE FlexibleContexts #-}
|
| 3 | 4 | {-# LANGUAGE GADTs #-}
|
| 4 | 5 | {-# LANGUAGE PolyKinds #-}
|
| 5 | 6 | {-# LANGUAGE StandaloneKindSignatures #-}
|
| 6 | -{-# LANGUAGE TypeFamilies #-}
|
|
| 7 | +{-# LANGUAGE TypeFamilyDependencies #-}
|
|
| 7 | 8 | |
| 8 | 9 | -- | Describes the provenance of types as they flow through the type-checker.
|
| 9 | 10 | -- The datatypes here are mainly used for error message generation.
|
| ... | ... | @@ -39,7 +40,7 @@ module GHC.Tc.Types.Origin ( |
| 39 | 40 | mkFRRUnboxedTuple, mkFRRUnboxedSum,
|
| 40 | 41 | |
| 41 | 42 | -- ** FixedRuntimeRep origin for rep-poly 'Id's
|
| 42 | - RepPolyId(..), Polarity(..), Position(..),
|
|
| 43 | + RepPolyId(..), Polarity(..), Position(..), mkArgPos,
|
|
| 43 | 44 | |
| 44 | 45 | -- ** Arrow command FixedRuntimeRep origin
|
| 45 | 46 | FRRArrowContext(..), pprFRRArrowContext,
|
| ... | ... | @@ -78,7 +79,7 @@ import GHC.Utils.Outputable |
| 78 | 79 | import GHC.Utils.Panic
|
| 79 | 80 | import GHC.Stack
|
| 80 | 81 | import GHC.Utils.Monad
|
| 81 | -import GHC.Utils.Misc( HasDebugCallStack )
|
|
| 82 | +import GHC.Utils.Misc( HasDebugCallStack, nTimes )
|
|
| 82 | 83 | import GHC.Types.Unique
|
| 83 | 84 | import GHC.Types.Unique.Supply
|
| 84 | 85 | |
| ... | ... | @@ -1188,7 +1189,7 @@ data FixedRuntimeRepContext |
| 1188 | 1189 | -- See 'FRRArrowContext' for more details.
|
| 1189 | 1190 | | FRRArrow !FRRArrowContext
|
| 1190 | 1191 | |
| 1191 | - -- | A representation-polymorphic check arising from a call
|
|
| 1192 | + -- | A representation-polymorphism check arising from a call
|
|
| 1192 | 1193 | -- to 'matchExpectedFunTys' or 'matchActualFunTy'.
|
| 1193 | 1194 | --
|
| 1194 | 1195 | -- See 'ExpectedFunTyOrigin' for more details.
|
| ... | ... | @@ -1197,6 +1198,13 @@ data FixedRuntimeRepContext |
| 1197 | 1198 | !Int
|
| 1198 | 1199 | -- ^ argument position (1-indexed)
|
| 1199 | 1200 | |
| 1201 | + -- | A representation-polymorphism check arising from eta-expansion
|
|
| 1202 | + -- performed as part of deep subsumption.
|
|
| 1203 | + | forall p. FRRDeepSubsumption
|
|
| 1204 | + { frrDSExpected :: Bool
|
|
| 1205 | + , frrDSPosition :: Position p
|
|
| 1206 | + }
|
|
| 1207 | + |
|
| 1200 | 1208 | -- | The description of a representation-polymorphic 'Id'.
|
| 1201 | 1209 | data RepPolyId
|
| 1202 | 1210 | -- | A representation-polymorphic 'PrimOp'.
|
| ... | ... | @@ -1234,8 +1242,8 @@ pprFixedRuntimeRepContext (FRRRecordUpdate lbl _arg) |
| 1234 | 1242 | pprFixedRuntimeRepContext (FRRBinder binder)
|
| 1235 | 1243 | = sep [ text "The binder"
|
| 1236 | 1244 | , quotes (ppr binder) ]
|
| 1237 | -pprFixedRuntimeRepContext (FRRRepPolyId nm id what)
|
|
| 1238 | - = pprFRRRepPolyId id nm what
|
|
| 1245 | +pprFixedRuntimeRepContext (FRRRepPolyId nm id pos)
|
|
| 1246 | + = text "The" <+> ppr pos <+> text "of" <+> pprRepPolyId id nm
|
|
| 1239 | 1247 | pprFixedRuntimeRepContext FRRPatBind
|
| 1240 | 1248 | = text "The pattern binding"
|
| 1241 | 1249 | pprFixedRuntimeRepContext FRRPatSynArg
|
| ... | ... | @@ -1277,6 +1285,13 @@ pprFixedRuntimeRepContext (FRRArrow arrowContext) |
| 1277 | 1285 | = pprFRRArrowContext arrowContext
|
| 1278 | 1286 | pprFixedRuntimeRepContext (FRRExpectedFunTy funTyOrig arg_pos)
|
| 1279 | 1287 | = pprExpectedFunTyOrigin funTyOrig arg_pos
|
| 1288 | +pprFixedRuntimeRepContext (FRRDeepSubsumption is_exp pos)
|
|
| 1289 | + = hsep [ text "The", what, text "type of the"
|
|
| 1290 | + , ppr (Argument pos)
|
|
| 1291 | + , text "of the eta-expansion"
|
|
| 1292 | + ]
|
|
| 1293 | + where
|
|
| 1294 | + what = if is_exp then text "expected" else text "actual"
|
|
| 1280 | 1295 | |
| 1281 | 1296 | instance Outputable FixedRuntimeRepContext where
|
| 1282 | 1297 | ppr = pprFixedRuntimeRepContext
|
| ... | ... | @@ -1305,34 +1320,117 @@ data ArgPos |
| 1305 | 1320 | * *
|
| 1306 | 1321 | ********************************************************************* -}
|
| 1307 | 1322 | |
| 1323 | +{- Note [Positional information in representation-polymorphism errors]
|
|
| 1324 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1325 | +Consider an invalid instantiation of the 'catch#' primop:
|
|
| 1326 | + |
|
| 1327 | + catch#
|
|
| 1328 | + :: forall {q :: RuntimeRep} {k :: Levity} (a :: TYPE q)
|
|
| 1329 | + (b :: TYPE (BoxedRep k)).
|
|
| 1330 | + (State# RealWorld -> (# State# RealWorld, a #))
|
|
| 1331 | + -> (b -> State# RealWorld -> (# State# RealWorld, a #))
|
|
| 1332 | + -> State# RealWorld
|
|
| 1333 | + -> (# State# RealWorld, a #)
|
|
| 1334 | + |
|
| 1335 | + boo :: forall r (a :: TYPE r). ...
|
|
| 1336 | + boo = catch# @a
|
|
| 1337 | + |
|
| 1338 | +The instantiation is invalid because we insist that the quantified RuntimeRep
|
|
| 1339 | +type variable 'q' be instantiated to a concrete RuntimeRep, as per
|
|
| 1340 | +Note [Representation-polymorphism checking built-ins] in GHC.Tc.Utils.Concrete.
|
|
| 1341 | + |
|
| 1342 | +We report this as the following error message:
|
|
| 1343 | + |
|
| 1344 | + The result of the first argument of the primop ‘catch#’ does not have a fixed runtime representation.
|
|
| 1345 | + Its type is: (a :: TYPE r).
|
|
| 1346 | + |
|
| 1347 | +The positional information in this message, namely "The result of the first argument",
|
|
| 1348 | +is produced by using the 'Position' datatype. In this case:
|
|
| 1349 | + |
|
| 1350 | + pos :: Position Neg
|
|
| 1351 | + pos = Result (Argument Top)
|
|
| 1352 | + ppr pos = "result of the first argument"
|
|
| 1353 | + |
|
| 1354 | +Other examples:
|
|
| 1355 | + |
|
| 1356 | + pos2 :: Position Neg
|
|
| 1357 | + pos2 = Argument (Result (Result Top))
|
|
| 1358 | + ppr pos2 = "3rd argument"
|
|
| 1359 | + |
|
| 1360 | + pos3 :: Position Pos
|
|
| 1361 | + pos3 = Argument (Result (Argument (Result Top)))
|
|
| 1362 | + ppr pos3 = "2nd argument of the 2nd argument"
|
|
| 1363 | + |
|
| 1364 | +It's useful to keep track at the type-level whether we are in a positive or
|
|
| 1365 | +negative position in the type, as for primops we can usually tolerate
|
|
| 1366 | +representation-polymorphism in positive positions, but not in negative ones;
|
|
| 1367 | +for example
|
|
| 1368 | + |
|
| 1369 | + ($) :: forall {r} (a :: Type) (b :: TYPE r). (a -> b) -> a -> b
|
|
| 1370 | + |
|
| 1371 | + |
|
| 1372 | +This positional information is (currently) used to report representation-polymorphism
|
|
| 1373 | +errors in precisely the following two situations:
|
|
| 1374 | + |
|
| 1375 | + 1. Representation-polymorphic Ids with no binding, as described in
|
|
| 1376 | + Note [Representation-polymorphic Ids with no binding] in GHC.Tc.Utils.Concrete.
|
|
| 1377 | + |
|
| 1378 | + This uses the 'FRRRepPolyId' constructor of 'FixedRuntimeRepContext'.
|
|
| 1379 | + |
|
| 1380 | + 2. When inserting eta-expansions for deep subsumption.
|
|
| 1381 | + See Wrinkle [Representation-polymorphism checking during subtyping] in
|
|
| 1382 | + Note [FunTy vs FunTy case in tc_sub_type_deep] in GHC.Tc.Utils.Unify.
|
|
| 1383 | + |
|
| 1384 | + This uses the 'FRRDeepSubsumption' constructor of 'FixedRuntimeRepContext'.
|
|
| 1385 | +-}
|
|
| 1386 | + |
|
| 1387 | +-- | Are we in a positive (covariant) or negative (contravariant) position?
|
|
| 1388 | +--
|
|
| 1389 | +-- See Note [Positional information in representation-polymorphism errors].
|
|
| 1308 | 1390 | data Polarity = Pos | Neg
|
| 1309 | 1391 | |
| 1392 | +-- | Flip the 'Polarity': turn positive into negative and vice-versa.
|
|
| 1310 | 1393 | type FlipPolarity :: Polarity -> Polarity
|
| 1311 | -type family FlipPolarity p where
|
|
| 1394 | +type family FlipPolarity p = r | r -> p where
|
|
| 1312 | 1395 | FlipPolarity Pos = Neg
|
| 1313 | 1396 | FlipPolarity Neg = Pos
|
| 1314 | 1397 | |
| 1315 | 1398 | -- | A position in which a type variable appears in a type;
|
| 1316 | 1399 | -- in particular, whether it appears in a positive or a negative position.
|
| 1400 | +--
|
|
| 1401 | +-- See Note [Positional information in representation-polymorphism errors].
|
|
| 1317 | 1402 | type Position :: Polarity -> Hs.Type
|
| 1318 | 1403 | data Position p where
|
| 1319 | - -- | In the @i@-th argument of a function arrow
|
|
| 1320 | - Argument :: Int -> Position (FlipPolarity p) -> Position p
|
|
| 1404 | + -- | In the argument of a function arrow
|
|
| 1405 | + Argument :: Position p -> Position (FlipPolarity p)
|
|
| 1321 | 1406 | -- | In the result of a function arrow
|
| 1322 | 1407 | Result :: Position p -> Position p
|
| 1323 | 1408 | -- | At the top level of a type
|
| 1324 | 1409 | Top :: Position Pos
|
| 1325 | - |
|
| 1326 | -pprFRRRepPolyId :: RepPolyId -> Name -> Position Neg -> SDoc
|
|
| 1327 | -pprFRRRepPolyId id nm (Argument i pos) =
|
|
| 1328 | - text "The" <+> what <+> speakNth i <+> text "argument of" <+> pprRepPolyId id nm
|
|
| 1410 | +deriving stock instance Show (Position p)
|
|
| 1411 | +instance Outputable (Position p) where
|
|
| 1412 | + ppr = go 1
|
|
| 1413 | + where
|
|
| 1414 | + go :: Int -> Position q -> SDoc
|
|
| 1415 | + go i (Argument (Result pos)) = go (i+1) (Argument pos)
|
|
| 1416 | + go i (Argument pos) = speakNth i <+> text "argument" <+> aux 1 pos
|
|
| 1417 | + go i (Result (Result pos)) = go i (Result pos)
|
|
| 1418 | + go i (Result pos) = text "result" <+> aux i pos
|
|
| 1419 | + go _ Top = text "top-level"
|
|
| 1420 | + |
|
| 1421 | + aux :: Int -> Position q -> SDoc
|
|
| 1422 | + aux i pos = case pos of { Top -> empty; _ -> text "of the" <+> go i pos }
|
|
| 1423 | + |
|
| 1424 | +-- | @'mkArgPos' i p@ makes the 'Position' @p@ relative to the @ith@ argument.
|
|
| 1425 | +--
|
|
| 1426 | +-- Example: @ppr (mkArgPos 3 (Result Top)) == "in the result of the 3rd argument"@.
|
|
| 1427 | +mkArgPos :: Int -> Position p -> Position (FlipPolarity p)
|
|
| 1428 | +mkArgPos i = go
|
|
| 1329 | 1429 | where
|
| 1330 | - what = case pos of
|
|
| 1331 | - Top -> empty
|
|
| 1332 | - Result {} -> text "return type of the"
|
|
| 1333 | - _ -> text "nested return type inside the"
|
|
| 1334 | -pprFRRRepPolyId id nm (Result {}) =
|
|
| 1335 | - text "The result of" <+> pprRepPolyId id nm
|
|
| 1430 | + go :: Position p -> Position (FlipPolarity p)
|
|
| 1431 | + go Top = Argument $ nTimes (i-1) Result Top
|
|
| 1432 | + go (Result p) = Result $ go p
|
|
| 1433 | + go (Argument p) = Argument $ go p
|
|
| 1336 | 1434 | |
| 1337 | 1435 | pprRepPolyId :: RepPolyId -> Name -> SDoc
|
| 1338 | 1436 | pprRepPolyId id nm = id_desc <+> quotes (ppr nm)
|
| ... | ... | @@ -803,7 +803,7 @@ idConcreteTvs id |
| 803 | 803 | = mkNameEnv
|
| 804 | 804 | [(tyVarName a_rep, ConcreteFRR $ FixedRuntimeRepOrigin (mkTyVarTy a)
|
| 805 | 805 | $ FRRRepPolyId unsafeCoercePrimName RepPolyFunction
|
| 806 | - $ Argument 1 Top)]
|
|
| 806 | + $ mkArgPos 1 Top)]
|
|
| 807 | 807 | |
| 808 | 808 | | otherwise
|
| 809 | 809 | = idDetailsConcreteTvs $ idDetails id |
| 1 | +{-# LANGUAGE DataKinds #-}
|
|
| 1 | 2 | {-# LANGUAGE DeriveTraversable #-}
|
| 2 | 3 | {-# LANGUAGE DerivingStrategies #-}
|
| 3 | 4 | {-# LANGUAGE LambdaCase #-}
|
| ... | ... | @@ -18,6 +19,7 @@ module GHC.Tc.Utils.Unify ( |
| 18 | 19 | -- Full-blown subsumption
|
| 19 | 20 | tcWrapResult, tcWrapResultO, tcWrapResultMono,
|
| 20 | 21 | tcSubType, tcSubTypeSigma, tcSubTypePat, tcSubTypeDS,
|
| 22 | + addSubTypeCtxt,
|
|
| 21 | 23 | tcSubTypeAmbiguity, tcSubMult,
|
| 22 | 24 | checkConstraints, checkTvConstraints,
|
| 23 | 25 | buildImplicationFor, buildTvImplication, emitResidualTvConstraint,
|
| ... | ... | @@ -25,9 +27,10 @@ module GHC.Tc.Utils.Unify ( |
| 25 | 27 | -- Skolemisation
|
| 26 | 28 | DeepSubsumptionFlag(..), getDeepSubsumptionFlag, isRhoTyDS,
|
| 27 | 29 | tcSkolemise, tcSkolemiseCompleteSig, tcSkolemiseExpectedType,
|
| 30 | + deeplyInstantiate,
|
|
| 28 | 31 | |
| 29 | 32 | -- Various unifications
|
| 30 | - unifyType, unifyKind, unifyInvisibleType, unifyExpectedType,
|
|
| 33 | + unifyType, unifyKind, unifyInvisibleType,
|
|
| 31 | 34 | unifyExprType, unifyTypeAndEmit, promoteTcType,
|
| 32 | 35 | swapOverTyVars, touchabilityTest, checkTopShape, lhsPriority,
|
| 33 | 36 | UnifyEnv(..), updUEnvLoc, setUEnvRole,
|
| ... | ... | @@ -57,7 +60,7 @@ module GHC.Tc.Utils.Unify ( |
| 57 | 60 | |
| 58 | 61 | simpleUnifyCheck, UnifyCheckCaller(..), SimpleUnifyResult(..),
|
| 59 | 62 | |
| 60 | - fillInferResult,
|
|
| 63 | + fillInferResult, fillInferResultDS
|
|
| 61 | 64 | ) where
|
| 62 | 65 | |
| 63 | 66 | import GHC.Prelude
|
| ... | ... | @@ -796,12 +799,14 @@ matchExpectedFunTys :: forall a. |
| 796 | 799 | -- Postcondition:
|
| 797 | 800 | -- If exp_ty is Check {}, then [ExpPatType] and ExpRhoType results are all Check{}
|
| 798 | 801 | -- If exp_ty is Infer {}, then [ExpPatType] and ExpRhoType results are all Infer{}
|
| 799 | -matchExpectedFunTys herald _ arity (Infer inf_res) thing_inside
|
|
| 802 | +matchExpectedFunTys herald _ctxt arity (Infer inf_res) thing_inside
|
|
| 800 | 803 | = do { arg_tys <- mapM (new_infer_arg_ty herald) [1 .. arity]
|
| 801 | 804 | ; res_ty <- newInferExpType
|
| 802 | 805 | ; result <- thing_inside (map ExpFunPatTy arg_tys) res_ty
|
| 803 | 806 | ; arg_tys <- mapM (\(Scaled m t) -> Scaled m <$> readExpType t) arg_tys
|
| 804 | 807 | ; res_ty <- readExpType res_ty
|
| 808 | + -- NB: mkScaledFunTys arg_tys res_ty does not contain any foralls
|
|
| 809 | + -- (even nested ones), so no need to instantiate.
|
|
| 805 | 810 | ; co <- fillInferResult (mkScaledFunTys arg_tys res_ty) inf_res
|
| 806 | 811 | ; return (mkWpCastN co, result) }
|
| 807 | 812 | |
| ... | ... | @@ -1223,7 +1228,21 @@ unification variable. We discard the evidence. |
| 1223 | 1228 | |
| 1224 | 1229 | -}
|
| 1225 | 1230 | |
| 1226 | - |
|
| 1231 | +-- | A version of 'fillInferResult' that also performs deep instantiation
|
|
| 1232 | +-- when deep subsumption is enabled.
|
|
| 1233 | +--
|
|
| 1234 | +-- See also Note [Instantiation of InferResult].
|
|
| 1235 | +fillInferResultDS :: CtOrigin -> TcRhoType -> InferResult -> TcM HsWrapper
|
|
| 1236 | +fillInferResultDS ct_orig rho inf_res
|
|
| 1237 | + = do { massertPpr (isRhoTy rho) $
|
|
| 1238 | + vcat [ text "fillInferResultDS: input type is not a rho-type"
|
|
| 1239 | + , text "ty:" <+> ppr rho ]
|
|
| 1240 | + ; ds_flag <- getDeepSubsumptionFlag
|
|
| 1241 | + ; case ds_flag of
|
|
| 1242 | + Shallow -> mkWpCastN <$> fillInferResult rho inf_res
|
|
| 1243 | + Deep -> do { (inst_wrap, rho') <- deeplyInstantiate ct_orig rho
|
|
| 1244 | + ; co <- fillInferResult rho' inf_res
|
|
| 1245 | + ; return (mkWpCastN co <.> inst_wrap) } }
|
|
| 1227 | 1246 | |
| 1228 | 1247 | {-
|
| 1229 | 1248 | ************************************************************************
|
| ... | ... | @@ -1290,27 +1309,34 @@ tcWrapResultO :: CtOrigin -> HsExpr GhcRn -> HsExpr GhcTc -> TcSigmaType -> ExpR |
| 1290 | 1309 | tcWrapResultO orig rn_expr expr actual_ty res_ty
|
| 1291 | 1310 | = do { traceTc "tcWrapResult" (vcat [ text "Actual: " <+> ppr actual_ty
|
| 1292 | 1311 | , text "Expected:" <+> ppr res_ty ])
|
| 1293 | - ; wrap <- tcSubTypeNC orig GenSigCtxt (Just $ HsExprRnThing rn_expr) actual_ty res_ty
|
|
| 1312 | + ; wrap <- tcSubType orig GenSigCtxt (Just $ HsExprRnThing rn_expr) actual_ty res_ty
|
|
| 1294 | 1313 | ; return (mkHsWrap wrap expr) }
|
| 1295 | 1314 | |
| 1296 | -tcWrapResultMono :: HsExpr GhcRn -> HsExpr GhcTc
|
|
| 1297 | - -> TcRhoType -- Actual -- a rho-type not a sigma-type
|
|
| 1298 | - -> ExpRhoType -- Expected
|
|
| 1299 | - -> TcM (HsExpr GhcTc)
|
|
| 1300 | --- A version of tcWrapResult to use when the actual type is a
|
|
| 1315 | +-- | A version of 'tcWrapResult' to use when the actual type is a
|
|
| 1301 | 1316 | -- rho-type, so nothing to instantiate; just go straight to unify.
|
| 1302 | --- It means we don't need to pass in a CtOrigin
|
|
| 1317 | +-- It means we don't need to pass in a CtOrigin.
|
|
| 1318 | +tcWrapResultMono :: HasDebugCallStack
|
|
| 1319 | + => HsExpr GhcRn -> HsExpr GhcTc
|
|
| 1320 | + -> TcRhoType -- ^ Actual; a rho-type, not a sigma-type
|
|
| 1321 | + -> ExpRhoType -- ^ Expected
|
|
| 1322 | + -> TcM (HsExpr GhcTc)
|
|
| 1303 | 1323 | tcWrapResultMono rn_expr expr act_ty res_ty
|
| 1304 | - = assertPpr (isRhoTy act_ty) (ppr act_ty $$ ppr rn_expr) $
|
|
| 1305 | - do { co <- unifyExpectedType rn_expr act_ty res_ty
|
|
| 1324 | + = do { co <- tcSubTypeMono rn_expr act_ty res_ty
|
|
| 1306 | 1325 | ; return (mkHsWrapCo co expr) }
|
| 1307 | 1326 | |
| 1308 | -unifyExpectedType :: HsExpr GhcRn
|
|
| 1309 | - -> TcRhoType -- Actual -- a rho-type not a sigma-type
|
|
| 1310 | - -> ExpRhoType -- Expected
|
|
| 1311 | - -> TcM TcCoercionN
|
|
| 1312 | -unifyExpectedType rn_expr act_ty exp_ty
|
|
| 1313 | - = case exp_ty of
|
|
| 1327 | +-- | A version of 'tcSubType' to use when the actual type is a rho-type,
|
|
| 1328 | +-- so that no instantiation is needed.
|
|
| 1329 | +tcSubTypeMono :: HasDebugCallStack
|
|
| 1330 | + => HsExpr GhcRn
|
|
| 1331 | + -> TcRhoType -- ^ Actual; a rho-type, not a sigma-type
|
|
| 1332 | + -> ExpRhoType -- ^ Expected
|
|
| 1333 | + -> TcM TcCoercionN
|
|
| 1334 | +tcSubTypeMono rn_expr act_ty exp_ty
|
|
| 1335 | + = assertPpr (isDeepRhoTy act_ty)
|
|
| 1336 | + (vcat [ text "Actual type is not a (deep) rho-type."
|
|
| 1337 | + , text "act_ty:" <+> ppr act_ty
|
|
| 1338 | + , text "rn_expr:" <+> ppr rn_expr]) $
|
|
| 1339 | + case exp_ty of
|
|
| 1314 | 1340 | Infer inf_res -> fillInferResult act_ty inf_res
|
| 1315 | 1341 | Check exp_ty -> unifyType (Just $ HsExprRnThing rn_expr) act_ty exp_ty
|
| 1316 | 1342 | |
| ... | ... | @@ -1331,46 +1357,39 @@ tcSubTypePat _ _ (Infer inf_res) ty_expected |
| 1331 | 1357 | ; return (mkWpCastN (mkSymCo co)) }
|
| 1332 | 1358 | |
| 1333 | 1359 | ---------------
|
| 1334 | -tcSubType :: CtOrigin -> UserTypeCtxt
|
|
| 1335 | - -> TcSigmaType -- ^ Actual
|
|
| 1336 | - -> ExpRhoType -- ^ Expected
|
|
| 1337 | - -> TcM HsWrapper
|
|
| 1338 | --- Checks that 'actual' is more polymorphic than 'expected'
|
|
| 1339 | -tcSubType orig ctxt ty_actual ty_expected
|
|
| 1340 | - = addSubTypeCtxt ty_actual ty_expected $
|
|
| 1341 | - do { traceTc "tcSubType" (vcat [pprUserTypeCtxt ctxt, ppr ty_actual, ppr ty_expected])
|
|
| 1342 | - ; tcSubTypeNC orig ctxt Nothing ty_actual ty_expected }
|
|
| 1343 | 1360 | |
| 1344 | ----------------
|
|
| 1361 | +-- | A subtype check that performs deep subsumption.
|
|
| 1362 | +-- See also 'tcSubTypeMono', for when no instantiation is required.
|
|
| 1345 | 1363 | tcSubTypeDS :: HsExpr GhcRn
|
| 1346 | 1364 | -> TcRhoType -- Actual type -- a rho-type not a sigma-type
|
| 1347 | 1365 | -> TcRhoType -- Expected type
|
| 1348 | 1366 | -- DeepSubsumption <=> when checking, this type
|
| 1349 | 1367 | -- is deeply skolemised
|
| 1350 | 1368 | -> TcM HsWrapper
|
| 1351 | --- Similar signature to unifyExpectedType; does deep subsumption
|
|
| 1352 | 1369 | -- Only one call site, in GHC.Tc.Gen.App.tcApp
|
| 1353 | 1370 | tcSubTypeDS rn_expr act_rho exp_rho
|
| 1354 | - = tc_sub_type_deep (unifyExprType rn_expr) orig GenSigCtxt act_rho exp_rho
|
|
| 1371 | + = tc_sub_type_deep Top (unifyExprType rn_expr) orig GenSigCtxt act_rho exp_rho
|
|
| 1355 | 1372 | where
|
| 1356 | 1373 | orig = exprCtOrigin rn_expr
|
| 1357 | 1374 | |
| 1358 | 1375 | ---------------
|
| 1359 | -tcSubTypeNC :: CtOrigin -- ^ Used when instantiating
|
|
| 1360 | - -> UserTypeCtxt -- ^ Used when skolemising
|
|
| 1361 | - -> Maybe TypedThing -- ^ The expression that has type 'actual' (if known)
|
|
| 1362 | - -> TcSigmaType -- ^ Actual type
|
|
| 1363 | - -> ExpRhoType -- ^ Expected type
|
|
| 1364 | - -> TcM HsWrapper
|
|
| 1365 | -tcSubTypeNC inst_orig ctxt m_thing ty_actual res_ty
|
|
| 1376 | + |
|
| 1377 | +-- | Checks that the 'actual' type is more polymorphic than the 'expected' type.
|
|
| 1378 | +tcSubType :: CtOrigin -- ^ Used when instantiating
|
|
| 1379 | + -> UserTypeCtxt -- ^ Used when skolemising
|
|
| 1380 | + -> Maybe TypedThing -- ^ The expression that has type 'actual' (if known)
|
|
| 1381 | + -> TcSigmaType -- ^ Actual type
|
|
| 1382 | + -> ExpRhoType -- ^ Expected type
|
|
| 1383 | + -> TcM HsWrapper
|
|
| 1384 | +tcSubType inst_orig ctxt m_thing ty_actual res_ty
|
|
| 1366 | 1385 | = case res_ty of
|
| 1367 | 1386 | Check ty_expected -> tc_sub_type (unifyType m_thing) inst_orig ctxt
|
| 1368 | 1387 | ty_actual ty_expected
|
| 1369 | 1388 | |
| 1370 | 1389 | Infer inf_res -> do { (wrap, rho) <- topInstantiate inst_orig ty_actual
|
| 1371 | 1390 | -- See Note [Instantiation of InferResult]
|
| 1372 | - ; co <- fillInferResult rho inf_res
|
|
| 1373 | - ; return (mkWpCastN co <.> wrap) }
|
|
| 1391 | + ; inst <- fillInferResultDS inst_orig rho inf_res
|
|
| 1392 | + ; return (inst <.> wrap) }
|
|
| 1374 | 1393 | |
| 1375 | 1394 | ---------------
|
| 1376 | 1395 | tcSubTypeSigma :: CtOrigin -- where did the actual type arise / why are we
|
| ... | ... | @@ -1388,9 +1407,9 @@ tcSubTypeAmbiguity :: UserTypeCtxt -- Where did this type arise |
| 1388 | 1407 | -> TcSigmaType -> TcSigmaType -> TcM HsWrapper
|
| 1389 | 1408 | -- See Note [Ambiguity check and deep subsumption]
|
| 1390 | 1409 | tcSubTypeAmbiguity ctxt ty_actual ty_expected
|
| 1391 | - = tc_sub_type_ds Shallow (unifyType Nothing)
|
|
| 1392 | - (AmbiguityCheckOrigin ctxt)
|
|
| 1393 | - ctxt ty_actual ty_expected
|
|
| 1410 | + = tc_sub_type_ds Top Shallow (unifyType Nothing)
|
|
| 1411 | + (AmbiguityCheckOrigin ctxt)
|
|
| 1412 | + ctxt ty_actual ty_expected
|
|
| 1394 | 1413 | |
| 1395 | 1414 | ---------------
|
| 1396 | 1415 | addSubTypeCtxt :: TcType -> ExpType -> TcM a -> TcM a
|
| ... | ... | @@ -1411,8 +1430,9 @@ addSubTypeCtxt ty_actual ty_expected thing_inside |
| 1411 | 1430 | |
| 1412 | 1431 | {- Note [Instantiation of InferResult]
|
| 1413 | 1432 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 1414 | -We now always instantiate before filling in InferResult, so that
|
|
| 1415 | -the result is a TcRhoType: see #17173 for discussion.
|
|
| 1433 | +When typechecking expressions (not types, not patterns), we always instantiate
|
|
| 1434 | +before filling in InferResult, so that the result is a TcRhoType.
|
|
| 1435 | +See #17173 for discussion.
|
|
| 1416 | 1436 | |
| 1417 | 1437 | For example:
|
| 1418 | 1438 | |
| ... | ... | @@ -1444,6 +1464,9 @@ For example: |
| 1444 | 1464 | There is one place where we don't want to instantiate eagerly,
|
| 1445 | 1465 | namely in GHC.Tc.Module.tcRnExpr, which implements GHCi's :type
|
| 1446 | 1466 | command. See Note [Implementing :type] in GHC.Tc.Module.
|
| 1467 | + |
|
| 1468 | +This also means that, if DeepSubsumption is enabled, we should also instantiate
|
|
| 1469 | +deeply; we do this by using fillInferResultDS.
|
|
| 1447 | 1470 | -}
|
| 1448 | 1471 | |
| 1449 | 1472 | ---------------
|
| ... | ... | @@ -1464,16 +1487,17 @@ tc_sub_type :: (TcType -> TcType -> TcM TcCoercionN) -- How to unify |
| 1464 | 1487 | ----------------------
|
| 1465 | 1488 | tc_sub_type unify inst_orig ctxt ty_actual ty_expected
|
| 1466 | 1489 | = do { ds_flag <- getDeepSubsumptionFlag
|
| 1467 | - ; tc_sub_type_ds ds_flag unify inst_orig ctxt ty_actual ty_expected }
|
|
| 1490 | + ; tc_sub_type_ds Top ds_flag unify inst_orig ctxt ty_actual ty_expected }
|
|
| 1468 | 1491 | |
| 1469 | 1492 | ----------------------
|
| 1470 | -tc_sub_type_ds :: DeepSubsumptionFlag
|
|
| 1493 | +tc_sub_type_ds :: Position p -- ^ position in the type (for error messages only)
|
|
| 1494 | + -> DeepSubsumptionFlag
|
|
| 1471 | 1495 | -> (TcType -> TcType -> TcM TcCoercionN)
|
| 1472 | 1496 | -> CtOrigin -> UserTypeCtxt -> TcSigmaType
|
| 1473 | 1497 | -> TcSigmaType -> TcM HsWrapper
|
| 1474 | 1498 | -- tc_sub_type_ds is the main subsumption worker function
|
| 1475 | 1499 | -- It takes an explicit DeepSubsumptionFlag
|
| 1476 | -tc_sub_type_ds ds_flag unify inst_orig ctxt ty_actual ty_expected
|
|
| 1500 | +tc_sub_type_ds pos ds_flag unify inst_orig ctxt ty_actual ty_expected
|
|
| 1477 | 1501 | | definitely_poly ty_expected -- See Note [Don't skolemise unnecessarily]
|
| 1478 | 1502 | , isRhoTyDS ds_flag ty_actual
|
| 1479 | 1503 | = do { traceTc "tc_sub_type (drop to equality)" $
|
| ... | ... | @@ -1490,7 +1514,7 @@ tc_sub_type_ds ds_flag unify inst_orig ctxt ty_actual ty_expected |
| 1490 | 1514 | ; (sk_wrap, inner_wrap)
|
| 1491 | 1515 | <- tcSkolemise ds_flag ctxt ty_expected $ \sk_rho ->
|
| 1492 | 1516 | case ds_flag of
|
| 1493 | - Deep -> tc_sub_type_deep unify inst_orig ctxt ty_actual sk_rho
|
|
| 1517 | + Deep -> tc_sub_type_deep pos unify inst_orig ctxt ty_actual sk_rho
|
|
| 1494 | 1518 | Shallow -> tc_sub_type_shallow unify inst_orig ty_actual sk_rho
|
| 1495 | 1519 | |
| 1496 | 1520 | ; return (sk_wrap <.> inner_wrap) }
|
| ... | ... | @@ -1656,7 +1680,7 @@ The effects are in these main places: |
| 1656 | 1680 | see the call to tcDeeplySkolemise in tcSkolemiseScoped.
|
| 1657 | 1681 | |
| 1658 | 1682 | 4. In GHC.Tc.Gen.App.tcApp we call tcSubTypeDS to match the result
|
| 1659 | - type. Without deep subsumption, unifyExpectedType would be sufficent.
|
|
| 1683 | + type. Without deep subsumption, tcSubTypeMono would be sufficent.
|
|
| 1660 | 1684 | |
| 1661 | 1685 | In all these cases note that the deep skolemisation must be done /first/.
|
| 1662 | 1686 | Consider (1)
|
| ... | ... | @@ -1669,8 +1693,10 @@ Wrinkles: |
| 1669 | 1693 | (DS1) Note that we /always/ use shallow subsumption in the ambiguity check.
|
| 1670 | 1694 | See Note [Ambiguity check and deep subsumption].
|
| 1671 | 1695 | |
| 1672 | -(DS2) Deep subsumption requires deep instantiation too.
|
|
| 1673 | - See Note [The need for deep instantiation]
|
|
| 1696 | +(DS2) When doing deep subsumption, we must be careful not to needlessly
|
|
| 1697 | + drop down to unification, e.g. in cases such as:
|
|
| 1698 | + (Bool -> ∀ d. d->d) <= alpha beta gamma
|
|
| 1699 | + See Note [FunTy vs non-FunTy case in tc_sub_type_deep].
|
|
| 1674 | 1700 | |
| 1675 | 1701 | (DS3) The interaction between deep subsumption and required foralls
|
| 1676 | 1702 | (forall a -> ty) is a bit subtle. See #24696 and
|
| ... | ... | @@ -1701,6 +1727,69 @@ ToDo: this eta-abstraction plays fast and loose with termination, |
| 1701 | 1727 | because it can introduce extra lambdas. Maybe add a `seq` to
|
| 1702 | 1728 | fix this
|
| 1703 | 1729 | |
| 1730 | +Note [FunTy vs FunTy case in tc_sub_type_deep]
|
|
| 1731 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1732 | +The goal of tc_sub_type_deep is to produce an HsWrapper that "proves" that the
|
|
| 1733 | +actual type is a subtype of the expected type. The most important case is how
|
|
| 1734 | +we deal with function arrows. Suppose we have:
|
|
| 1735 | + |
|
| 1736 | + ty_actual = act_arg -> act_res
|
|
| 1737 | + ty_expected = exp_arg -> exp_res
|
|
| 1738 | + |
|
| 1739 | +To produce fun_wrap :: (act_arg -> act_res) ~> (exp_arg -> exp_res), we use
|
|
| 1740 | +the fact that the function arrow is contravariant in its argument type and
|
|
| 1741 | +covariant in its result type. Thus we recursively perform subtype checks
|
|
| 1742 | +on the argument types (with actual/expected switched) and the result types,
|
|
| 1743 | +to get:
|
|
| 1744 | + |
|
| 1745 | + arg_wrap :: exp_arg ~> act_arg -- NB: expected/actual have switched sides
|
|
| 1746 | + res_wrap :: act_res ~> exp_res
|
|
| 1747 | + |
|
| 1748 | +Then fun_wrap = mkWpFun arg_wrap res_wrap.
|
|
| 1749 | + |
|
| 1750 | +Wrinkle [Representation-polymorphism checking during subtyping]
|
|
| 1751 | + |
|
| 1752 | + Inserting a WpFun HsWrapper amounts to impedance matching in deep subsumption
|
|
| 1753 | + via eta-expansion:
|
|
| 1754 | + |
|
| 1755 | + f ==> \ (x :: exp_arg) -> res_wrap [ f (arg_wrap [x]) ]
|
|
| 1756 | + |
|
| 1757 | + As we produce a lambda, we must enforce the representation polymorphism
|
|
| 1758 | + invariants described in Note [Representation polymorphism invariants] in GHC.Core.
|
|
| 1759 | + That is, we must ensure that both x (the lambda binder) and (arg_wrap [x]) (the function argument)
|
|
| 1760 | + have a fixed runtime representation.
|
|
| 1761 | + |
|
| 1762 | + Note however that desugaring mkWpFun does not always introduce a lambda: if
|
|
| 1763 | + both the argument and result HsWrappers are casts, then a FunCo cast suffices,
|
|
| 1764 | + in which case we should not perform representation-polymorphism checking.
|
|
| 1765 | + |
|
| 1766 | + This means that, in the FunTy/FunTy case of tc_sub_type_deep, we can skip
|
|
| 1767 | + the representation-polymorphism checks if the produced argument and result
|
|
| 1768 | + wrappers are identities or casts.
|
|
| 1769 | + It is important to do so, otherwise we reject valid programs.
|
|
| 1770 | + |
|
| 1771 | + Here's a contrived example (there are undoubtedly more natural examples)
|
|
| 1772 | + (see testsuite/tests/rep-poly/NoEtaRequired):
|
|
| 1773 | + |
|
| 1774 | + type Id :: k -> k
|
|
| 1775 | + type family Id a where
|
|
| 1776 | + |
|
| 1777 | + type T :: TYPE r -> TYPE (Id r)
|
|
| 1778 | + type family T a where
|
|
| 1779 | + |
|
| 1780 | + test :: forall r (a :: TYPE r). a :~~: T a -> ()
|
|
| 1781 | + test HRefl =
|
|
| 1782 | + let
|
|
| 1783 | + f :: (a -> a) -> ()
|
|
| 1784 | + f _ = ()
|
|
| 1785 | + g :: T a -> T a
|
|
| 1786 | + g = undefined
|
|
| 1787 | + in f g
|
|
| 1788 | + |
|
| 1789 | + We don't need to eta-expand `g` to make `f g` typecheck; a cast suffices.
|
|
| 1790 | + Hence we should not perform representation-polymorphism checks; they would
|
|
| 1791 | + fail here.
|
|
| 1792 | + |
|
| 1704 | 1793 | Note [Setting the argument context]
|
| 1705 | 1794 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 1706 | 1795 | Consider we are doing the ambiguity check for the (bogus)
|
| ... | ... | @@ -1751,30 +1840,31 @@ complains. |
| 1751 | 1840 | The easiest solution was to use tcEqMult in tc_sub_type_deep, and
|
| 1752 | 1841 | insist on equality. This is only in the DeepSubsumption code anyway.
|
| 1753 | 1842 | |
| 1754 | -Note [The need for deep instantiation]
|
|
| 1755 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1843 | +Note [FunTy vs non-FunTy case in tc_sub_type_deep]
|
|
| 1844 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1756 | 1845 | Consider this, without Quick Look, but with Deep Subsumption:
|
| 1757 | 1846 | f :: ∀a b c. a b c -> Int
|
| 1758 | 1847 | g :: Bool -> ∀d. d -> d
|
| 1759 | -Consider the application (f g). We need to do the subsumption test
|
|
| 1760 | - |
|
| 1761 | - (Bool -> ∀ d. d->d) <= (alpha beta gamma)
|
|
| 1848 | +To typecheck the application (f g), we need to do the subsumption test
|
|
| 1762 | 1849 | |
| 1763 | -where alpha, beta, gamma are the unification variables that instantiate a,b,c,
|
|
| 1764 | -respectively. We must not drop down to unification, or we will reject the call.
|
|
| 1765 | -Rather we must deeply instantiate the LHS to get
|
|
| 1850 | + (Bool -> ∀ d. d->d) <= alpha beta gamma
|
|
| 1766 | 1851 | |
| 1767 | - (Bool -> delta -> delta) <= (alpha beta gamma)
|
|
| 1852 | +where alpha, beta, gamma are the unification variables that instantiate a,b,c
|
|
| 1853 | +(respectively). We must not drop down to unification, or we will reject the call.
|
|
| 1854 | +Instead, we should only unify alpha := (->), in which case we end up with the
|
|
| 1855 | +usual FunTy vs FunTy case of Note [FunTy vs FunTy case in tc_sub_type_deep]:
|
|
| 1768 | 1856 | |
| 1769 | -and now we can unify to get
|
|
| 1857 | + (Bool -> ∀ d. d->d) <= beta -> gamma
|
|
| 1770 | 1858 | |
| 1771 | - alpha = (->)
|
|
| 1772 | - beta = Bool
|
|
| 1773 | - gamma = delta -> delta
|
|
| 1859 | +which is straightforwardly solved by beta := Bool, using covariance in the return
|
|
| 1860 | +type of the function arrow, and instantiating the forall before unifying with gamma.
|
|
| 1774 | 1861 | |
| 1775 | -Hence the call to `deeplyInstantiate` in `tc_sub_type_deep`.
|
|
| 1862 | +The conclusion is this: when doing a deep subtype check (in tc_sub_type_deep),
|
|
| 1863 | +if the LHS is a FunTy and the RHS is a rho-type which is not a FunTy,
|
|
| 1864 | +then unify the RHS with a FunTy and continue by performing a sub-type check on
|
|
| 1865 | +the LHS vs the new RHS. And vice-versa (if it's the RHS that is a FunTy).
|
|
| 1776 | 1866 | |
| 1777 | -See typecheck/should_compile/T11305 for an example of when this is important.
|
|
| 1867 | +See T11305 and T26225 for examples of when this is important.
|
|
| 1778 | 1868 | |
| 1779 | 1869 | Note [Deep subsumption and required foralls]
|
| 1780 | 1870 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -1837,12 +1927,17 @@ getDeepSubsumptionFlag :: TcM DeepSubsumptionFlag |
| 1837 | 1927 | getDeepSubsumptionFlag = do { ds <- xoptM LangExt.DeepSubsumption
|
| 1838 | 1928 | ; if ds then return Deep else return Shallow }
|
| 1839 | 1929 | |
| 1930 | +-- | 'tc_sub_type_deep' is where the actual work happens for deep subsumption.
|
|
| 1931 | +--
|
|
| 1932 | +-- Given @ty_actual@ (a sigma-type) and @ty_expected@ (deeply skolemised, i.e.
|
|
| 1933 | +-- a deep rho type), it returns an 'HsWrapper' @wrap :: ty_actual ~> ty_expected@.
|
|
| 1840 | 1934 | tc_sub_type_deep :: HasDebugCallStack
|
| 1841 | - => (TcType -> TcType -> TcM TcCoercionN) -- How to unify
|
|
| 1842 | - -> CtOrigin -- Used when instantiating
|
|
| 1843 | - -> UserTypeCtxt -- Used when skolemising
|
|
| 1844 | - -> TcSigmaType -- Actual; a sigma-type
|
|
| 1845 | - -> TcRhoType -- Expected; deeply skolemised
|
|
| 1935 | + => Position p -- ^ Position in the type (for error messages only)
|
|
| 1936 | + -> (TcType -> TcType -> TcM TcCoercionN) -- ^ How to unify
|
|
| 1937 | + -> CtOrigin -- ^ Used when instantiating
|
|
| 1938 | + -> UserTypeCtxt -- ^ Used when skolemising
|
|
| 1939 | + -> TcSigmaType -- ^ Actual; a sigma-type
|
|
| 1940 | + -> TcRhoType -- ^ Expected; deeply skolemised
|
|
| 1846 | 1941 | -> TcM HsWrapper
|
| 1847 | 1942 | |
| 1848 | 1943 | -- If wrap = tc_sub_type_deep t1 t2
|
| ... | ... | @@ -1850,63 +1945,161 @@ tc_sub_type_deep :: HasDebugCallStack |
| 1850 | 1945 | -- Here is where the work actually happens!
|
| 1851 | 1946 | -- Precondition: ty_expected is deeply skolemised
|
| 1852 | 1947 | |
| 1853 | -tc_sub_type_deep unify inst_orig ctxt ty_actual ty_expected
|
|
| 1948 | +tc_sub_type_deep pos unify inst_orig ctxt ty_actual ty_expected
|
|
| 1854 | 1949 | = assertPpr (isDeepRhoTy ty_expected) (ppr ty_expected) $
|
| 1855 | 1950 | do { traceTc "tc_sub_type_deep" $
|
| 1856 | 1951 | vcat [ text "ty_actual =" <+> ppr ty_actual
|
| 1857 | 1952 | , text "ty_expected =" <+> ppr ty_expected ]
|
| 1858 | 1953 | ; go ty_actual ty_expected }
|
| 1859 | 1954 | where
|
| 1860 | - -- NB: 'go' is not recursive, except for doing coreView
|
|
| 1861 | - go ty_a ty_e | Just ty_a' <- coreView ty_a = go ty_a' ty_e
|
|
| 1862 | - | Just ty_e' <- coreView ty_e = go ty_a ty_e'
|
|
| 1863 | 1955 | |
| 1864 | - go (TyVarTy tv_a) ty_e
|
|
| 1865 | - = do { lookup_res <- isFilledMetaTyVar_maybe tv_a
|
|
| 1956 | + -- 'unwrap' removes top-level type synonyms & looks through filled meta-tyvars
|
|
| 1957 | + unwrap :: TcType -> TcM TcType
|
|
| 1958 | + unwrap ty
|
|
| 1959 | + | Just ty' <- coreView ty
|
|
| 1960 | + = unwrap ty'
|
|
| 1961 | + unwrap ty@(TyVarTy tv)
|
|
| 1962 | + = do { lookup_res <- isFilledMetaTyVar_maybe tv
|
|
| 1866 | 1963 | ; case lookup_res of
|
| 1867 | - Just ty_a' ->
|
|
| 1868 | - do { traceTc "tc_sub_type_deep following filled meta-tyvar:"
|
|
| 1869 | - (ppr tv_a <+> text "-->" <+> ppr ty_a')
|
|
| 1870 | - ; tc_sub_type_deep unify inst_orig ctxt ty_a' ty_e }
|
|
| 1871 | - Nothing -> just_unify ty_actual ty_expected }
|
|
| 1872 | - |
|
| 1873 | - go ty_a@(FunTy { ft_af = af1, ft_mult = act_mult, ft_arg = act_arg, ft_res = act_res })
|
|
| 1874 | - ty_e@(FunTy { ft_af = af2, ft_mult = exp_mult, ft_arg = exp_arg, ft_res = exp_res })
|
|
| 1875 | - | isVisibleFunArg af1, isVisibleFunArg af2
|
|
| 1876 | - = if (isTauTy ty_a && isTauTy ty_e) -- Short cut common case to avoid
|
|
| 1877 | - then just_unify ty_actual ty_expected -- unnecessary eta expansion
|
|
| 1878 | - else
|
|
| 1879 | - -- This is where we do the co/contra thing, and generate a WpFun, which in turn
|
|
| 1880 | - -- causes eta-expansion, which we don't like; hence encouraging NoDeepSubsumption
|
|
| 1881 | - do { arg_wrap <- tc_sub_type_ds Deep unify given_orig GenSigCtxt exp_arg act_arg
|
|
| 1882 | - -- GenSigCtxt: See Note [Setting the argument context]
|
|
| 1883 | - ; res_wrap <- tc_sub_type_deep unify inst_orig ctxt act_res exp_res
|
|
| 1884 | - ; tcEqMult inst_orig act_mult exp_mult
|
|
| 1885 | - -- See Note [Multiplicity in deep subsumption]
|
|
| 1886 | - ; return (mkWpFun arg_wrap res_wrap (Scaled exp_mult exp_arg) exp_res) }
|
|
| 1887 | - -- arg_wrap :: exp_arg ~> act_arg
|
|
| 1888 | - -- res_wrap :: act-res ~> exp_res
|
|
| 1889 | - where
|
|
| 1890 | - given_orig = GivenOrigin (SigSkol GenSigCtxt exp_arg [])
|
|
| 1891 | - |
|
| 1892 | - go ty_a ty_e
|
|
| 1964 | + Just ty' -> unwrap ty'
|
|
| 1965 | + Nothing -> return ty }
|
|
| 1966 | + unwrap ty = return ty
|
|
| 1967 | + |
|
| 1968 | + go, go1 :: TcType -> TcType -> TcM HsWrapper
|
|
| 1969 | + go ty_a ty_e =
|
|
| 1970 | + do { ty_a' <- unwrap ty_a
|
|
| 1971 | + ; ty_e' <- unwrap ty_e
|
|
| 1972 | + ; go1 ty_a' ty_e' }
|
|
| 1973 | + |
|
| 1974 | + -- If ty_actual is not a rho-type, instantiate it first; otherwise
|
|
| 1975 | + -- unification has no chance of succeeding.
|
|
| 1976 | + go1 ty_a ty_e
|
|
| 1893 | 1977 | | let (tvs, theta, _) = tcSplitSigmaTy ty_a
|
| 1894 | 1978 | , not (null tvs && null theta)
|
| 1895 | 1979 | = do { (in_wrap, in_rho) <- topInstantiate inst_orig ty_a
|
| 1896 | - ; body_wrap <- tc_sub_type_deep unify inst_orig ctxt in_rho ty_e
|
|
| 1980 | + ; body_wrap <- go in_rho ty_e
|
|
| 1897 | 1981 | ; return (body_wrap <.> in_wrap) }
|
| 1898 | 1982 | |
| 1899 | - | otherwise -- Revert to unification
|
|
| 1900 | - = do { -- It's still possible that ty_actual has nested foralls. Instantiate
|
|
| 1901 | - -- these, as there's no way unification will succeed with them in.
|
|
| 1902 | - -- See Note [The need for deep instantiation]
|
|
| 1903 | - (inst_wrap, rho_a) <- deeplyInstantiate inst_orig ty_actual
|
|
| 1904 | - ; unify_wrap <- just_unify rho_a ty_expected
|
|
| 1905 | - ; return (unify_wrap <.> inst_wrap) }
|
|
| 1983 | + -- Main case: FunTy vs FunTy. go_fun does the work.
|
|
| 1984 | + go1 (FunTy { ft_af = af1, ft_mult = act_mult, ft_arg = act_arg, ft_res = act_res })
|
|
| 1985 | + (FunTy { ft_af = af2, ft_mult = exp_mult, ft_arg = exp_arg, ft_res = exp_res })
|
|
| 1986 | + | isVisibleFunArg af1
|
|
| 1987 | + , isVisibleFunArg af2
|
|
| 1988 | + = go_fun af1 act_mult act_arg act_res
|
|
| 1989 | + af2 exp_mult exp_arg exp_res
|
|
| 1990 | + |
|
| 1991 | + -- See Note [FunTy vs non-FunTy case in tc_sub_type_deep]
|
|
| 1992 | + go1 (FunTy { ft_af = af1, ft_mult = act_mult, ft_arg = act_arg, ft_res = act_res }) ty_e
|
|
| 1993 | + | isVisibleFunArg af1
|
|
| 1994 | + = do { exp_mult <- newMultiplicityVar
|
|
| 1995 | + ; exp_arg <- newOpenFlexiTyVarTy -- NB: no FRR check needed; we might not need to eta-expand
|
|
| 1996 | + ; exp_res <- newOpenFlexiTyVarTy
|
|
| 1997 | + ; let exp_funTy = FunTy { ft_af = af1, ft_mult = exp_mult, ft_arg = exp_arg, ft_res = exp_res }
|
|
| 1998 | + ; unify_wrap <- just_unify exp_funTy ty_e
|
|
| 1999 | + ; fun_wrap <- go_fun af1 act_mult act_arg act_res af1 exp_mult exp_arg exp_res
|
|
| 2000 | + ; return $ unify_wrap <.> fun_wrap
|
|
| 2001 | + -- unify_wrap :: exp_funTy ~> ty_e
|
|
| 2002 | + -- fun_wrap :: ty_a ~> exp_funTy
|
|
| 2003 | + }
|
|
| 2004 | + go1 ty_a (FunTy { ft_af = af2, ft_mult = exp_mult, ft_arg = exp_arg, ft_res = exp_res })
|
|
| 2005 | + | isVisibleFunArg af2
|
|
| 2006 | + = do { act_mult <- newMultiplicityVar
|
|
| 2007 | + ; act_arg <- newOpenFlexiTyVarTy -- NB: no FRR check needed; we might not need to eta-expand
|
|
| 2008 | + ; act_res <- newOpenFlexiTyVarTy
|
|
| 2009 | + ; let act_funTy = FunTy { ft_af = af2, ft_mult = act_mult, ft_arg = act_arg, ft_res = act_res }
|
|
| 2010 | + |
|
| 2011 | + ; unify_wrap <- just_unify ty_a act_funTy
|
|
| 2012 | + ; fun_wrap <- go_fun af2 act_mult act_arg act_res af2 exp_mult exp_arg exp_res
|
|
| 2013 | + ; return $ fun_wrap <.> unify_wrap
|
|
| 2014 | + -- unify_wrap :: ty_a ~> act_funTy
|
|
| 2015 | + -- fun_wrap :: act_funTy ~> ty_e
|
|
| 2016 | + }
|
|
| 2017 | + |
|
| 2018 | + -- Otherwise, revert to unification.
|
|
| 2019 | + go1 ty_a ty_e = just_unify ty_a ty_e
|
|
| 1906 | 2020 | |
| 1907 | 2021 | just_unify ty_a ty_e = do { cow <- unify ty_a ty_e
|
| 1908 | 2022 | ; return (mkWpCastN cow) }
|
| 1909 | 2023 | |
| 2024 | + -- FunTy/FunTy case: this is where we insert any necessary eta-expansions.
|
|
| 2025 | + go_fun :: FunTyFlag -> Mult -> TcType -> TcType -- actual FunTy
|
|
| 2026 | + -> FunTyFlag -> Mult -> TcType -> TcType -- expected FunTy
|
|
| 2027 | + -> TcM HsWrapper
|
|
| 2028 | + go_fun act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res
|
|
| 2029 | + -- See Note [FunTy vs FunTy case in tc_sub_type_deep]
|
|
| 2030 | + = do { arg_wrap <- tc_sub_type_ds (Argument pos) Deep unify given_orig GenSigCtxt exp_arg act_arg
|
|
| 2031 | + -- GenSigCtxt: See Note [Setting the argument context]
|
|
| 2032 | + ; res_wrap <- tc_sub_type_deep (Result pos) unify inst_orig ctxt act_res exp_res
|
|
| 2033 | + |
|
| 2034 | + -- See Note [Multiplicity in deep subsumption]
|
|
| 2035 | + ; tcEqMult inst_orig act_mult exp_mult
|
|
| 2036 | + |
|
| 2037 | + ; mkWpFun_FRR pos
|
|
| 2038 | + act_af act_mult act_arg act_res
|
|
| 2039 | + exp_af exp_mult exp_arg exp_res
|
|
| 2040 | + arg_wrap res_wrap
|
|
| 2041 | + }
|
|
| 2042 | + where
|
|
| 2043 | + given_orig = GivenOrigin (SigSkol GenSigCtxt exp_arg [])
|
|
| 2044 | + |
|
| 2045 | +-- | Like 'mkWpFun', except that it performs representation-polymorphism
|
|
| 2046 | +-- checks on the argument type.
|
|
| 2047 | +mkWpFun_FRR
|
|
| 2048 | + :: Position p
|
|
| 2049 | + -> FunTyFlag -> Type -> TcType -> Type -- actual FunTy
|
|
| 2050 | + -> FunTyFlag -> Type -> TcType -> Type -- expected FunTy
|
|
| 2051 | + -> HsWrapper -- ^ exp_arg ~> act_arg
|
|
| 2052 | + -> HsWrapper -- ^ act_res ~> exp_res
|
|
| 2053 | + -> TcM HsWrapper -- ^ act_funTy ~> exp_funTy
|
|
| 2054 | +mkWpFun_FRR pos act_af act_mult act_arg act_res exp_af exp_mult exp_arg exp_res arg_wrap res_wrap
|
|
| 2055 | + | needs_eta
|
|
| 2056 | + -- See Wrinkle [Representation-polymorphism checking during subtyping]
|
|
| 2057 | + = do { (exp_arg_co, exp_arg_frr) <- hasFixedRuntimeRep (FRRDeepSubsumption True pos) exp_arg
|
|
| 2058 | + ; (act_arg_co, _act_arg_frr) <- hasFixedRuntimeRep (FRRDeepSubsumption False pos) act_arg
|
|
| 2059 | + ; let
|
|
| 2060 | + exp_arg_fun_co =
|
|
| 2061 | + mkFunCo Nominal exp_af
|
|
| 2062 | + (mkReflCo Nominal exp_mult)
|
|
| 2063 | + (mkSymCo exp_arg_co)
|
|
| 2064 | + (mkReflCo Nominal exp_res)
|
|
| 2065 | + act_arg_fun_co =
|
|
| 2066 | + mkFunCo Nominal act_af
|
|
| 2067 | + (mkReflCo Nominal act_mult)
|
|
| 2068 | + act_arg_co
|
|
| 2069 | + (mkReflCo Nominal act_res)
|
|
| 2070 | + arg_wrap_frr =
|
|
| 2071 | + mkWpCastN (mkSymCo exp_arg_co) <.> arg_wrap <.> mkWpCastN act_arg_co
|
|
| 2072 | + -- exp_arg_co :: exp_arg ~> exp_arg_frr
|
|
| 2073 | + -- act_arg_co :: act_arg ~> act_arg_frr
|
|
| 2074 | + -- arg_wrap :: exp_arg ~> act_arg
|
|
| 2075 | + -- arg_wrap_frr :: exp_arg_frr ~> act_arg_frr
|
|
| 2076 | + |
|
| 2077 | + -- NB: because of the needs_eta guard, we know that mkWpFun will
|
|
| 2078 | + -- return (WpFun ...); so we might as well just use the WpFun constructor.
|
|
| 2079 | + ; return $
|
|
| 2080 | + mkWpCastN exp_arg_fun_co
|
|
| 2081 | + <.>
|
|
| 2082 | + WpFun arg_wrap_frr res_wrap (Scaled exp_mult exp_arg_frr)
|
|
| 2083 | + <.>
|
|
| 2084 | + mkWpCastN act_arg_fun_co }
|
|
| 2085 | + | otherwise
|
|
| 2086 | + = return $
|
|
| 2087 | + mkWpFun arg_wrap res_wrap (Scaled exp_mult exp_arg) exp_res
|
|
| 2088 | + -- NB: because of 'needs_eta', this will never actually be a WpFun.
|
|
| 2089 | + -- mkWpFun will turn it into a WpHole or WpCast, which is why
|
|
| 2090 | + -- we can skip the hasFixedRuntimeRep checks in this case.
|
|
| 2091 | + -- See Wrinkle [Representation-polymorphism checking during subtyping]
|
|
| 2092 | + where
|
|
| 2093 | + needs_eta :: Bool
|
|
| 2094 | + needs_eta =
|
|
| 2095 | + not (hole_or_cast arg_wrap)
|
|
| 2096 | + ||
|
|
| 2097 | + not (hole_or_cast res_wrap)
|
|
| 2098 | + hole_or_cast :: HsWrapper -> Bool
|
|
| 2099 | + hole_or_cast WpHole = True
|
|
| 2100 | + hole_or_cast (WpCast {}) = True
|
|
| 2101 | + hole_or_cast _ = False
|
|
| 2102 | + |
|
| 1910 | 2103 | -----------------------
|
| 1911 | 2104 | deeplySkolemise :: SkolemInfo -> TcSigmaType
|
| 1912 | 2105 | -> TcM ( HsWrapper
|
| ... | ... | @@ -1950,7 +1950,7 @@ seqId = pcRepPolyId seqName ty concs info |
| 1950 | 1950 | Case (Var x) x openBetaTy [Alt DEFAULT [] (Var y)]
|
| 1951 | 1951 | |
| 1952 | 1952 | concs = mkRepPolyIdConcreteTyVars
|
| 1953 | - [ ((openBetaTy, Argument 2 Top), runtimeRep2TyVar)]
|
|
| 1953 | + [ ((openBetaTy, mkArgPos 2 Top), runtimeRep2TyVar)]
|
|
| 1954 | 1954 | |
| 1955 | 1955 | arity = 2
|
| 1956 | 1956 | |
| ... | ... | @@ -2009,7 +2009,7 @@ oneShotId = pcRepPolyId oneShotName ty concs info |
| 2009 | 2009 | arity = 2
|
| 2010 | 2010 | |
| 2011 | 2011 | concs = mkRepPolyIdConcreteTyVars
|
| 2012 | - [((openAlphaTy, Argument 2 Top), runtimeRep1TyVar)]
|
|
| 2012 | + [((openAlphaTy, mkArgPos 2 Top), runtimeRep1TyVar)]
|
|
| 2013 | 2013 | |
| 2014 | 2014 | ----------------------------------------------------------------------
|
| 2015 | 2015 | {- Note [Wired-in Ids for rebindable syntax]
|
| ... | ... | @@ -2054,7 +2054,7 @@ leftSectionId = pcRepPolyId leftSectionName ty concs info |
| 2054 | 2054 | arity = 2
|
| 2055 | 2055 | |
| 2056 | 2056 | concs = mkRepPolyIdConcreteTyVars
|
| 2057 | - [((openAlphaTy, Argument 2 Top), runtimeRep1TyVar)]
|
|
| 2057 | + [((openAlphaTy, mkArgPos 2 Top), runtimeRep1TyVar)]
|
|
| 2058 | 2058 | |
| 2059 | 2059 | -- See Note [Left and right sections] in GHC.Rename.Expr
|
| 2060 | 2060 | -- See Note [Wired-in Ids for rebindable syntax]
|
| ... | ... | @@ -2088,8 +2088,8 @@ rightSectionId = pcRepPolyId rightSectionName ty concs info |
| 2088 | 2088 | |
| 2089 | 2089 | concs =
|
| 2090 | 2090 | mkRepPolyIdConcreteTyVars
|
| 2091 | - [ ((openAlphaTy, Argument 3 Top), runtimeRep1TyVar)
|
|
| 2092 | - , ((openBetaTy , Argument 2 Top), runtimeRep2TyVar)]
|
|
| 2091 | + [ ((openAlphaTy, mkArgPos 3 Top), runtimeRep1TyVar)
|
|
| 2092 | + , ((openBetaTy , mkArgPos 2 Top), runtimeRep2TyVar)]
|
|
| 2093 | 2093 | |
| 2094 | 2094 | --------------------------------------------------------------------------------
|
| 2095 | 2095 | |
| ... | ... | @@ -2119,7 +2119,7 @@ coerceId = pcRepPolyId coerceName ty concs info |
| 2119 | 2119 | [Alt (DataAlt coercibleDataCon) [eq] (Cast (Var x) (mkCoVarCo eq))]
|
| 2120 | 2120 | |
| 2121 | 2121 | concs = mkRepPolyIdConcreteTyVars
|
| 2122 | - [((mkTyVarTy av, Argument 1 Top), rv)]
|
|
| 2122 | + [((mkTyVarTy av, mkArgPos 1 Top), rv)]
|
|
| 2123 | 2123 | |
| 2124 | 2124 | {-
|
| 2125 | 2125 | Note [seqId magic]
|
| ... | ... | @@ -15,7 +15,7 @@ in coerce BAD 1 |
| 15 | 15 | CvSubst = []>
|
| 16 | 16 | in coerce BAD 2
|
| 17 | 17 | <no location info>: warning:
|
| 18 | - • The return type of the first argument of the primop ‘catch#’ does not have a fixed runtime representation:
|
|
| 18 | + • The result of the first argument of the primop ‘catch#’ does not have a fixed runtime representation:
|
|
| 19 | 19 | a :: TYPE q
|
| 20 | 20 | Substitution: <InScope = {a q}
|
| 21 | 21 | IdSubst = []
|
| ... | ... | @@ -23,7 +23,7 @@ in coerce BAD 2 |
| 23 | 23 | CvSubst = []>
|
| 24 | 24 | in catch# BAD 1
|
| 25 | 25 | <no location info>: warning:
|
| 26 | - • The return type of the first argument of the primop ‘catch#’ does not have a fixed runtime representation:
|
|
| 26 | + • The result of the first argument of the primop ‘catch#’ does not have a fixed runtime representation:
|
|
| 27 | 27 | ‘q’ is not concrete.
|
| 28 | 28 | Substitution: <InScope = {a q}
|
| 29 | 29 | IdSubst = []
|
| 1 | - |
|
| 2 | -T5439.hs:83:33: error: [GHC-83865]
|
|
| 3 | - • Couldn't match expected type: Attempt (HElemOf rs)
|
|
| 4 | - with actual type: Attempt (HHead (HDrop n0 l0))
|
|
| 5 | - -> Attempt (HElemOf l0)
|
|
| 6 | - • Probable cause: ‘($)’ is applied to too few arguments
|
|
| 7 | - In the second argument of ‘($)’, namely
|
|
| 8 | - ‘inj $ Failure (e :: SomeException)’
|
|
| 1 | +T5439.hs:83:28: error: [GHC-83865]
|
|
| 2 | + • Couldn't match type: Attempt (HElemOf rs)
|
|
| 3 | + with: Attempt (HHead (HDrop n0 l0)) -> Attempt (HElemOf l0)
|
|
| 4 | + Expected: f (Attempt (HHead (HDrop n0 l0)) -> Attempt (HElemOf l0))
|
|
| 5 | + Actual: f (Attempt (WaitOpResult (WaitOps rs)))
|
|
| 6 | + • In the first argument of ‘complete’, namely ‘ev’
|
|
| 7 | + In the first argument of ‘($)’, namely ‘complete ev’
|
|
| 9 | 8 | In a stmt of a 'do' block:
|
| 10 | 9 | c <- complete ev $ inj $ Failure (e :: SomeException)
|
| 11 | - In the expression:
|
|
| 12 | - do c <- complete ev $ inj $ Failure (e :: SomeException)
|
|
| 13 | - return $ c || not first
|
|
| 14 | 10 | • Relevant bindings include
|
| 15 | 11 | register :: Bool -> Peano n -> WaitOps (HDrop n rs) -> IO Bool
|
| 16 | 12 | (bound at T5439.hs:65:9)
|
| ... | ... | @@ -30,3 +26,4 @@ T5439.hs:83:39: error: [GHC-83865] |
| 30 | 26 | ‘inj $ Failure (e :: SomeException)’
|
| 31 | 27 | In a stmt of a 'do' block:
|
| 32 | 28 | c <- complete ev $ inj $ Failure (e :: SomeException)
|
| 29 | + |
| 1 | - |
|
| 2 | 1 | T10403.hs:16:7: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)]
|
| 3 | 2 | • Found extra-constraints wildcard standing for ‘Functor f’
|
| 4 | 3 | Where: ‘f’ is a rigid type variable bound by
|
| 5 | - the inferred type of h1 :: Functor f => (a1 -> a2) -> f a1 -> H f
|
|
| 4 | + the inferred type of h1 :: Functor f => (t -> b) -> f t -> H f
|
|
| 6 | 5 | at T10403.hs:18:1-41
|
| 7 | 6 | • In the type signature: h1 :: _ => _
|
| 8 | 7 | |
| 9 | 8 | T10403.hs:16:12: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)]
|
| 10 | - • Found type wildcard ‘_’ standing for ‘(a1 -> a2) -> f a1 -> H f’
|
|
| 11 | - Where: ‘a2’, ‘a1’, ‘f’ are rigid type variables bound by
|
|
| 12 | - the inferred type of h1 :: Functor f => (a1 -> a2) -> f a1 -> H f
|
|
| 9 | + • Found type wildcard ‘_’ standing for ‘(t -> b) -> f t -> H f’
|
|
| 10 | + Where: ‘b’, ‘t’, ‘f’ are rigid type variables bound by
|
|
| 11 | + the inferred type of h1 :: Functor f => (t -> b) -> f t -> H f
|
|
| 13 | 12 | at T10403.hs:18:1-41
|
| 14 | 13 | • In the type signature: h1 :: _ => _
|
| 15 | 14 | |
| 16 | 15 | T10403.hs:20:7: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)]
|
| 17 | - • Found type wildcard ‘_’ standing for ‘(a1 -> a2) -> f a1 -> H f’
|
|
| 18 | - Where: ‘a2’, ‘a1’, ‘f’ are rigid type variables bound by
|
|
| 19 | - the inferred type of h2 :: (a1 -> a2) -> f a1 -> H f
|
|
| 16 | + • Found type wildcard ‘_’ standing for ‘(t -> b) -> f t -> H f’
|
|
| 17 | + Where: ‘b’, ‘t’, ‘f’ are rigid type variables bound by
|
|
| 18 | + the inferred type of h2 :: (t -> b) -> f t -> H f
|
|
| 20 | 19 | at T10403.hs:23:1-41
|
| 21 | 20 | • In the type signature: h2 :: _
|
| 22 | 21 | |
| ... | ... | @@ -24,7 +23,8 @@ T10403.hs:23:15: warning: [GHC-39999] [-Wdeferred-type-errors (in -Wdefault)] |
| 24 | 23 | • No instance for ‘Functor f’ arising from a use of ‘fmap’
|
| 25 | 24 | Possible fix:
|
| 26 | 25 | add (Functor f) to the context of
|
| 27 | - the inferred type of h2 :: (a1 -> a2) -> f a1 -> H f
|
|
| 26 | + the inferred type of h2 :: (t -> b) -> f t -> H f
|
|
| 28 | 27 | • In the second argument of ‘(.)’, namely ‘fmap (const ())’
|
| 29 | 28 | In the expression: (H . fmap (const ())) (fmap f b)
|
| 30 | 29 | In an equation for ‘h2’: h2 f b = (H . fmap (const ())) (fmap f b)
|
| 30 | + |
| 1 | - |
|
| 2 | 1 | T10615.hs:5:7: error: [GHC-88464]
|
| 3 | - • Found type wildcard ‘_’ standing for ‘w’
|
|
| 4 | - Where: ‘w’ is a rigid type variable bound by
|
|
| 5 | - the inferred type of f1 :: w -> f
|
|
| 2 | + • Found type wildcard ‘_’ standing for ‘t’
|
|
| 3 | + Where: ‘t’ is a rigid type variable bound by
|
|
| 4 | + the inferred type of f1 :: t -> f
|
|
| 6 | 5 | at T10615.hs:6:1-10
|
| 7 | 6 | To use the inferred type, enable PartialTypeSignatures
|
| 8 | 7 | • In the type signature: f1 :: _ -> f
|
| 9 | 8 | |
| 10 | 9 | T10615.hs:6:6: error: [GHC-25897]
|
| 11 | - • Couldn't match type ‘f’ with ‘b1 -> w’
|
|
| 12 | - Expected: w -> f
|
|
| 13 | - Actual: w -> b1 -> w
|
|
| 10 | + • Couldn't match expected type ‘f’ with actual type ‘b1 -> t’
|
|
| 14 | 11 | ‘f’ is a rigid type variable bound by
|
| 15 | - the inferred type of f1 :: w -> f
|
|
| 12 | + the inferred type of f1 :: t -> f
|
|
| 16 | 13 | at T10615.hs:5:1-12
|
| 17 | 14 | • In the expression: const
|
| 18 | 15 | In an equation for ‘f1’: f1 = const
|
| 19 | - • Relevant bindings include f1 :: w -> f (bound at T10615.hs:6:1)
|
|
| 16 | + • Relevant bindings include f1 :: t -> f (bound at T10615.hs:6:1)
|
|
| 20 | 17 | |
| 21 | 18 | T10615.hs:8:7: error: [GHC-88464]
|
| 22 | - • Found type wildcard ‘_’ standing for ‘w’
|
|
| 23 | - Where: ‘w’ is a rigid type variable bound by
|
|
| 24 | - the inferred type of f2 :: w -> _f
|
|
| 19 | + • Found type wildcard ‘_’ standing for ‘t’
|
|
| 20 | + Where: ‘t’ is a rigid type variable bound by
|
|
| 21 | + the inferred type of f2 :: t -> _f
|
|
| 25 | 22 | at T10615.hs:9:1-10
|
| 26 | 23 | To use the inferred type, enable PartialTypeSignatures
|
| 27 | 24 | • In the type signature: f2 :: _ -> _f
|
| 28 | 25 | |
| 29 | 26 | T10615.hs:9:6: error: [GHC-25897]
|
| 30 | - • Couldn't match type ‘_f’ with ‘b0 -> w’
|
|
| 31 | - Expected: w -> _f
|
|
| 32 | - Actual: w -> b0 -> w
|
|
| 27 | + • Couldn't match expected type ‘_f’ with actual type ‘b0 -> t’
|
|
| 33 | 28 | ‘_f’ is a rigid type variable bound by
|
| 34 | - the inferred type of f2 :: w -> _f
|
|
| 29 | + the inferred type of f2 :: t -> _f
|
|
| 35 | 30 | at T10615.hs:8:1-13
|
| 36 | 31 | • In the expression: const
|
| 37 | 32 | In an equation for ‘f2’: f2 = const
|
| 38 | - • Relevant bindings include f2 :: w -> _f (bound at T10615.hs:9:1)
|
|
| 33 | + • Relevant bindings include f2 :: t -> _f (bound at T10615.hs:9:1)
|
|
| 39 | 34 |
| 1 | +{-# LANGUAGE Haskell2010 #-}
|
|
| 2 | +{-# LANGUAGE DataKinds, TypeFamilies, PolyKinds, StandaloneKindSignatures #-}
|
|
| 3 | +{-# LANGUAGE RankNTypes #-}
|
|
| 4 | +{-# LANGUAGE ScopedTypeVariables #-}
|
|
| 5 | +{-# LANGUAGE TypeOperators #-}
|
|
| 6 | +{-# LANGUAGE UndecidableInstances #-}
|
|
| 7 | + |
|
| 8 | +module NoEtaRequired where
|
|
| 9 | + |
|
| 10 | +import Data.Proxy
|
|
| 11 | +import Data.Type.Equality ( (:~~:)(..) )
|
|
| 12 | +import GHC.Exts ( TYPE, RuntimeRep(..) )
|
|
| 13 | + |
|
| 14 | +type Id :: k -> k
|
|
| 15 | +type family Id a where
|
|
| 16 | + |
|
| 17 | +type T :: TYPE r -> TYPE (Id r)
|
|
| 18 | +type family T a where
|
|
| 19 | + |
|
| 20 | +test :: forall r (a :: TYPE r). a :~~: T a -> ()
|
|
| 21 | +test HRefl =
|
|
| 22 | + let
|
|
| 23 | + f :: (a -> a) -> ()
|
|
| 24 | + f _ = ()
|
|
| 25 | + g :: T a -> T a
|
|
| 26 | + g = undefined
|
|
| 27 | + in f g
|
|
| 28 | +-- This test makes sure we DO NOT eta-expand 'g' to '\ x -> g x' when trying
|
|
| 29 | +-- to make 'f g' typecheck. We CANNOT eta-expand here, as the binder 'x' would
|
|
| 30 | +-- not have a fixed runtime representation.
|
|
| 31 | + |
| 1 | 1 | T21906.hs:14:17: error: [GHC-55287]
|
| 2 | - • The return type of the third argument of the primop ‘keepAlive#’
|
|
| 2 | + • The result of the third argument of the primop ‘keepAlive#’
|
|
| 3 | 3 | does not have a fixed runtime representation.
|
| 4 | 4 | Its type is:
|
| 5 | 5 | b1 :: TYPE r1
|
| ... | ... | @@ -12,7 +12,7 @@ T21906.hs:14:17: error: [GHC-55287] |
| 12 | 12 | In an equation for ‘test1’: test1 val s f = keepAlive# val s f
|
| 13 | 13 | |
| 14 | 14 | T21906.hs:21:25: error: [GHC-55287]
|
| 15 | - • The return type of the first argument of the primop ‘catch#’
|
|
| 15 | + • The result of the first argument of the primop ‘catch#’
|
|
| 16 | 16 | does not have a fixed runtime representation.
|
| 17 | 17 | Its type is:
|
| 18 | 18 | a1 :: TYPE q1
|
| ... | ... | @@ -26,7 +26,7 @@ T21906.hs:21:25: error: [GHC-55287] |
| 26 | 26 | test2 action handle s = catch# action handle s
|
| 27 | 27 | |
| 28 | 28 | T21906.hs:30:17: error: [GHC-55287]
|
| 29 | - • The nested return type inside the second argument of the primop ‘control0#’
|
|
| 29 | + • The result of the first argument of the first argument of the second argument of the primop ‘control0#’
|
|
| 30 | 30 | does not have a fixed runtime representation.
|
| 31 | 31 | Its type is:
|
| 32 | 32 | b0 :: TYPE r0
|
| ... | ... | @@ -39,7 +39,7 @@ T21906.hs:30:17: error: [GHC-55287] |
| 39 | 39 | In an equation for ‘test3’: test3 tag f s = control0# tag f s
|
| 40 | 40 | |
| 41 | 41 | T21906.hs:35:19: error: [GHC-55287]
|
| 42 | - • The return type of the first argument of the primop ‘fork#’
|
|
| 42 | + • The result of the first argument of the primop ‘fork#’
|
|
| 43 | 43 | does not have a fixed runtime representation.
|
| 44 | 44 | Its type is:
|
| 45 | 45 | a0 :: TYPE q0
|
| ... | ... | @@ -112,6 +112,7 @@ test('RepPolyWrappedVar', normal, compile_fail, ['']) |
| 112 | 112 | test('RepPolyWrappedVar2', [js_skip], compile, [''])
|
| 113 | 113 | test('UnliftedNewtypesCoerceFail', normal, compile_fail, [''])
|
| 114 | 114 | test('UnliftedNewtypesLevityBinder', normal, compile_fail, [''])
|
| 115 | +test('NoEtaRequired', normal, compile, [''])
|
|
| 115 | 116 | |
| 116 | 117 | ###############################################################################
|
| 117 | 118 | ## The following tests require rewriting in RuntimeReps, ##
|
| 1 | +{-# LANGUAGE DeepSubsumption #-}
|
|
| 2 | +{-# LANGUAGE NamedWildCards #-}
|
|
| 3 | +{-# LANGUAGE PartialTypeSignatures #-}
|
|
| 4 | +{-# LANGUAGE TypeFamilies #-}
|
|
| 5 | +{-# LANGUAGE UnicodeSyntax #-}
|
|
| 6 | + |
|
| 7 | +{-# OPTIONS_GHC -Wno-partial-type-signatures #-}
|
|
| 8 | + |
|
| 9 | +module T26225 where
|
|
| 10 | + |
|
| 11 | +-- Recall: ty1 is a subtype of ty2, written ty1 ⊑ ty2,
|
|
| 12 | +-- if we can use ty1 wherever ty2 is expected.
|
|
| 13 | +-- Can also read as "ty1 is more polymorphic than ty2".
|
|
| 14 | +-- Example: ∀ a. a -> a ⊑ Int -> Int, meaning that we can pass
|
|
| 15 | +-- the identity function where one is expecting a function of type Int -> Int.
|
|
| 16 | + |
|
| 17 | +-- Int -> (∀ a. a -> a) ⊑ α[tau]
|
|
| 18 | +-- Accepted by GHC.
|
|
| 19 | +ex0 :: ()
|
|
| 20 | +ex0 =
|
|
| 21 | + let
|
|
| 22 | + f :: Int -> (∀ a. a -> a)
|
|
| 23 | + f _ = id
|
|
| 24 | + g :: _α -> ()
|
|
| 25 | + g _ = ()
|
|
| 26 | + in g f
|
|
| 27 | + |
|
| 28 | +-- ((∀ a. a->a) -> Int) -> Bool ⊑ α[tau]
|
|
| 29 | +-- Rejected by GHC up to and including 9.14.
|
|
| 30 | +ex1' :: ()
|
|
| 31 | +ex1' =
|
|
| 32 | + let
|
|
| 33 | + f :: ((∀ a. a -> a) -> Int) -> Bool
|
|
| 34 | + f _ = False
|
|
| 35 | + g :: _α -> ()
|
|
| 36 | + g _ = ()
|
|
| 37 | + in g f
|
|
| 38 | + -- Couldn't match expected type ‘α’ with actual type ‘((∀ a. a -> a) -> Int) -> Bool’
|
|
| 39 | + |
|
| 40 | +-- ((∀ a. a->a) -> Int) -> Bool ⊑ β[tau] Bool
|
|
| 41 | +-- Rejected by GHC up to and including 9.14.
|
|
| 42 | +ex2' :: ()
|
|
| 43 | +ex2' =
|
|
| 44 | + let
|
|
| 45 | + f :: ((∀ a. a -> a) -> Int) -> Bool
|
|
| 46 | + f _ = False
|
|
| 47 | + g :: _β Bool -> ()
|
|
| 48 | + g _ = ()
|
|
| 49 | + in g f
|
|
| 50 | + -- Couldn't match expected type ‘β’ with actual type ‘(->) ((∀ a. a -> a) -> Int)’
|
|
| 51 | + |
|
| 52 | +-- ex3 :: β[tau] Bool ⊑ (∀ a. a->a) -> Bool
|
|
| 53 | +-- Rejected by GHC up to and including 9.14.
|
|
| 54 | +ex3 :: ()
|
|
| 55 | +ex3 =
|
|
| 56 | + let
|
|
| 57 | + f :: _β Bool
|
|
| 58 | + f = undefined
|
|
| 59 | + g :: ((∀ a. a -> a) -> Bool) -> ()
|
|
| 60 | + g _ = ()
|
|
| 61 | + in g f
|
|
| 62 | + -- Couldn't match expected type ‘β’ with actual type ‘(->) (∀ a. a -> a)’
|
|
| 63 | + |
|
| 64 | +-- ex3' :: F Int Bool ⊑ (∀ a. a->a) -> Bool, where F Int = (->) (Int -> Int)
|
|
| 65 | +-- Rejected by GHC up to and including 9.14.
|
|
| 66 | +ex3' :: ()
|
|
| 67 | +ex3' =
|
|
| 68 | + let
|
|
| 69 | + f :: F Int Bool
|
|
| 70 | + f _ = False
|
|
| 71 | + g :: ((∀ a. a -> a) -> Bool) -> ()
|
|
| 72 | + g _ = ()
|
|
| 73 | + in g f
|
|
| 74 | + -- • Couldn't match type: Int -> Int
|
|
| 75 | + -- with: ∀ a. a -> a
|
|
| 76 | + -- Expected: (∀ a. a -> a) -> Bool
|
|
| 77 | + -- Actual: F Int Bool
|
|
| 78 | +type family F a where { F Int = (->) (Int -> Int) } |
| 1 | +{-# LANGUAGE DeepSubsumption #-}
|
|
| 2 | +{-# LANGUAGE RankNTypes #-}
|
|
| 3 | + |
|
| 4 | +module T26225b where
|
|
| 5 | + |
|
| 6 | +f :: Int -> (forall a. a->a)
|
|
| 7 | +f _ x = x
|
|
| 8 | +g :: Int -> Bool -> Bool
|
|
| 9 | +g _ x = x
|
|
| 10 | + |
|
| 11 | +test3 b =
|
|
| 12 | + case b of
|
|
| 13 | + True -> f
|
|
| 14 | + False -> g
|
|
| 15 | +test3' b =
|
|
| 16 | + case b of
|
|
| 17 | + True -> g
|
|
| 18 | + False -> f
|
|
| 19 | +-- Both of these currently error with:
|
|
| 20 | +-- * Couldn't match type: forall a. a -> a
|
|
| 21 | +-- with: Bool -> Bool |
| ... | ... | @@ -861,6 +861,8 @@ test('DeepSubsumption06', normal, compile, ['-XHaskell98']) |
| 861 | 861 | test('DeepSubsumption07', normal, compile, ['-XHaskell2010'])
|
| 862 | 862 | test('DeepSubsumption08', normal, compile, [''])
|
| 863 | 863 | test('DeepSubsumption09', normal, compile, [''])
|
| 864 | +test('T26225', normal, compile, [''])
|
|
| 865 | +test('T26225b', normal, compile, [''])
|
|
| 864 | 866 | test('T21765', normal, compile, [''])
|
| 865 | 867 | test('T21951a', normal, compile, ['-Wredundant-strictness-flags'])
|
| 866 | 868 | test('T21951b', normal, compile, ['-Wredundant-strictness-flags'])
|
| 1 | - |
|
| 2 | -T12563.hs:8:15: error: [GHC-91028]
|
|
| 3 | - • Couldn't match expected type ‘(forall a. f a) -> f r’
|
|
| 4 | - with actual type ‘p’
|
|
| 5 | - Cannot equate type variable ‘p’
|
|
| 6 | - with a type involving polytypes: (forall a. f a) -> f r
|
|
| 7 | - ‘p’ is a rigid type variable bound by
|
|
| 8 | - the inferred type of x :: p -> f r
|
|
| 9 | - at T12563.hs:8:1-15
|
|
| 10 | - • In the first argument of ‘foo’, namely ‘g’
|
|
| 11 | - In the expression: foo g
|
|
| 12 | - In the expression: \ g -> foo g
|
|
| 13 | - • Relevant bindings include
|
|
| 14 | - g :: p (bound at T12563.hs:8:6)
|
|
| 15 | - x :: p -> f r (bound at T12563.hs:8:1) |
| 1 | - |
|
| 2 | 1 | T14618.hs:7:14: error: [GHC-25897]
|
| 3 | 2 | • Couldn't match expected type ‘b’ with actual type ‘a’
|
| 4 | 3 | ‘a’ is a rigid type variable bound by
|
| ... | ... | @@ -19,3 +18,4 @@ T14618.hs:7:14: error: [GHC-25897] |
| 19 | 18 | f' = f
|
| 20 | 19 | • Relevant bindings include
|
| 21 | 20 | safeCoerce :: a -> b (bound at T14618.hs:7:1)
|
| 21 | + |
| 1 | - |
|
| 2 | 1 | T6022.hs:4:1: error: [GHC-80003]
|
| 3 | - • Non type-variable argument in the constraint: Eq ([a] -> a)
|
|
| 2 | + • Non type-variable argument in the constraint: Eq ([t] -> t)
|
|
| 4 | 3 | • When checking the inferred type
|
| 5 | - f :: forall {a}. Eq ([a] -> a) => ([a] -> a) -> Bool
|
|
| 4 | + f :: forall {t}. Eq ([t] -> t) => ([t] -> t) -> Bool
|
|
| 6 | 5 | Suggested fix:
|
| 7 | 6 | Perhaps you intended to use the ‘FlexibleContexts’ extension
|
| 7 | + |
| 1 | - |
|
| 2 | 1 | T8883.hs:21:1: error: [GHC-80003]
|
| 3 | - • Non type-variable argument in the constraint: Functor (PF a)
|
|
| 2 | + • Non type-variable argument in the constraint: Functor (PF t)
|
|
| 4 | 3 | • When checking the inferred type
|
| 5 | - fold :: forall {a} {b}.
|
|
| 6 | - (Functor (PF a), Regular a) =>
|
|
| 7 | - (PF a b -> b) -> a -> b
|
|
| 4 | + fold :: forall {t} {b}.
|
|
| 5 | + (Functor (PF t), Regular t) =>
|
|
| 6 | + (PF t b -> b) -> t -> b
|
|
| 8 | 7 | Suggested fix:
|
| 9 | 8 | Perhaps you intended to use the ‘FlexibleContexts’ extension
|
| 9 | + |
| ... | ... | @@ -432,7 +432,7 @@ test('T12124', normal, compile_fail, ['']) |
| 432 | 432 | test('T12430', normal, compile_fail, [''])
|
| 433 | 433 | test('T12589', normal, compile_fail, [''])
|
| 434 | 434 | test('T12529', normal, compile_fail, [''])
|
| 435 | -test('T12563', normal, compile_fail, [''])
|
|
| 435 | +test('T12563', normal, compile, ['']) # Turns out we can accept this one after all!
|
|
| 436 | 436 | test('T12648', normal, compile_fail, [''])
|
| 437 | 437 | test('T12729', normal, compile_fail, [''])
|
| 438 | 438 | test('T12785b', normal, compile_fail, [''])
|
| 1 | - |
|
| 2 | 1 | tcfail140.hs:11:7: error: [GHC-83865]
|
| 3 | 2 | • Couldn't match expected type ‘t1 -> t’ with actual type ‘Int’
|
| 4 | 3 | • The function ‘f’ is applied to two visible arguments,
|
| ... | ... | @@ -17,13 +16,13 @@ tcfail140.hs:13:10: error: [GHC-83865] |
| 17 | 16 | rot :: p -> t (bound at tcfail140.hs:13:1)
|
| 18 | 17 | |
| 19 | 18 | tcfail140.hs:15:15: error: [GHC-83865]
|
| 20 | - • Couldn't match expected type ‘a -> b’ with actual type ‘Int’
|
|
| 19 | + • Couldn't match expected type ‘t -> b’ with actual type ‘Int’
|
|
| 21 | 20 | • In the first argument of ‘map’, namely ‘(3 `f`)’
|
| 22 | 21 | In the expression: map (3 `f`) xs
|
| 23 | 22 | In an equation for ‘bot’: bot xs = map (3 `f`) xs
|
| 24 | 23 | • Relevant bindings include
|
| 25 | - xs :: [a] (bound at tcfail140.hs:15:5)
|
|
| 26 | - bot :: [a] -> [b] (bound at tcfail140.hs:15:1)
|
|
| 24 | + xs :: [t] (bound at tcfail140.hs:15:5)
|
|
| 25 | + bot :: [t] -> [b] (bound at tcfail140.hs:15:1)
|
|
| 27 | 26 | |
| 28 | 27 | tcfail140.hs:17:8: error: [GHC-27346]
|
| 29 | 28 | • The data constructor ‘Just’ should have 1 argument, but has been given none
|
| ... | ... | @@ -36,3 +35,4 @@ tcfail140.hs:20:1: error: [GHC-83865] |
| 36 | 35 | • Couldn't match expected type ‘Int’ with actual type ‘t0 -> Bool’
|
| 37 | 36 | • The equation for ‘g’ has two visible arguments,
|
| 38 | 37 | but its type ‘Int -> Int’ has only one
|
| 38 | + |