[commit: ghc] type-nats-simple: Generalize CoAxiomRule to support non-nominal Roles. Add coreLint checks. (cf2b52b)

git at git.haskell.org git at git.haskell.org
Sat Sep 7 22:49:27 CEST 2013


Repository : ssh://git@git.haskell.org/ghc

On branch  : type-nats-simple
Link       : http://ghc.haskell.org/trac/ghc/changeset/cf2b52bb7ce82f47b146eabe78ddde8ae164dcf1/ghc

>---------------------------------------------------------------

commit cf2b52bb7ce82f47b146eabe78ddde8ae164dcf1
Author: Iavor S. Diatchki <iavor.diatchki at gmail.com>
Date:   Sat Sep 7 13:43:30 2013 -0700

    Generalize CoAxiomRule to support non-nominal Roles.  Add coreLint checks.


>---------------------------------------------------------------

cf2b52bb7ce82f47b146eabe78ddde8ae164dcf1
 compiler/coreSyn/CoreLint.lhs    |   42 ++++++++++++++++++++++++++++++--------
 compiler/typecheck/TcTypeNats.hs |    6 ++++--
 compiler/types/CoAxiom.lhs       |    5 +++--
 compiler/types/Coercion.lhs      |    2 +-
 compiler/types/OptCoercion.lhs   |    4 ++--
 5 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/compiler/coreSyn/CoreLint.lhs b/compiler/coreSyn/CoreLint.lhs
index 3d5e93a..57604b3 100644
--- a/compiler/coreSyn/CoreLint.lhs
+++ b/compiler/coreSyn/CoreLint.lhs
@@ -981,22 +981,46 @@ lintCoercion this@(AxiomRuleCo co ts cs)
   = do _ks <- mapM lintType ts
        eqs <- mapM lintCoercion cs
 
-       let unexpected_roles = [ r | (_,_,_,r) <- eqs, r /= Nominal ]
-       unless (null unexpected_roles) $
-          failWithL $ err "CoAxiomRule applied to non-nominal coercion(s)"
-                          (map ppr unexpected_roles)
+       let tyNum = length ts
+
+       case compare (coaxrTypeArity co) tyNum of
+         EQ -> return ()
+         LT -> err "Too many type arguments"
+                    [ txt "expected" <+> int (coaxrTypeArity co)
+                    , txt "provided" <+> int tyNum ]
+         GT -> err "Not enough type arguments"
+                    [ txt "expected" <+> int (coaxrTypeArity co)
+                          , txt "provided" <+> int tyNum ]
+       checkRoles 0 (coaxrAsmpRoles co) eqs
 
        case coaxrProves co ts [ Pair l r | (_,l,r,_) <- eqs ] of
-         Nothing -> failWithL $ err "Malformed use of AxiomRuleCo" [ ppr this ]
+         Nothing -> err "Malformed use of AxiomRuleCo" [ ppr this ]
          Just (Pair l r) ->
            do kL <- lintType l
               kR <- lintType r
-              checkL (eqKind kL kR)
-                $ err "Kind error in CoAxiomRule" [ppr kL <+> txt "/=" <+> ppr kR]
-              return (kL, l, r, Nominal)
+              unless (eqKind kL kR)
+                $ err "Kind error in CoAxiomRule"
+                       [ppr kL <+> txt "/=" <+> ppr kR]
+              return (kL, l, r, coaxrRole co)
   where
   txt       = ptext . sLit
-  err m xs  = hang (txt m) 2 $ vcat (txt "Rule:" <+> ppr (coaxrName co) : xs)
+  err m xs  = failWithL $
+                hang (txt m) 2 $ vcat (txt "Rule:" <+> ppr (coaxrName co) : xs)
+
+  checkRoles n (e : es) ((_,_,_,r) : rs)
+    | e == r    = checkRoles (n+1) es rs
+    | otherwise = err "Argument roles mismatch"
+                      [ txt "In argument:" <+> int (n+1)
+                      , txt "Expected:" <+> ppr e
+                      , txt "Found:" <+> ppr r ]
+  checkRoles _ [] []  = return ()
+  checkRoles n [] rs  = err "Too many coercion arguments"
+                          [ txt "Expected:" <+> int n
+                          , txt "Provided:" <+> int (n + length rs) ]
+
+  checkRoles n es []  = err "Not enough coercion arguments"
+                          [ txt "Expected:" <+> int (n + length es)
+                          , txt "Provided:" <+> int n ]
 
 \end{code}
 
diff --git a/compiler/typecheck/TcTypeNats.hs b/compiler/typecheck/TcTypeNats.hs
index 289b0e8..87ed825 100644
--- a/compiler/typecheck/TcTypeNats.hs
+++ b/compiler/typecheck/TcTypeNats.hs
@@ -158,7 +158,8 @@ mkBinAxiom str tc f =
   CoAxiomRule
     { coaxrName      = fsLit str
     , coaxrTypeArity = 2
-    , coaxrAsmpArity = 0
+    , coaxrAsmpRoles = []
+    , coaxrRole      = Nominal
     , coaxrProves    = \ts cs ->
         case (ts,cs) of
           ([s,t],[]) -> do x <- isNumLitTy s
@@ -173,7 +174,8 @@ mkAxiom1 str f =
   CoAxiomRule
     { coaxrName      = fsLit str
     , coaxrTypeArity = 1
-    , coaxrAsmpArity = 0
+    , coaxrAsmpRoles = []
+    , coaxrRole      = Nominal
     , coaxrProves    = \ts cs ->
         case (ts,cs) of
           ([s],[]) -> return (f s)
diff --git a/compiler/types/CoAxiom.lhs b/compiler/types/CoAxiom.lhs
index c750321..671e857 100644
--- a/compiler/types/CoAxiom.lhs
+++ b/compiler/types/CoAxiom.lhs
@@ -487,8 +487,9 @@ type Eqn = Pair Type
 -- | For now, we work only with nominal equality.
 data CoAxiomRule = CoAxiomRule
   { coaxrName      :: FastString
-  , coaxrTypeArity :: Int
-  , coaxrAsmpArity :: Int
+  , coaxrTypeArity :: Int       -- number of type argumentInts
+  , coaxrAsmpRoles :: [Role]    -- roles of parameter equations
+  , coaxrRole      :: Role      -- role of resulting equation
   , coaxrProves    :: [Type] -> [Eqn] -> Maybe Eqn
     -- ^ This returns @Nothing@ when we don't like
     -- the supplied arguments.
diff --git a/compiler/types/Coercion.lhs b/compiler/types/Coercion.lhs
index 77d280e..49e37fa 100644
--- a/compiler/types/Coercion.lhs
+++ b/compiler/types/Coercion.lhs
@@ -1784,7 +1784,7 @@ coercionRole = go
     go (LRCo _ _)           = Nominal
     go (InstCo co _)        = go co
     go (SubCo _)            = Representational
-    go (AxiomRuleCo _ _ _)  = Nominal
+    go (AxiomRuleCo c _ _)  = coaxrRole c
 \end{code}
 
 Note [Nested InstCos]
diff --git a/compiler/types/OptCoercion.lhs b/compiler/types/OptCoercion.lhs
index 3397ca7..1a06445 100644
--- a/compiler/types/OptCoercion.lhs
+++ b/compiler/types/OptCoercion.lhs
@@ -227,9 +227,9 @@ opt_co' env sym _ (SubCo co) = opt_co env sym (Just Representational) co
 -- XXX: We could add another field to CoAxiomRule that
 -- would allow us to do custom simplifications.
 opt_co' env sym mrole (AxiomRuleCo co ts cs) =
-  wrapRole mrole Nominal $
+  wrapRole mrole (coaxrRole co) $
     AxiomRuleCo co (map (substTy env) ts)
-                   (map (opt_co env sym (Just Nominal)) cs)
+                   (zipWith (opt_co env sym) (map Just (coaxrAsmpRoles co)) cs)
 
 
 





More information about the ghc-commits mailing list