[commit: ghc] wip/hasfield: Do not solve HasField constraints where the field is naughty or higher-rank (eb6f660)

git at git.haskell.org git at git.haskell.org
Mon May 16 08:07:17 UTC 2016


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

On branch  : wip/hasfield
Link       : http://ghc.haskell.org/trac/ghc/changeset/eb6f660b85c7d0ac173b314c8b30fd3a045efe6b/ghc

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

commit eb6f660b85c7d0ac173b314c8b30fd3a045efe6b
Author: Adam Gundry <adam at well-typed.com>
Date:   Tue Dec 22 16:34:59 2015 +0000

    Do not solve HasField constraints where the field is naughty or higher-rank


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

eb6f660b85c7d0ac173b314c8b30fd3a045efe6b
 compiler/typecheck/TcInteract.hs                         |  8 ++++++--
 testsuite/tests/overloadedrecflds/should_fail/all.T      |  1 +
 .../overloadedrecflds/should_fail/hasfieldfail02.hs      | 16 ++++++++++++++++
 .../overloadedrecflds/should_fail/hasfieldfail02.stderr  | 14 ++++++++++++++
 4 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/compiler/typecheck/TcInteract.hs b/compiler/typecheck/TcInteract.hs
index c0e37b0..d246b15 100644
--- a/compiler/typecheck/TcInteract.hs
+++ b/compiler/typecheck/TcInteract.hs
@@ -29,7 +29,7 @@ import PrelNames ( knownNatClassName, knownSymbolClassName,
 import TysWiredIn ( ipClass, typeNatKind, typeSymbolKind, heqDataCon,
                     coercibleDataCon )
 import TysPrim    ( eqPrimTyCon, eqReprPrimTyCon, mkProxyPrimTy )
-import Id( idType )
+import Id( idType, isNaughtyRecordSelector )
 import CoAxiom ( Eqn, CoAxiom(..), CoAxBranch(..), fromBranches )
 import Class
 import TyCon
@@ -2154,6 +2154,10 @@ matchHasField clas tys@[x_ty, r_ty, a_ty]
              inst_field_ty = substTy tenv field_ty
              theta = mkTyConApp eqPrimTyCon [liftedTypeKind, liftedTypeKind, inst_field_ty, a_ty ]
 
+       ; if isNaughtyRecordSelector sel_id || not (isTauTy inst_field_ty)
+         then return NoInstance
+         else do {
+
        ; let mk_ev [ev] = EvCast (EvExpr (mkHsLamConst proxy_ty (mkFunTy r_ty a_ty) body)) (mkTcSymCo ax)
                where
                 proxy_ty = mkProxyPrimTy typeSymbolKind x_ty
@@ -2166,7 +2170,7 @@ matchHasField clas tys@[x_ty, r_ty, a_ty]
                          , lir_mk_ev     = mk_ev
                          , lir_safe_over = True
                          })
-       } }
+       } } }
 matchHasField _ _ = return NoInstance
 
 mkHsLamConst :: Type -> Type -> HsExpr Id -> HsExpr Id
diff --git a/testsuite/tests/overloadedrecflds/should_fail/all.T b/testsuite/tests/overloadedrecflds/should_fail/all.T
index 9f5b780..5f378e9 100644
--- a/testsuite/tests/overloadedrecflds/should_fail/all.T
+++ b/testsuite/tests/overloadedrecflds/should_fail/all.T
@@ -33,3 +33,4 @@ test('T11167_ambiguous_fixity',
 test('hasfieldfail01',
      extra_clean(['HasFieldFail01_A.hi', 'HasFieldFail01_A.o']),
      multimod_compile_fail, ['hasfieldfail01', ''])
+test('hasfieldfail02', normal, compile_fail, [''])
diff --git a/testsuite/tests/overloadedrecflds/should_fail/hasfieldfail02.hs b/testsuite/tests/overloadedrecflds/should_fail/hasfieldfail02.hs
new file mode 100644
index 0000000..d3175d2
--- /dev/null
+++ b/testsuite/tests/overloadedrecflds/should_fail/hasfieldfail02.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE DataKinds, ExistentialQuantification, MagicHash, RankNTypes #-}
+
+import GHC.Prim (Proxy#, proxy#)
+import GHC.Records (HasField(..))
+
+data T = MkT { foo :: forall a . a -> a }
+data U = forall b . MkU { bar :: b }
+
+-- This should fail because foo is higher-rank.
+x = getField (proxy# :: Proxy# "foo") (MkT id)
+
+-- This should fail because bar is a naughty record selector (it
+-- involves an existential).
+y = getField (proxy# :: Proxy# "bar") (MkU True)
+
+main = return ()
diff --git a/testsuite/tests/overloadedrecflds/should_fail/hasfieldfail02.stderr b/testsuite/tests/overloadedrecflds/should_fail/hasfieldfail02.stderr
new file mode 100644
index 0000000..aea9fea
--- /dev/null
+++ b/testsuite/tests/overloadedrecflds/should_fail/hasfieldfail02.stderr
@@ -0,0 +1,14 @@
+
+hasfieldfail02.hs:10:5: error:
+    • No instance for (HasField "foo" T a1)
+        arising from a use of ‘getField’
+    • In the expression: getField (proxy# :: Proxy# "foo") (MkT id)
+      In an equation for ‘x’:
+          x = getField (proxy# :: Proxy# "foo") (MkT id)
+
+hasfieldfail02.hs:14:5: error:
+    • No instance for (HasField "bar" U a0)
+        arising from a use of ‘getField’
+    • In the expression: getField (proxy# :: Proxy# "bar") (MkU True)
+      In an equation for ‘y’:
+          y = getField (proxy# :: Proxy# "bar") (MkU True)



More information about the ghc-commits mailing list