[commit: ghc] master: In splitHsFunType, take account of prefix (->) (770e16f)

git at git.haskell.org git at git.haskell.org
Mon May 12 15:04:24 UTC 2014


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

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/770e16fceee60db0c2f79e3b77f6fc619bc1d864/ghc

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

commit 770e16fceee60db0c2f79e3b77f6fc619bc1d864
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date:   Mon May 12 16:02:36 2014 +0100

    In splitHsFunType, take account of prefix (->)
    
    This fixes Trac #9096


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

770e16fceee60db0c2f79e3b77f6fc619bc1d864
 compiler/hsSyn/HsTypes.lhs    | 31 ++++++++++++++++++++++++-------
 testsuite/tests/gadt/T9096.hs |  6 ++++++
 testsuite/tests/gadt/all.T    |  1 +
 3 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/compiler/hsSyn/HsTypes.lhs b/compiler/hsSyn/HsTypes.lhs
index 28c6a2b..6f65a12 100644
--- a/compiler/hsSyn/HsTypes.lhs
+++ b/compiler/hsSyn/HsTypes.lhs
@@ -45,6 +45,7 @@ import HsLit
 import Name( Name )
 import RdrName( RdrName )
 import DataCon( HsBang(..) )
+import TysPrim( funTyConName )
 import Type
 import HsDoc
 import BasicTypes
@@ -506,15 +507,31 @@ splitLHsClassTy_maybe ty
         HsKindSig ty _     -> checkl ty args
         _                  -> Nothing
 
--- Splits HsType into the (init, last) parts
+-- splitHsFunType decomposes a type (t1 -> t2 ... -> tn)
 -- Breaks up any parens in the result type: 
 --      splitHsFunType (a -> (b -> c)) = ([a,b], c)
-splitHsFunType :: LHsType name -> ([LHsType name], LHsType name)
-splitHsFunType (L _ (HsFunTy x y)) = (x:args, res)
-  where
-  (args, res) = splitHsFunType y
-splitHsFunType (L _ (HsParTy ty))  = splitHsFunType ty
-splitHsFunType other               = ([], other)
+-- Also deals with (->) t1 t2; that is why it only works on LHsType Name
+--   (see Trac #9096)
+splitHsFunType :: LHsType Name -> ([LHsType Name], LHsType Name)
+splitHsFunType (L _ (HsParTy ty)) 
+  = splitHsFunType ty
+
+splitHsFunType (L _ (HsFunTy x y))
+  | (args, res) <- splitHsFunType y
+  = (x:args, res)
+
+splitHsFunType orig_ty@(L _ (HsAppTy t1 t2)) 
+  = go t1 [t2]
+  where  -- Look for (->) t1 t2, possibly with parenthesisation
+    go (L _ (HsTyVar fn))    tys | fn == funTyConName
+                                 , [t1,t2] <- tys
+                                 , (args, res) <- splitHsFunType t2
+                                 = (t1:args, res)
+    go (L _ (HsAppTy t1 t2)) tys = go t1 (t2:tys)
+    go (L _ (HsParTy ty))    tys = go ty tys
+    go _                     _   = ([], orig_ty)  -- Failure to match
+
+splitHsFunType other = ([], other)
 \end{code}
 
 
diff --git a/testsuite/tests/gadt/T9096.hs b/testsuite/tests/gadt/T9096.hs
new file mode 100644
index 0000000..d778798
--- /dev/null
+++ b/testsuite/tests/gadt/T9096.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE GADTs #-}
+
+module T9096 where
+
+data Foo a where
+  MkFoo :: (->) a (Foo a)
diff --git a/testsuite/tests/gadt/all.T b/testsuite/tests/gadt/all.T
index 9192891..52a8812 100644
--- a/testsuite/tests/gadt/all.T
+++ b/testsuite/tests/gadt/all.T
@@ -122,3 +122,4 @@ test('T7321',
      ['$MAKE -s --no-print-directory T7321'])
 test('T7974', normal, compile, [''])
 test('T7558', normal, compile_fail, [''])
+test('T9096', normal, compile, [''])



More information about the ghc-commits mailing list