diff options
author | sheaf <sam.derbyshire@gmail.com> | 2022-03-01 17:36:48 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2022-03-02 14:09:51 -0500 |
commit | f596c91aaede75f7293ac2214ad48018a6b7a753 (patch) | |
tree | 92c51240f4d7237d03868d27ddada78a0819cc14 /testsuite/tests/ghci | |
parent | 81b7c4361c0e3da403e0fcf42cc7faae2ca3db9a (diff) | |
download | haskell-f596c91aaede75f7293ac2214ad48018a6b7a753.tar.gz |
Improve out-of-order inferred type variables
Don't instantiate type variables for :type in
`GHC.Tc.Gen.App.tcInstFun`, to avoid inconsistently instantianting
`r1` but not `r2` in the type
forall {r1} (a :: TYPE r1) {r2} (b :: TYPE r2). ...
This fixes #21088.
This patch also changes the primop pretty-printer to ensure
that we put all the inferred type variables first. For example,
the type of reallyUnsafePtrEquality# is now
forall {l :: Levity} {k :: Levity}
(a :: TYPE (BoxedRep l))
(b :: TYPE (BoxedRep k)).
a -> b -> Int#
This means we avoid running into issue #21088 entirely with
the types of primops. Users can still write a type signature where
the inferred type variables don't come first, however.
This change to primops had a knock-on consequence, revealing that
we were sometimes performing eta reduction on keepAlive#.
This patch updates tryEtaReduce to avoid eta reducing functions
with no binding, bringing it in line with tryEtaReducePrep,
and thus fixing #21090.
Diffstat (limited to 'testsuite/tests/ghci')
-rw-r--r-- | testsuite/tests/ghci/scripts/T12550.stdout | 3 | ||||
-rw-r--r-- | testsuite/tests/ghci/scripts/T21088.hs | 29 | ||||
-rw-r--r-- | testsuite/tests/ghci/scripts/T21088.script | 11 | ||||
-rw-r--r-- | testsuite/tests/ghci/scripts/T21088.stdout | 19 | ||||
-rwxr-xr-x | testsuite/tests/ghci/scripts/all.T | 1 |
5 files changed, 62 insertions, 1 deletions
diff --git a/testsuite/tests/ghci/scripts/T12550.stdout b/testsuite/tests/ghci/scripts/T12550.stdout index 48a1b8e11c..d753d4f666 100644 --- a/testsuite/tests/ghci/scripts/T12550.stdout +++ b/testsuite/tests/ghci/scripts/T12550.stdout @@ -62,7 +62,8 @@ instance Functor (URec Int) -- Defined in ‘GHC.Generics’ instance Functor (URec Word) -- Defined in ‘GHC.Generics’ instance Functor V1 -- Defined in ‘GHC.Generics’ datatypeName - ∷ ∀ d k1 (t ∷ ★ → (k1 → ★) → k1 → ★) (f ∷ k1 → ★) (a ∷ k1). + ∷ ∀ {k} (d ∷ k) k1 (t ∷ k → (k1 → ★) → k1 → ★) (f ∷ k1 → ★) + (a ∷ k1). Datatype d ⇒ t d f a → [Char] type Datatype :: ∀ {k}. k → Constraint diff --git a/testsuite/tests/ghci/scripts/T21088.hs b/testsuite/tests/ghci/scripts/T21088.hs new file mode 100644 index 0000000000..efe4e8ab93 --- /dev/null +++ b/testsuite/tests/ghci/scripts/T21088.hs @@ -0,0 +1,29 @@ +{-# LANGUAGE PolyKinds, DataKinds, ScopedTypeVariables #-} + +module T21088 where + +import Data.Proxy + ( Proxy(..) ) +import GHC.Exts + ( TYPE, RuntimeRep ) + +-- We don't change the order of quantification, +-- so we check we are not instantiating `r1` but not `r2`, +-- which would be quite confusing. +foo :: forall {r1 :: RuntimeRep} (a1 :: TYPE r1) + {r2 :: RuntimeRep} (a2 :: TYPE r2) + . Proxy a1 -> Proxy a2 +foo _ = Proxy + +bar :: forall {r1 :: RuntimeRep} {r2 :: RuntimeRep} + (a1 :: TYPE r1) (a2 :: TYPE r2) + . Proxy a1 -> Proxy a2 +bar _ = Proxy + +baz :: forall {k1} (a1 :: k1) {k2} (a2 :: k2) + . Proxy a1 -> Proxy a2 +baz _ = Proxy + +quux :: forall {k1} {k2} (a1 :: k1) (a2 :: k2) + . Proxy a1 -> Proxy a2 +quux _ = Proxy diff --git a/testsuite/tests/ghci/scripts/T21088.script b/testsuite/tests/ghci/scripts/T21088.script new file mode 100644 index 0000000000..fe809b1970 --- /dev/null +++ b/testsuite/tests/ghci/scripts/T21088.script @@ -0,0 +1,11 @@ +:l T21088 +:type foo +:type bar +:type baz +:type quux + +:set -fprint-explicit-kinds -fprint-explicit-runtime-reps -fprint-explicit-foralls +:type foo +:type bar +:type baz +:type quux diff --git a/testsuite/tests/ghci/scripts/T21088.stdout b/testsuite/tests/ghci/scripts/T21088.stdout new file mode 100644 index 0000000000..ca3c4ddcc7 --- /dev/null +++ b/testsuite/tests/ghci/scripts/T21088.stdout @@ -0,0 +1,19 @@ +foo :: Proxy a1 -> Proxy a2 +bar :: Proxy a1 -> Proxy a2 +baz :: forall {k1} (a1 :: k1) {k2} (a2 :: k2). Proxy a1 -> Proxy a2 +quux + :: forall {k1} {k2} (a1 :: k1) (a2 :: k2). Proxy a1 -> Proxy a2 +foo + :: forall {r1 :: RuntimeRep} (a1 :: TYPE r1) {r2 :: RuntimeRep} + (a2 :: TYPE r2). + Proxy @{TYPE r1} a1 -> Proxy @{TYPE r2} a2 +bar + :: forall {r1 :: RuntimeRep} {r2 :: RuntimeRep} (a1 :: TYPE r1) + (a2 :: TYPE r2). + Proxy @{TYPE r1} a1 -> Proxy @{TYPE r2} a2 +baz + :: forall {k1} (a1 :: k1) {k2} (a2 :: k2). + Proxy @{k1} a1 -> Proxy @{k2} a2 +quux + :: forall {k1} {k2} (a1 :: k1) (a2 :: k2). + Proxy @{k1} a1 -> Proxy @{k2} a2 diff --git a/testsuite/tests/ghci/scripts/all.T b/testsuite/tests/ghci/scripts/all.T index bccfa977e5..0f6ed54ddb 100755 --- a/testsuite/tests/ghci/scripts/all.T +++ b/testsuite/tests/ghci/scripts/all.T @@ -363,3 +363,4 @@ test('T20587', [extra_files(['../shell.hs'])], ghci_script, test('T20909', normal, ghci_script, ['T20909.script']) test('T20150', normal, ghci_script, ['T20150.script']) test('T20974', normal, ghci_script, ['T20974.script']) +test('T21088', normal, ghci_script, ['T21088.script']) |