[commit: ghc] wip/ttypeable: Fix #13264 (bb5953f)
git at git.haskell.org
git at git.haskell.org
Mon Feb 13 15:16:34 UTC 2017
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/ttypeable
Link : http://ghc.haskell.org/trac/ghc/changeset/bb5953f048b51a965a6b3204ae0ed5040d1e6979/ghc
>---------------------------------------------------------------
commit bb5953f048b51a965a6b3204ae0ed5040d1e6979
Author: Ben Gamari <ben at smart-cactus.org>
Date: Fri Feb 10 17:49:38 2017 -0500
Fix #13264
>---------------------------------------------------------------
bb5953f048b51a965a6b3204ae0ed5040d1e6979
compiler/typecheck/TcCanonical.hs | 24 ++++++++++++++++++++++--
compiler/typecheck/TcType.hs | 24 +++++++++++++++++++++++-
2 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/compiler/typecheck/TcCanonical.hs b/compiler/typecheck/TcCanonical.hs
index 1cfa9a5..ad8e939 100644
--- a/compiler/typecheck/TcCanonical.hs
+++ b/compiler/typecheck/TcCanonical.hs
@@ -541,6 +541,25 @@ track whether or not we've already flattened.
It is conceivable to do a better job at tracking whether or not a type
is flattened, but this is left as future work. (Mar '15)
+
+
+Note [FunTy and decomposing tycon applications]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When can_eq_nc' attempts to decompose a tycon application we haven't yet zonked.
+This means that we may very well have a FunTy containing a type of some unknown
+kind. For instance, we may have,
+
+ FunTy (a :: k) Int
+
+Where k is a unification variable. tcRepSplitTyConApp_maybe panics in the event
+that it sees such a type as it cannot determine the RuntimeReps which the (->)
+is applied to. Consequently, it is vital that we instead use
+tcRepSplitTyConApp_maybe', which simply returns Nothing in such a case.
+
+When this happens can_eq_nc' will fail to decompose, zonk, and try again.
+Zonking should fill the variable k, meaning that decomposition will succeed the
+second time around.
-}
canEqNC :: CtEvidence -> EqRel -> Type -> Type -> TcS (StopOrContinue Ct)
@@ -614,8 +633,9 @@ can_eq_nc' _flat _rdr_env _envs ev eq_rel ty1@(LitTy l1) _ (LitTy l2) _
-- Try to decompose type constructor applications
-- Including FunTy (s -> t)
can_eq_nc' _flat _rdr_env _envs ev eq_rel ty1 _ ty2 _
- | Just (tc1, tys1) <- tcRepSplitTyConApp_maybe ty1
- , Just (tc2, tys2) <- tcRepSplitTyConApp_maybe ty2
+ --- See Note [FunTy and decomposing type constructor applications].
+ | Just (tc1, tys1) <- tcRepSplitTyConApp_maybe' ty1
+ , Just (tc2, tys2) <- tcRepSplitTyConApp_maybe' ty2
, not (isTypeFamilyTyCon tc1)
, not (isTypeFamilyTyCon tc2)
= canTyConApp ev eq_rel tc1 tys1 tc2 tys2
diff --git a/compiler/typecheck/TcType.hs b/compiler/typecheck/TcType.hs
index 3581d87..63cc1ee 100644
--- a/compiler/typecheck/TcType.hs
+++ b/compiler/typecheck/TcType.hs
@@ -62,7 +62,8 @@ module TcType (
tcSplitPhiTy, tcSplitPredFunTy_maybe,
tcSplitFunTy_maybe, tcSplitFunTys, tcFunArgTy, tcFunResultTy, tcFunResultTyN,
tcSplitFunTysN,
- tcSplitTyConApp, tcSplitTyConApp_maybe, tcRepSplitTyConApp_maybe,
+ tcSplitTyConApp, tcSplitTyConApp_maybe,
+ tcRepSplitTyConApp_maybe, tcRepSplitTyConApp_maybe',
tcTyConAppTyCon, tcTyConAppTyCon_maybe, tcTyConAppArgs,
tcSplitAppTy_maybe, tcSplitAppTy, tcSplitAppTys, tcRepSplitAppTy_maybe,
tcGetTyVar_maybe, tcGetTyVar, nextRole,
@@ -1458,6 +1459,7 @@ tcSplitTyConApp_maybe :: HasCallStack => Type -> Maybe (TyCon, [Type])
tcSplitTyConApp_maybe ty | Just ty' <- coreView ty = tcSplitTyConApp_maybe ty'
tcSplitTyConApp_maybe ty = tcRepSplitTyConApp_maybe ty
+-- | Like 'tcSplitTyConApp_maybe' but doesn't look through type synonyms.
tcRepSplitTyConApp_maybe :: HasCallStack => Type -> Maybe (TyCon, [Type])
tcRepSplitTyConApp_maybe (TyConApp tc tys) = Just (tc, tys)
tcRepSplitTyConApp_maybe (FunTy arg res)
@@ -1469,6 +1471,26 @@ tcRepSplitTyConApp_maybe (FunTy arg res)
= pprPanic "tcRepSplitTyConApp_maybe" (ppr arg $$ ppr res)
tcRepSplitTyConApp_maybe _ = Nothing
+-- | Like 'tcRepSplitTyConApp_maybe', but returns 'Nothing' if,
+--
+-- 1. the type is structurally not a type constructor application, or
+--
+-- 2. the type is a function type (e.g. application of 'funTyCon'), but we
+-- currently don't even enough information to fully determine its RuntimeRep
+-- variables. For instance, @FunTy (a :: k) Int at .
+--
+-- By constrast 'tcRepSplitTyConApp_maybe' panics in the second case.
+--
+-- The behavior here is needed during canonicalization; see Note [FunTy and
+-- decomposing tycon applications] in TcCanonical for details.
+tcRepSplitTyConApp_maybe' :: HasCallStack => Type -> Maybe (TyCon, [Type])
+tcRepSplitTyConApp_maybe' (TyConApp tc tys) = Just (tc, tys)
+tcRepSplitTyConApp_maybe' (FunTy arg res)
+ | Just arg_rep <- getRuntimeRep_maybe arg
+ , Just res_rep <- getRuntimeRep_maybe res
+ = Just (funTyCon, [arg_rep, res_rep, arg, res])
+tcRepSplitTyConApp_maybe' _ = Nothing
+
-----------------------
tcSplitFunTys :: Type -> ([Type], Type)
More information about the ghc-commits
mailing list