diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2019-08-30 13:43:24 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2019-09-20 10:50:21 +0100 |
commit | 0dad81ca5fd1f63bf8a3b6ad09787559e8bd05c0 (patch) | |
tree | 8759889c9a5bfe5f59dda0f809c2bfc1b8fab3f1 /testsuite | |
parent | 1755424806839d57a0c5672922a4b65b838f7d17 (diff) | |
download | haskell-0dad81ca5fd1f63bf8a3b6ad09787559e8bd05c0.tar.gz |
Fix bogus type of case expressionwip/T17056
Issue #17056 revealed that we were sometimes building a case
expression whose type field (in the Case constructor) was bogus.
Consider a phantom type synonym
type S a = Int
and we want to form the case expression
case x of K (a::*) -> (e :: S a)
We must not make the type field of the Case constructor be (S a)
because 'a' isn't in scope. We must instead expand the synonym.
Changes in this patch:
* Expand synonyms in the new function CoreUtils.mkSingleAltCase.
* Use mkSingleAltCase in MkCore.wrapFloat, which was the proximate
source of the bug (when called by exprIsConApp_maybe)
* Use mkSingleAltCase elsewhere
* Documentation
CoreSyn new invariant (6) in Note [Case expression invariants]
CoreSyn Note [Why does Case have a 'Type' field?]
CoreUtils Note [Care with the type of a case expression]
* I improved Core Lint's error reporting, which was pretty
confusing in this case, because it didn't mention that the offending
type was the return type of a case expression.
* A little bit of cosmetic refactoring in CoreUtils
Diffstat (limited to 'testsuite')
-rw-r--r-- | testsuite/tests/dependent/should_compile/all.T | 2 | ||||
-rw-r--r-- | testsuite/tests/indexed-types/should_compile/T17056.hs | 47 | ||||
-rw-r--r-- | testsuite/tests/indexed-types/should_compile/all.T | 1 |
3 files changed, 49 insertions, 1 deletions
diff --git a/testsuite/tests/dependent/should_compile/all.T b/testsuite/tests/dependent/should_compile/all.T index bbc32c8115..823244ebca 100644 --- a/testsuite/tests/dependent/should_compile/all.T +++ b/testsuite/tests/dependent/should_compile/all.T @@ -40,7 +40,7 @@ test('T12742', normal, compile, ['']) # (1) Use -fexternal-interpreter, or # (2) Build the program twice: once with -dynamic, and then # with -prof using -osuf to set a different object file suffix. -test('T13910', [expect_broken_for(16537, ['optasm']), omit_ways(['profasm'])], compile, ['']) +test('T13910', [omit_ways(['profasm'])], compile, ['']) test('T13938', [req_th, extra_files(['T13938a.hs'])], makefile_test, ['T13938']) test('T14556', normal, compile, ['']) test('T14720', normal, compile, ['']) diff --git a/testsuite/tests/indexed-types/should_compile/T17056.hs b/testsuite/tests/indexed-types/should_compile/T17056.hs new file mode 100644 index 0000000000..d22d1dfcdc --- /dev/null +++ b/testsuite/tests/indexed-types/should_compile/T17056.hs @@ -0,0 +1,47 @@ +-- This test tripped Core Lint by producing a +-- case expression whose 'type' field included an +-- out of scope variable because of a phantom type +-- synonym + +{-# OPTIONS_GHC -O #-} + +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +module Bug where + +import Data.Kind (Type) +import Data.Type.Equality ((:~:)(..)) + +type IsInt a = Int :~: a + +data Sing :: forall (b :: Type). IsInt b -> Type where + SRefl :: Sing Refl + +data SomeSing :: Type -> Type where + SomeSing :: Sing (x :: IsInt b) -> SomeSing b + +type WhyCastWith (e :: IsInt b) = b +-- Type /synonym/ +-- WhyCastWith b (e :: IsInt b) = b + +type family Apply (e :: IsInt b) :: Type +type instance Apply (e :: IsInt b) = WhyCastWith e + +-- axiom Apply (b :: *) (e :: IsInt b) ~ WhyCastWith e + +(~>:~:) :: forall (b :: Type) (r :: IsInt b). + Sing r + -> Apply r +(~>:~:) SRefl = let w = w in w + +castWith :: forall b. IsInt b -> b +castWith eq + = case (case eq of Refl -> SomeSing SRefl) :: SomeSing b of + SomeSing SRefl -> (~>:~:) @b SRefl diff --git a/testsuite/tests/indexed-types/should_compile/all.T b/testsuite/tests/indexed-types/should_compile/all.T index 7eeeda6d59..1ee797ca41 100644 --- a/testsuite/tests/indexed-types/should_compile/all.T +++ b/testsuite/tests/indexed-types/should_compile/all.T @@ -292,3 +292,4 @@ test('T16356_Compile2', normal, compile, ['']) test('T16632', normal, compile, ['-Wunused-type-patterns -fdiagnostics-show-caret']) test('T16828', normal, compile, ['']) test('T17008b', normal, compile, ['']) +test('T17056', normal, compile, ['']) |