diff options
author | sheaf <sam.derbyshire@gmail.com> | 2021-11-09 23:23:35 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-11-10 18:19:37 -0500 |
commit | 1540f556a4501056056eec7d45d3c9246e8213d9 (patch) | |
tree | 10b836f740100da5d47932e4c7b6df766a35ba64 | |
parent | dfb9913c530d9132700fd5252c763e43976ece45 (diff) | |
download | haskell-1540f556a4501056056eec7d45d3c9246e8213d9.tar.gz |
Clarify hs-boot file default method restrictions
The user guide wrongly stated that default methods should not
be included in hs-boot files. In fact, if the class is not left
abstract (no methods, no superclass constraints, ...) then the
defaults must be provided and match with those given in the .hs
file.
We add some tests for this, as there were no tests in the testsuite
that gave rise to the "missing default methods" error.
Fixes #20588
-rw-r--r-- | docs/users_guide/separate_compilation.rst | 10 | ||||
-rw-r--r-- | testsuite/tests/typecheck/should_compile/T20588b.hs | 15 | ||||
-rw-r--r-- | testsuite/tests/typecheck/should_compile/T20588b.hs-boot | 10 | ||||
-rw-r--r-- | testsuite/tests/typecheck/should_compile/T20588b_aux.hs | 4 | ||||
-rw-r--r-- | testsuite/tests/typecheck/should_compile/all.T | 1 | ||||
-rw-r--r-- | testsuite/tests/typecheck/should_fail/T20588.hs | 15 | ||||
-rw-r--r-- | testsuite/tests/typecheck/should_fail/T20588.hs-boot | 12 | ||||
-rw-r--r-- | testsuite/tests/typecheck/should_fail/T20588.stderr | 29 | ||||
-rw-r--r-- | testsuite/tests/typecheck/should_fail/T20588_aux.hs | 4 | ||||
-rw-r--r-- | testsuite/tests/typecheck/should_fail/all.T | 1 |
10 files changed, 97 insertions, 4 deletions
diff --git a/docs/users_guide/separate_compilation.rst b/docs/users_guide/separate_compilation.rst index c6e9b7d0b6..b580c9ab18 100644 --- a/docs/users_guide/separate_compilation.rst +++ b/docs/users_guide/separate_compilation.rst @@ -864,10 +864,12 @@ A hs-boot file is written in a subset of Haskell: You cannot use ``deriving`` on a data type declaration; write an ``instance`` declaration instead. -- Class declarations is exactly as in Haskell, except that you may not - put default method declarations. You can also omit all the - superclasses and class methods entirely; but you must either omit - them all or put them all in. +- Class declarations can either be given in full, exactly as in Haskell, + or they can be given abstractly by omitting everything other than the + instance head: no superclasses, no class methods, no associated types. + If the class declaration is given in full, the default delarations + must also match; this applies to both default methods and default + declarations for associated types. - You can include instance declarations just as in Haskell; but omit the "where" part. diff --git a/testsuite/tests/typecheck/should_compile/T20588b.hs b/testsuite/tests/typecheck/should_compile/T20588b.hs new file mode 100644 index 0000000000..2c0b2d9afd --- /dev/null +++ b/testsuite/tests/typecheck/should_compile/T20588b.hs @@ -0,0 +1,15 @@ + +{-# LANGUAGE TypeFamilies #-} + +module T20588b where + +import Data.Kind + +class C (a :: Type) where + {-# MINIMAL meth #-} + meth :: a -> a + meth = id + +class D (a :: Type) where + type family T a :: Type + type instance T a = Int diff --git a/testsuite/tests/typecheck/should_compile/T20588b.hs-boot b/testsuite/tests/typecheck/should_compile/T20588b.hs-boot new file mode 100644 index 0000000000..387d3798e4 --- /dev/null +++ b/testsuite/tests/typecheck/should_compile/T20588b.hs-boot @@ -0,0 +1,10 @@ + +{-# LANGUAGE TypeFamilies #-} + +module T20588b where + +import Data.Kind + +class C (a :: Type) +class D (a :: Type) + diff --git a/testsuite/tests/typecheck/should_compile/T20588b_aux.hs b/testsuite/tests/typecheck/should_compile/T20588b_aux.hs new file mode 100644 index 0000000000..1211907bf5 --- /dev/null +++ b/testsuite/tests/typecheck/should_compile/T20588b_aux.hs @@ -0,0 +1,4 @@ +module T20588b_aux where + +import {-# SOURCE #-} T20588b + diff --git a/testsuite/tests/typecheck/should_compile/all.T b/testsuite/tests/typecheck/should_compile/all.T index 9aad00f982..eb0520be2c 100644 --- a/testsuite/tests/typecheck/should_compile/all.T +++ b/testsuite/tests/typecheck/should_compile/all.T @@ -808,3 +808,4 @@ test('T20187b', normal, compile, ['-Wredundant-strictness-flags']) test('T20356', normal, compile, ['']) test('T20584', normal, compile, ['']) test('T20584b', normal, compile, ['']) +test('T20588b', [extra_files(['T20588b.hs', 'T20588b.hs-boot', 'T20588b_aux.hs'])], multimod_compile, ['T20588b_aux.hs', '-v0']) diff --git a/testsuite/tests/typecheck/should_fail/T20588.hs b/testsuite/tests/typecheck/should_fail/T20588.hs new file mode 100644 index 0000000000..475c68ef2d --- /dev/null +++ b/testsuite/tests/typecheck/should_fail/T20588.hs @@ -0,0 +1,15 @@ + +{-# LANGUAGE TypeFamilies #-} + +module T20588 where + +import Data.Kind + +class C (a :: Type) where + {-# MINIMAL meth #-} + meth :: a -> a + meth = id + +class D (a :: Type) where + type family T a :: Type + type instance T a = Int diff --git a/testsuite/tests/typecheck/should_fail/T20588.hs-boot b/testsuite/tests/typecheck/should_fail/T20588.hs-boot new file mode 100644 index 0000000000..f879066ff2 --- /dev/null +++ b/testsuite/tests/typecheck/should_fail/T20588.hs-boot @@ -0,0 +1,12 @@ + +{-# LANGUAGE TypeFamilies #-} + +module T20588 where + +import Data.Kind + +class C (a :: Type) where + meth :: a -> a + +class D (a :: Type) where + type family T a :: Type diff --git a/testsuite/tests/typecheck/should_fail/T20588.stderr b/testsuite/tests/typecheck/should_fail/T20588.stderr new file mode 100644 index 0000000000..b9b7ed3f38 --- /dev/null +++ b/testsuite/tests/typecheck/should_fail/T20588.stderr @@ -0,0 +1,29 @@ + +T20588.hs-boot:8:1: error: + Class ‘C’ has conflicting definitions in the module + and its hs-boot file + Main module: type C :: * -> Constraint + class C a where + meth :: a -> a + {-# MINIMAL meth #-} + Boot file: type C :: * -> Constraint + class C a where + meth :: a -> a + {-# MINIMAL meth #-} + The methods do not match: + The default methods associated with ‘meth’ are different + +T20588.hs-boot:11:1: error: + Class ‘D’ has conflicting definitions in the module + and its hs-boot file + Main module: type D :: * -> Constraint + class D a where + type T :: * -> * + type family T a + Default: Int + Boot file: type D :: * -> Constraint + class D a where + type T :: * -> * + type family T a + The associated types do not match: + The associated type defaults differ diff --git a/testsuite/tests/typecheck/should_fail/T20588_aux.hs b/testsuite/tests/typecheck/should_fail/T20588_aux.hs new file mode 100644 index 0000000000..5764a5d875 --- /dev/null +++ b/testsuite/tests/typecheck/should_fail/T20588_aux.hs @@ -0,0 +1,4 @@ +module T20588_aux where + +import {-# SOURCE #-} T20588 + diff --git a/testsuite/tests/typecheck/should_fail/all.T b/testsuite/tests/typecheck/should_fail/all.T index 3aba1c9ac0..4dba37c780 100644 --- a/testsuite/tests/typecheck/should_fail/all.T +++ b/testsuite/tests/typecheck/should_fail/all.T @@ -624,3 +624,4 @@ test('T20122', normal, compile_fail, ['']) test('T20241b', normal, compile_fail, ['']) test('T20260', normal, compile_fail, ['']) test('OrdErr', normal, compile_fail, ['']) +test('T20588', [extra_files(['T20588.hs', 'T20588.hs-boot', 'T20588_aux.hs'])], multimod_compile_fail, ['T20588_aux.hs', '-v0']) |