[commit: ghc] master: Put the decision of when a unification variable can unify with a polytype (073119e)
git at git.haskell.org
git at git.haskell.org
Fri Nov 21 13:03:05 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/073119e8e3eff54e64e2f89aa3a00dcf87b36ded/ghc
>---------------------------------------------------------------
commit 073119e8e3eff54e64e2f89aa3a00dcf87b36ded
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date: Fri Nov 21 10:59:49 2014 +0000
Put the decision of when a unification variable can unify with a polytype
This was being doing independently in two places. Now it's done in one
place, TcType.canUnifyWithPolyType
>---------------------------------------------------------------
073119e8e3eff54e64e2f89aa3a00dcf87b36ded
compiler/typecheck/TcType.lhs | 40 ++++++++++++++++++++++++++++++----------
compiler/typecheck/TcUnify.lhs | 26 +++-----------------------
2 files changed, 33 insertions(+), 33 deletions(-)
diff --git a/compiler/typecheck/TcType.lhs b/compiler/typecheck/TcType.lhs
index a9b44ab..5665730 100644
--- a/compiler/typecheck/TcType.lhs
+++ b/compiler/typecheck/TcType.lhs
@@ -41,6 +41,7 @@ module TcType (
metaTyVarUntouchables, setMetaTyVarUntouchables, metaTyVarUntouchables_maybe,
isTouchableMetaTyVar, isTouchableOrFmv,
isFloatedTouchableMetaTyVar,
+ canUnifyWithPolyType,
--------------------------------
-- Builders
@@ -1202,16 +1203,7 @@ occurCheckExpand dflags tv ty
where
details = ASSERT2( isTcTyVar tv, ppr tv ) tcTyVarDetails tv
- impredicative
- = case details of
- MetaTv { mtv_info = ReturnTv } -> True
- MetaTv { mtv_info = SigTv } -> False
- MetaTv { mtv_info = TauTv } -> xopt Opt_ImpredicativeTypes dflags
- || isOpenTypeKind (tyVarKind tv)
- -- Note [OpenTypeKind accepts foralls]
- -- in TcUnify
- _other -> True
- -- We can have non-meta tyvars in given constraints
+ impredicative = canUnifyWithPolyType dflags details (tyVarKind tv)
-- Check 'ty' is a tyvar, or can be expanded into one
go_sig_tv ty@(TyVarTy {}) = OC_OK ty
@@ -1259,8 +1251,36 @@ occurCheckExpand dflags tv ty
bad | Just ty' <- tcView ty -> go ty'
| otherwise -> bad
-- Failing that, try to expand a synonym
+
+canUnifyWithPolyType :: DynFlags -> TcTyVarDetails -> TcKind -> Bool
+canUnifyWithPolyType dflags details kind
+ = case details of
+ MetaTv { mtv_info = ReturnTv } -> True -- See Note [ReturnTv]
+ MetaTv { mtv_info = SigTv } -> False
+ MetaTv { mtv_info = TauTv } -> xopt Opt_ImpredicativeTypes dflags
+ || isOpenTypeKind kind
+ -- Note [OpenTypeKind accepts foralls]
+ _other -> True
+ -- We can have non-meta tyvars in given constraints
\end{code}
+Note [OpenTypeKind accepts foralls]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Here is a common paradigm:
+ foo :: (forall a. a -> a) -> Int
+ foo = error "urk"
+To make this work we need to instantiate 'error' with a polytype.
+A similar case is
+ bar :: Bool -> (forall a. a->a) -> Int
+ bar True = \x. (x 3)
+ bar False = error "urk"
+Here we need to instantiate 'error' with a polytype.
+
+But 'error' has an OpenTypeKind type variable, precisely so that
+we can instantiate it with Int#. So we also allow such type variables
+to be instantiate with foralls. It's a bit of a hack, but seems
+straightforward.
+
%************************************************************************
%* *
\subsection{Predicate types}
diff --git a/compiler/typecheck/TcUnify.lhs b/compiler/typecheck/TcUnify.lhs
index eb39038..966e564 100644
--- a/compiler/typecheck/TcUnify.lhs
+++ b/compiler/typecheck/TcUnify.lhs
@@ -1011,13 +1011,10 @@ checkTauTvUpdate dflags tv ty
_ -> return Nothing
| otherwise -> return (Just ty1) }
where
- info = ASSERT2( isMetaTyVar tv, ppr tv ) metaTyVarInfo tv
- -- See Note [ReturnTv] in TcType
+ details = ASSERT2( isMetaTyVar tv, ppr tv ) tcTyVarDetails tv
+ info = mtv_info details
is_return_tv = case info of { ReturnTv -> True; _ -> False }
-
- impredicative = xopt Opt_ImpredicativeTypes dflags
- || isOpenTypeKind (tyVarKind tv)
- -- Note [OpenTypeKind accepts foralls]
+ impredicative = canUnifyWithPolyType dflags details (tyVarKind tv)
defer_me :: TcType -> Bool
-- Checks for (a) occurrence of tv
@@ -1031,23 +1028,6 @@ checkTauTvUpdate dflags tv ty
defer_me (ForAllTy _ ty) = not impredicative || defer_me ty
\end{code}
-Note [OpenTypeKind accepts foralls]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Here is a common paradigm:
- foo :: (forall a. a -> a) -> Int
- foo = error "urk"
-To make this work we need to instantiate 'error' with a polytype.
-A similar case is
- bar :: Bool -> (forall a. a->a) -> Int
- bar True = \x. (x 3)
- bar False = error "urk"
-Here we need to instantiate 'error' with a polytype.
-
-But 'error' has an OpenTypeKind type variable, precisely so that
-we can instantiate it with Int#. So we also allow such type variables
-to be instantiate with foralls. It's a bit of a hack, but seems
-straightforward.
-
Note [Conservative unification check]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When unifying (tv ~ rhs), w try to avoid creating deferred constraints
More information about the ghc-commits
mailing list