summaryrefslogtreecommitdiff
path: root/compiler/typecheck/TcType.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/typecheck/TcType.hs')
-rw-r--r--compiler/typecheck/TcType.hs111
1 files changed, 66 insertions, 45 deletions
diff --git a/compiler/typecheck/TcType.hs b/compiler/typecheck/TcType.hs
index 3534b46115..b46685eb36 100644
--- a/compiler/typecheck/TcType.hs
+++ b/compiler/typecheck/TcType.hs
@@ -24,6 +24,10 @@ module TcType (
TcTyVar, TcTyVarSet, TcDTyVarSet, TcTyCoVarSet, TcDTyCoVarSet,
TcKind, TcCoVar, TcTyCoVar, TcTyBinder,
+ ExpType(..), ExpSigmaType, ExpRhoType, mkCheckExpType,
+
+ SyntaxOpType(..), synKnownType, mkSynFunTys,
+
-- TcLevel
TcLevel(..), topTcLevel, pushTcLevel, isTopTcLevel,
strictlyDeeperThan, sameDepthAs, fmvTcLevel,
@@ -35,7 +39,7 @@ module TcType (
MetaDetails(Flexi, Indirect), MetaInfo(..), TauTvFlavour(..),
isImmutableTyVar, isSkolemTyVar, isMetaTyVar, isMetaTyVarTy, isTyVarTy,
isSigTyVar, isOverlappableTyVar, isTyConableTyVar,
- isFskTyVar, isFmvTyVar, isFlattenTyVar, isReturnTyVar,
+ isFskTyVar, isFmvTyVar, isFlattenTyVar,
isAmbiguousTyVar, metaTvRef, metaTyVarInfo,
isFlexi, isIndirect, isRuntimeUnkSkol,
metaTyVarTcLevel, setMetaTyVarTcLevel, metaTyVarTcLevel_maybe,
@@ -68,7 +72,7 @@ module TcType (
-- Again, newtypes are opaque
eqType, eqTypes, cmpType, cmpTypes, eqTypeX,
pickyEqType, tcEqType, tcEqKind, tcEqTypeNoKindCheck, tcEqTypeVis,
- isSigmaTy, isRhoTy, isOverloadedTy,
+ isSigmaTy, isRhoTy, isRhoExpTy, isOverloadedTy,
isFloatingTy, isDoubleTy, isFloatTy, isIntTy, isWordTy, isStringTy,
isIntegerTy, isBoolTy, isUnitTy, isCharTy,
isTauTy, isTauTyCon, tcIsTyVarTy, tcIsForAllTy,
@@ -274,6 +278,59 @@ type TcTyCoVarSet = TyCoVarSet
type TcDTyVarSet = DTyVarSet
type TcDTyCoVarSet = DTyCoVarSet
+-- | An expected type to check against during type-checking.
+-- See Note [ExpType] in TcMType, where you'll also find manipulators.
+data ExpType = Check TcType
+ | Infer Unique -- for debugging only
+ TcLevel -- See Note [TcLevel of ExpType] in TcMType
+ Kind
+ (IORef (Maybe TcType))
+
+type ExpSigmaType = ExpType
+type ExpRhoType = ExpType
+
+instance Outputable ExpType where
+ ppr (Check ty) = ppr ty
+ ppr (Infer u lvl ki _)
+ = parens (text "Infer" <> braces (ppr u <> comma <> ppr lvl)
+ <+> dcolon <+> ppr ki)
+
+-- | Make an 'ExpType' suitable for checking.
+mkCheckExpType :: TcType -> ExpType
+mkCheckExpType = Check
+
+-- | What to expect for an argument to a rebindable-syntax operator.
+-- Quite like 'Type', but allows for holes to be filled in by tcSyntaxOp.
+-- The callback called from tcSyntaxOp gets a list of types; the meaning
+-- of these types is determined by a left-to-right depth-first traversal
+-- of the 'SyntaxOpType' tree. So if you pass in
+--
+-- > SynAny `SynFun` (SynList `SynFun` SynType Int) `SynFun` SynAny
+--
+-- you'll get three types back: one for the first 'SynAny', the /element/
+-- type of the list, and one for the last 'SynAny'. You don't get anything
+-- for the 'SynType', because you've said positively that it should be an
+-- Int, and so it shall be.
+--
+-- This is defined here to avoid defining it in TcExpr.hs-boot.
+data SyntaxOpType
+ = SynAny -- ^ Any type
+ | SynRho -- ^ A rho type, deeply skolemised or instantiated as appropriate
+ | SynList -- ^ A list type. You get back the element type of the list
+ | SynFun SyntaxOpType SyntaxOpType
+ -- ^ A function.
+ | SynType ExpType -- ^ A known type.
+infixr 0 `SynFun`
+
+-- | Like 'SynType' but accepts a regular TcType
+synKnownType :: TcType -> SyntaxOpType
+synKnownType = SynType . mkCheckExpType
+
+-- | Like 'mkFunTys' but for 'SyntaxOpType'
+mkSynFunTys :: [SyntaxOpType] -> ExpType -> SyntaxOpType
+mkSynFunTys arg_tys res_ty = foldr SynFun (SynType res_ty) arg_tys
+
+
{-
Note [TcRhoType]
~~~~~~~~~~~~~~~~
@@ -313,35 +370,6 @@ Similarly consider
When doing kind inference on {S,T} we don't want *skolems* for k1,k2,
because they end up unifying; we want those SigTvs again.
-Note [ReturnTv]
-~~~~~~~~~~~~~~~
-We sometimes want to convert a checking algorithm into an inference
-algorithm. An easy way to do this is to "check" that a term has a
-metavariable as a type. But, we must be careful to allow that metavariable
-to unify with *anything*. (Well, anything that doesn't fail an occurs-check.)
-This is what ReturnTv means.
-
-For example, if we have
-
- (undefined :: (forall a. TF1 a ~ TF2 a => a)) x
-
-we'll call (tcInfer . tcExpr) on the function expression. tcInfer will
-create a ReturnTv to represent the expression's type. We really need this
-ReturnTv to become set to (forall a. TF1 a ~ TF2 a => a) despite the fact
-that this type mentions type families and is a polytype.
-
-However, we must also be careful to make sure that the ReturnTvs really
-always do get unified with something -- we don't want these floating
-around in the solver. So, we check after running the checker to make
-sure the ReturnTv is filled. If it's not, we set it to a TauTv.
-
-We can't ASSERT that no ReturnTvs hit the solver, because they
-can if there's, say, a kind error that stops checkTauTvUpdate from
-working. This happens in test case typecheck/should_fail/T5570, for
-example.
-
-See also the commentary on #9404.
-
Note [TyVars and TcTyVars]
~~~~~~~~~~~~~~~~~~~~~~~~~~
The Var type has constructors TyVar and TcTyVar. They are used
@@ -396,10 +424,6 @@ data MetaInfo
-- A TauTv is always filled in with a tau-type, which
-- never contains any ForAlls.
- | ReturnTv -- Can unify with *anything*. Used to convert a
- -- type "checking" algorithm into a type inference algorithm.
- -- See Note [ReturnTv]
-
| SigTv -- A variant of TauTv, except that it should not be
-- unified with a type, only with a type variable
-- SigTvs are only distinguished to improve error messages
@@ -607,7 +631,6 @@ pprTcTyVarDetails (MetaTv { mtv_info = info, mtv_tclvl = tclvl })
= pp_info <> colon <> ppr tclvl
where
pp_info = case info of
- ReturnTv -> text "ret"
TauTv -> text "tau"
SigTv -> text "sig"
FlatMetaTv -> text "fuv"
@@ -835,7 +858,7 @@ isImmutableTyVar tv
isTyConableTyVar, isSkolemTyVar, isOverlappableTyVar,
isMetaTyVar, isAmbiguousTyVar,
- isFmvTyVar, isFskTyVar, isFlattenTyVar, isReturnTyVar :: TcTyVar -> Bool
+ isFmvTyVar, isFskTyVar, isFlattenTyVar :: TcTyVar -> Bool
isTyConableTyVar tv
-- True of a meta-type variable that can be filled in
@@ -884,11 +907,6 @@ isMetaTyVar tv
_ -> False
| otherwise = False
-isReturnTyVar tv
- = case tcTyVarDetails tv of
- MetaTv { mtv_info = ReturnTv } -> True
- _ -> False
-
-- isAmbiguousTyVar is used only when reporting type errors
-- It picks out variables that are unbound, namely meta
-- type variables and the RuntimUnk variables created by
@@ -1409,8 +1427,7 @@ occurCheckExpand :: DynFlags -> TcTyVar -> Type -> OccCheckResult Type
-- See Note [Occurs check expansion]
-- Check whether
-- a) the given variable occurs in the given type.
--- b) there is a forall in the type (unless we have -XImpredicativeTypes
--- or it's a ReturnTv
+-- b) there is a forall in the type (unless we have -XImpredicativeTypes)
-- c) if it's a SigTv, ty should be a tyvar
--
-- We may have needed to do some type synonym unfolding in order to
@@ -1558,7 +1575,6 @@ occurCheckExpand dflags tv ty
canUnifyWithPolyType :: DynFlags -> TcTyVarDetails -> Bool
canUnifyWithPolyType dflags details
= case details of
- MetaTv { mtv_info = ReturnTv } -> True -- See Note [ReturnTv]
MetaTv { mtv_info = SigTv } -> False
MetaTv { mtv_info = TauTv } -> xopt LangExt.ImpredicativeTypes dflags
_other -> True
@@ -1817,6 +1833,11 @@ isRhoTy (ForAllTy (Named {}) _) = False
isRhoTy (ForAllTy (Anon a) r) = not (isPredTy a) && isRhoTy r
isRhoTy _ = True
+-- | Like 'isRhoTy', but also says 'True' for 'Infer' types
+isRhoExpTy :: ExpType -> Bool
+isRhoExpTy (Check ty) = isRhoTy ty
+isRhoExpTy (Infer {}) = True
+
isOverloadedTy :: Type -> Bool
-- Yes for a type of a function that might require evidence-passing
-- Used only by bindLocalMethods