[commit: ghc] wip/T9233: Address #9233. (6772f8f)
git at git.haskell.org
git at git.haskell.org
Tue Jul 15 20:47:07 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/T9233
Link : http://ghc.haskell.org/trac/ghc/changeset/6772f8f2ac70fa6dc246aff001ddbd1533db4b5b/ghc
>---------------------------------------------------------------
commit 6772f8f2ac70fa6dc246aff001ddbd1533db4b5b
Author: Richard Eisenberg <eir at cis.upenn.edu>
Date: Tue Jul 15 16:45:06 2014 -0400
Address #9233.
The implementation of coercionRole on an NthCo coercion was
terrible terrible terrible when called on deeply-nested NthCo's.
This commit includes a streamlined algorithm to get this role.
>---------------------------------------------------------------
6772f8f2ac70fa6dc246aff001ddbd1533db4b5b
compiler/types/Coercion.lhs | 35 ++++++++++++++++++++++++++++++++---
1 file changed, 32 insertions(+), 3 deletions(-)
diff --git a/compiler/types/Coercion.lhs b/compiler/types/Coercion.lhs
index b33eae9..3c1221a 100644
--- a/compiler/types/Coercion.lhs
+++ b/compiler/types/Coercion.lhs
@@ -1854,13 +1854,42 @@ coercionRole = go
go (UnivCo r _ _) = r
go (SymCo co) = go co
go (TransCo co1 _) = go co1 -- same as go co2
- go (NthCo n co) = let Pair ty1 _ = coercionKind co
- (tc, _) = splitTyConApp ty1
- in nthRole (coercionRole co) tc n
+ go (NthCo n co) = nthCoRole n co
go (LRCo _ _) = Nominal
go (InstCo co _) = go co
go (SubCo _) = Representational
go (AxiomRuleCo c _ _) = coaxrRole c
+
+-- | Gets the role of an NthCo. This is implemented separately
+-- because the naive version was very very slow. See #9233.
+nthCoRole :: Int -> Coercion -> Role
+nthCoRole n0 co0
+ | Representational <- r
+ = nthRole r tc n0
+ | otherwise
+ = r -- Nominal and Phantom are simpler!
+ where
+ (tc, r) = tycon_role co0
+
+ tycon_role (Refl r ty)
+ = (tyConAppTyCon ty, r)
+ tycon_role (TyConAppCo r tc _) = (tc, r)
+ tycon_role (CoVarCo cv)
+ = (tyConAppTyCon $ fst $ coVarKind cv, coVarRole cv)
+ tycon_role (UnivCo r ty1 _)
+ = (tyConAppTyCon ty1, r)
+ tycon_role (SymCo co) = tycon_role co
+ tycon_role (TransCo co1 _) = tycon_role co1
+ tycon_role (NthCo n co)
+ = case tycon_role co of
+ (tc1, Representational) -> (tc1, nthRole Representational tc1 n)
+ (_, role) -> (panic "tycon_role NthCo", role)
+ tycon_role (LRCo {})
+ = (panic "tycon_role LRCo", Nominal)
+ tycon_role co
+ -- can't really improve upon other algorithms in other cases
+ = (tyConAppTyCon $ pFst $ coercionKind co, coercionRole co)
+
\end{code}
Note [Nested InstCos]
More information about the ghc-commits
mailing list