From 0aaf812ed0a4a4be9528b2e2f6b72bee7cd8002d Mon Sep 17 00:00:00 2001 From: Simon Peyton Jones Date: Thu, 18 Sep 2014 16:19:55 +0100 Subject: Clean up Coercible handling, and interaction of data families with newtypes This patch fixes Trac #9580, in which the Coercible machinery succeeded even though the relevant data constructor was not in scope. As usual I got dragged into a raft of refactoring changes, all for the better. * Delete TcEvidence.coercionToTcCoercion (now unused) * Move instNewTyConTF_maybe, instNewTyCon_maybe to FamInst, and rename them to tcInstNewTyConTF_maybe, tcInstNewTyCon (They both return TcCoercions.) * tcInstNewTyConTF_maybe also gets more convenient type, which improves TcInteract.getCoercibleInst * Define FamInst.tcLookupDataFamInst, and use it in TcDeriv, (as well as in tcInstNewTyConTF_maybe) * Improve error report for Coercible errors, when data familes are involved Another use of tcLookupDataFamInst * In TcExpr.tcTagToEnum, use tcLookupDataFamInst to replace local hacky code * Fix Coercion.instNewTyCon_maybe and Type.newTyConInstRhs to deal with eta-reduced newtypes, using (new) Type.unwrapNewTyConEtad_maybe and (new) Type.applyTysX Some small refactoring of TcSMonad.matchFam. --- testsuite/tests/indexed-types/should_fail/T9580.hs | 7 +++++++ testsuite/tests/indexed-types/should_fail/T9580.stderr | 10 ++++++++++ testsuite/tests/indexed-types/should_fail/T9580a.hs | 5 +++++ testsuite/tests/indexed-types/should_fail/all.T | 1 + testsuite/tests/typecheck/should_fail/TcCoercibleFail.stderr | 3 ++- 5 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 testsuite/tests/indexed-types/should_fail/T9580.hs create mode 100644 testsuite/tests/indexed-types/should_fail/T9580.stderr create mode 100644 testsuite/tests/indexed-types/should_fail/T9580a.hs (limited to 'testsuite') diff --git a/testsuite/tests/indexed-types/should_fail/T9580.hs b/testsuite/tests/indexed-types/should_fail/T9580.hs new file mode 100644 index 0000000000..de5455f493 --- /dev/null +++ b/testsuite/tests/indexed-types/should_fail/T9580.hs @@ -0,0 +1,7 @@ +module T9580 where + +import T9580a +import Data.Coerce + +foo :: Dimensional Int Double -> Double +foo x = coerce x diff --git a/testsuite/tests/indexed-types/should_fail/T9580.stderr b/testsuite/tests/indexed-types/should_fail/T9580.stderr new file mode 100644 index 0000000000..19ceefb0ff --- /dev/null +++ b/testsuite/tests/indexed-types/should_fail/T9580.stderr @@ -0,0 +1,10 @@ +[1 of 2] Compiling T9580a ( T9580a.hs, T9580a.o ) +[2 of 2] Compiling T9580 ( T9580.hs, T9580.o ) + +T9580.hs:7:9: + Could not coerce from ‘Dimensional Int Double’ to ‘Double’ + because the data constructor ‘T9580a.Quantity'’ + of newtype ‘Dimensional Int v’ is not in scope + arising from a use of ‘coerce’ + In the expression: coerce x + In an equation for ‘foo’: foo x = coerce x diff --git a/testsuite/tests/indexed-types/should_fail/T9580a.hs b/testsuite/tests/indexed-types/should_fail/T9580a.hs new file mode 100644 index 0000000000..578c8bafb8 --- /dev/null +++ b/testsuite/tests/indexed-types/should_fail/T9580a.hs @@ -0,0 +1,5 @@ +{-# LANGUAGE KindSignatures, TypeFamilies #-} +module T9580a( Dimensional ) where + +data family Dimensional var :: * -> * +newtype instance Dimensional Int v = Quantity' v diff --git a/testsuite/tests/indexed-types/should_fail/all.T b/testsuite/tests/indexed-types/should_fail/all.T index 2862f1e854..f06060efd0 100644 --- a/testsuite/tests/indexed-types/should_fail/all.T +++ b/testsuite/tests/indexed-types/should_fail/all.T @@ -128,4 +128,5 @@ test('T9357', normal, compile_fail, ['']) test('T9371', normal, compile_fail, ['']) test('T9433', normal, compile_fail, ['']) test('BadSock', normal, compile_fail, ['']) +test('T9580', normal, multimod_compile_fail, ['T9580', '']) diff --git a/testsuite/tests/typecheck/should_fail/TcCoercibleFail.stderr b/testsuite/tests/typecheck/should_fail/TcCoercibleFail.stderr index 5bb9210a13..b95b4cea67 100644 --- a/testsuite/tests/typecheck/should_fail/TcCoercibleFail.stderr +++ b/testsuite/tests/typecheck/should_fail/TcCoercibleFail.stderr @@ -33,7 +33,8 @@ TcCoercibleFail.hs:16:8: TcCoercibleFail.hs:18:8: Could not coerce from ‘Int’ to ‘Down Int’ - because the constructor of ‘Down’ is not imported + because the data constructor ‘Data.Ord.Down’ + of newtype ‘Down’ is not in scope arising from a use of ‘coerce’ In the expression: coerce In the expression: coerce $ one :: Down Int -- cgit v1.2.1