diff options
author | Ryan Scott <ryan.gl.scott@gmail.com> | 2019-05-12 19:16:37 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-05-22 16:56:01 -0400 |
commit | 6efe04dee3f4c584e0cd043b8424718f0791d1be (patch) | |
tree | 8a69d7500190af046add0b4ae43e3e46b0f330a5 /testsuite | |
parent | 2c15b85eb2541a64df0cdf3705fb9aa068634004 (diff) | |
download | haskell-6efe04dee3f4c584e0cd043b8424718f0791d1be.tar.gz |
Use HsTyPats in associated type family defaults
Associated type family default declarations behave strangely in a
couple of ways:
1. If one tries to bind the type variables with an explicit `forall`,
the `forall`'d part will simply be ignored. (#16110)
2. One cannot use visible kind application syntax on the left-hand
sides of associated default equations, unlike every other form
of type family equation. (#16356)
Both of these issues have a common solution. Instead of using
`LHsQTyVars` to represent the left-hand side arguments of an
associated default equation, we instead use `HsTyPats`, which is what
other forms of type family equations use. In particular, here are
some highlights of this patch:
* `FamEqn` is no longer parameterized by a `pats` type variable, as
the `feqn_pats` field is now always `HsTyPats`.
* The new design for `FamEqn` in chronicled in
`Note [Type family instance declarations in HsSyn]`.
* `TyFamDefltEqn` now becomes the same thing as `TyFamInstEqn`. This
means that many of `TyFamDefltEqn`'s code paths can now reuse the
code paths for `TyFamInstEqn`, resulting in substantial
simplifications to various parts of the code dealing with
associated type family defaults.
Fixes #16110 and #16356.
Diffstat (limited to 'testsuite')
20 files changed, 211 insertions, 10 deletions
diff --git a/testsuite/tests/indexed-types/should_compile/T16110_Compile.hs b/testsuite/tests/indexed-types/should_compile/T16110_Compile.hs new file mode 100644 index 0000000000..f05a4513fb --- /dev/null +++ b/testsuite/tests/indexed-types/should_compile/T16110_Compile.hs @@ -0,0 +1,13 @@ +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeFamilies #-} +module T16110_Compile where + +class C a where + type T1 a b + type forall a b. T1 a b = Either a b + + type T2 a b + type forall x y. T2 x y = Either x y + + type T3 a b + type forall. T3 _ _ = Int diff --git a/testsuite/tests/indexed-types/should_compile/T16356_Compile1.hs b/testsuite/tests/indexed-types/should_compile/T16356_Compile1.hs new file mode 100644 index 0000000000..74dee38ac4 --- /dev/null +++ b/testsuite/tests/indexed-types/should_compile/T16356_Compile1.hs @@ -0,0 +1,25 @@ +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE TypeFamilies #-} +module T16356_Compile1 where + +import Data.Kind (Type) + +data B (a :: k) + +type family FClosed :: k -> Type where + FClosed @k = B @k + +type family FOpen :: k -> Type +type instance FOpen @k = B @k + +class FAssocClass k where + type FAssoc :: k -> Type + +instance FAssocClass k where + type FAssoc @k = B @k + +class FAssocDefaultClass k where + type FAssocDefault :: k -> Type + type FAssocDefault @k = B @k diff --git a/testsuite/tests/indexed-types/should_compile/T16356_Compile2.hs b/testsuite/tests/indexed-types/should_compile/T16356_Compile2.hs new file mode 100644 index 0000000000..46c8b00e1f --- /dev/null +++ b/testsuite/tests/indexed-types/should_compile/T16356_Compile2.hs @@ -0,0 +1,16 @@ +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE TypeFamilies #-} +{-# OPTIONS_GHC -Wunused-type-patterns #-} +module T16356_Compile2 where + +class C (a :: j) where + type T1 (a :: j) (b :: k) + type T1 @j @_ a _ = Int + + type T2 (a :: j) (b :: k) + type forall j (a :: j). T2 a _ = Int + + type T3 (a :: j) (b :: k) + type forall j (a :: j). T3 @j @_ a _ = Int diff --git a/testsuite/tests/indexed-types/should_compile/T16356_Compile2.stderr b/testsuite/tests/indexed-types/should_compile/T16356_Compile2.stderr new file mode 100644 index 0000000000..3aceb43604 --- /dev/null +++ b/testsuite/tests/indexed-types/should_compile/T16356_Compile2.stderr @@ -0,0 +1,18 @@ + +T16356_Compile2.hs:10:12: warning: [-Wunused-type-patterns] + Defined but not used on the right hand side: type variable ‘j’ + +T16356_Compile2.hs:10:17: warning: [-Wunused-type-patterns] + Defined but not used on the right hand side: type variable ‘a’ + +T16356_Compile2.hs:13:15: warning: [-Wunused-type-patterns] + Defined but not used on the right hand side: type variable ‘j’ + +T16356_Compile2.hs:13:18: warning: [-Wunused-type-patterns] + Defined but not used on the right hand side: type variable ‘a’ + +T16356_Compile2.hs:16:15: warning: [-Wunused-type-patterns] + Defined but not used on the right hand side: type variable ‘j’ + +T16356_Compile2.hs:16:18: warning: [-Wunused-type-patterns] + Defined but not used on the right hand side: type variable ‘a’ diff --git a/testsuite/tests/indexed-types/should_compile/all.T b/testsuite/tests/indexed-types/should_compile/all.T index c268f2638d..9142b8edcd 100644 --- a/testsuite/tests/indexed-types/should_compile/all.T +++ b/testsuite/tests/indexed-types/should_compile/all.T @@ -286,4 +286,7 @@ test('T15711', normal, compile, ['-ddump-types']) test('T15852', normal, compile, ['-ddump-types']) test('T15764a', normal, compile, ['']) test('T15740a', normal, compile, ['']) +test('T16110_Compile', normal, compile, ['']) +test('T16356_Compile1', normal, compile, ['']) +test('T16356_Compile2', normal, compile, ['']) test('T16632', normal, compile, ['-Wunused-type-patterns -fdiagnostics-show-caret']) diff --git a/testsuite/tests/indexed-types/should_fail/SimpleFail4.stderr b/testsuite/tests/indexed-types/should_fail/SimpleFail4.stderr index 8768c66613..b791ea7d82 100644 --- a/testsuite/tests/indexed-types/should_fail/SimpleFail4.stderr +++ b/testsuite/tests/indexed-types/should_fail/SimpleFail4.stderr @@ -1,6 +1,7 @@ -SimpleFail4.hs:10:11: error: - Unexpected type ‘Int’ - In the default declaration for ‘S2’ - A default declaration should have form - default S2 a = ... +SimpleFail4.hs:10:3: error: + • Illegal argument ‘Int’ in: + ‘type S2 Int = Char’ + The arguments to ‘S2’ must all be distinct type variables + • In the default type instance declaration for ‘S2’ + In the class declaration for ‘C2’ diff --git a/testsuite/tests/indexed-types/should_fail/T16110_Fail1.hs b/testsuite/tests/indexed-types/should_fail/T16110_Fail1.hs new file mode 100644 index 0000000000..2ec2332660 --- /dev/null +++ b/testsuite/tests/indexed-types/should_fail/T16110_Fail1.hs @@ -0,0 +1,19 @@ +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeFamilies #-} +module T16110_Fail1 where + +import Data.Kind + +class C (a :: Type) where + type T1 a b + type forall. T1 a b = Either a b + + type T2 a b + type forall dup dup dup a b. T2 a b = Either a b + + type T3 a b + type forall (a :: a) b. T3 a b = Either a b + + type T4 a b + type forall (a :: k) k b. T4 a b = Either a b diff --git a/testsuite/tests/indexed-types/should_fail/T16110_Fail1.stderr b/testsuite/tests/indexed-types/should_fail/T16110_Fail1.stderr new file mode 100644 index 0000000000..2381655876 --- /dev/null +++ b/testsuite/tests/indexed-types/should_fail/T16110_Fail1.stderr @@ -0,0 +1,18 @@ + +T16110_Fail1.hs:10:19: error: Not in scope: type variable ‘a’ + +T16110_Fail1.hs:10:21: error: Not in scope: type variable ‘b’ + +T16110_Fail1.hs:10:32: error: Not in scope: type variable ‘a’ + +T16110_Fail1.hs:10:34: error: Not in scope: type variable ‘b’ + +T16110_Fail1.hs:13:15: error: + Conflicting definitions for ‘dup’ + Bound at: T16110_Fail1.hs:13:15-17 + T16110_Fail1.hs:13:19-21 + T16110_Fail1.hs:13:23-25 + +T16110_Fail1.hs:16:21: error: Not in scope: type variable ‘a’ + +T16110_Fail1.hs:19:21: error: Not in scope: type variable ‘k’ diff --git a/testsuite/tests/indexed-types/should_fail/T16110_Fail2.hs b/testsuite/tests/indexed-types/should_fail/T16110_Fail2.hs new file mode 100644 index 0000000000..fe0a9506ad --- /dev/null +++ b/testsuite/tests/indexed-types/should_fail/T16110_Fail2.hs @@ -0,0 +1,9 @@ +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE TypeFamilies #-} +module T16110_Fail2 where + +-- Ensure that kind variables don't leak into error messages if they're not +-- pertitent to the issue at hand +class C (a :: j) where + type T (a :: j) (b :: k) (c :: k) + type T a b b = Int diff --git a/testsuite/tests/indexed-types/should_fail/T16110_Fail2.stderr b/testsuite/tests/indexed-types/should_fail/T16110_Fail2.stderr new file mode 100644 index 0000000000..caa46af46a --- /dev/null +++ b/testsuite/tests/indexed-types/should_fail/T16110_Fail2.stderr @@ -0,0 +1,7 @@ + +T16110_Fail2.hs:9:3: error: + • Illegal duplicate variable ‘b’ in: + ‘type T a b b = Int’ + The arguments to ‘T’ must all be distinct type variables + • In the default type instance declaration for ‘T’ + In the class declaration for ‘C’ diff --git a/testsuite/tests/indexed-types/should_fail/T16110_Fail3.hs b/testsuite/tests/indexed-types/should_fail/T16110_Fail3.hs new file mode 100644 index 0000000000..89b1f27bb6 --- /dev/null +++ b/testsuite/tests/indexed-types/should_fail/T16110_Fail3.hs @@ -0,0 +1,11 @@ +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE TypeFamilies #-} +module T16110_Fail3 where + +import Data.Kind + +-- Ensure that kind variables don't leak into error messages if they're not +-- pertitent to the issue at hand +class C (a :: j) where + type T (a :: j) (b :: Type) + type T a Int = Int diff --git a/testsuite/tests/indexed-types/should_fail/T16110_Fail3.stderr b/testsuite/tests/indexed-types/should_fail/T16110_Fail3.stderr new file mode 100644 index 0000000000..0fdea6a63a --- /dev/null +++ b/testsuite/tests/indexed-types/should_fail/T16110_Fail3.stderr @@ -0,0 +1,7 @@ + +T16110_Fail3.hs:11:3: error: + • Illegal argument ‘Int’ in: + ‘type T a Int = Int’ + The arguments to ‘T’ must all be distinct type variables + • In the default type instance declaration for ‘T’ + In the class declaration for ‘C’ diff --git a/testsuite/tests/indexed-types/should_fail/T16356_Fail1.hs b/testsuite/tests/indexed-types/should_fail/T16356_Fail1.hs new file mode 100644 index 0000000000..13a9cde2f3 --- /dev/null +++ b/testsuite/tests/indexed-types/should_fail/T16356_Fail1.hs @@ -0,0 +1,10 @@ +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE TypeFamilies #-} +module T16356_Fail1 where + +import Data.Kind + +class C (a :: j) where + type T (a :: j) + type T @Type a = Maybe a diff --git a/testsuite/tests/indexed-types/should_fail/T16356_Fail1.stderr b/testsuite/tests/indexed-types/should_fail/T16356_Fail1.stderr new file mode 100644 index 0000000000..b354d1db00 --- /dev/null +++ b/testsuite/tests/indexed-types/should_fail/T16356_Fail1.stderr @@ -0,0 +1,7 @@ + +T16356_Fail1.hs:10:3: error: + • Illegal argument ‘*’ in: + ‘type T @* a = Maybe a’ + The arguments to ‘T’ must all be distinct type variables + • In the default type instance declaration for ‘T’ + In the class declaration for ‘C’ diff --git a/testsuite/tests/indexed-types/should_fail/T16356_Fail2.hs b/testsuite/tests/indexed-types/should_fail/T16356_Fail2.hs new file mode 100644 index 0000000000..1ed53e02d9 --- /dev/null +++ b/testsuite/tests/indexed-types/should_fail/T16356_Fail2.hs @@ -0,0 +1,8 @@ +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE TypeFamilies #-} +module T16356_Fail2 where + +class C (a :: j) where + type T (a :: j) (b :: k) + type T @k @k a b = k diff --git a/testsuite/tests/indexed-types/should_fail/T16356_Fail2.stderr b/testsuite/tests/indexed-types/should_fail/T16356_Fail2.stderr new file mode 100644 index 0000000000..37f8159ae0 --- /dev/null +++ b/testsuite/tests/indexed-types/should_fail/T16356_Fail2.stderr @@ -0,0 +1,7 @@ + +T16356_Fail2.hs:8:3: error: + • Illegal duplicate variable ‘k’ in: + ‘type T @k @k a b = k’ + The arguments to ‘T’ must all be distinct type variables + • In the default type instance declaration for ‘T’ + In the class declaration for ‘C’ diff --git a/testsuite/tests/indexed-types/should_fail/T16356_Fail3.hs b/testsuite/tests/indexed-types/should_fail/T16356_Fail3.hs new file mode 100644 index 0000000000..da59f5399d --- /dev/null +++ b/testsuite/tests/indexed-types/should_fail/T16356_Fail3.hs @@ -0,0 +1,9 @@ +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE TypeFamilies #-} +module T16356_Fail3 where + +import Data.Kind + +class C a where + type T1 a + type T1 @Type a = a diff --git a/testsuite/tests/indexed-types/should_fail/T16356_Fail3.stderr b/testsuite/tests/indexed-types/should_fail/T16356_Fail3.stderr new file mode 100644 index 0000000000..e8b59175f4 --- /dev/null +++ b/testsuite/tests/indexed-types/should_fail/T16356_Fail3.stderr @@ -0,0 +1,6 @@ + +T16356_Fail3.hs:9:3: error: + • Cannot apply function of kind ‘* -> *’ + to visible kind argument ‘Type’ + • In the default type instance declaration for ‘T1’ + In the class declaration for ‘C’ diff --git a/testsuite/tests/indexed-types/should_fail/all.T b/testsuite/tests/indexed-types/should_fail/all.T index e154a31dd0..1ad9aa2504 100644 --- a/testsuite/tests/indexed-types/should_fail/all.T +++ b/testsuite/tests/indexed-types/should_fail/all.T @@ -153,3 +153,9 @@ test('T15870', normal, compile_fail, ['']) test('T14887', normal, compile_fail, ['']) test('T14230', normal, compile_fail, ['']) test('T14230a', normal, compile_fail, ['']) +test('T16110_Fail1', normal, compile_fail, ['']) +test('T16110_Fail2', normal, compile_fail, ['']) +test('T16110_Fail3', normal, compile_fail, ['']) +test('T16356_Fail1', normal, compile_fail, ['']) +test('T16356_Fail2', normal, compile_fail, ['']) +test('T16356_Fail3', normal, compile_fail, ['']) diff --git a/testsuite/tests/typecheck/should_fail/AssocTyDef02.stderr b/testsuite/tests/typecheck/should_fail/AssocTyDef02.stderr index b310a79a6f..e76e8a89e2 100644 --- a/testsuite/tests/typecheck/should_fail/AssocTyDef02.stderr +++ b/testsuite/tests/typecheck/should_fail/AssocTyDef02.stderr @@ -1,6 +1,7 @@ -AssocTyDef02.hs:6:14: - Unexpected type ‘[b]’ - In the default declaration for ‘Typ’ - A default declaration should have form - default Typ a = ... +AssocTyDef02.hs:6:5: error: + • Illegal argument ‘[b]’ in: + ‘type Typ [b] = Int’ + The arguments to ‘Typ’ must all be distinct type variables + • In the default type instance declaration for ‘Typ’ + In the class declaration for ‘Cls’ |