diff options
author | Ryan Scott <ryan.gl.scott@gmail.com> | 2021-01-31 09:04:39 -0500 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-02-01 03:12:07 -0500 |
commit | d4bcd37f15a59cea22fbaef280cd85cac20872bf (patch) | |
tree | 2de35715e477e1658bb2f0722602824d99526856 /libraries/base/tests | |
parent | 14c4f7014d1bbdf51a79745821fcfc39e7db0ec9 (diff) | |
download | haskell-d4bcd37f15a59cea22fbaef280cd85cac20872bf.tar.gz |
Fix accidental unsoundness in Data.Typeable.Internal.mkTypeLitFromString
An accidental use of `tcSymbol` instead of `tcNat` in the `TypeLitNat` case of
`mkTypeLitFromString` meant that it was possible to unsafely equate `Nat` with
`Symbol`. A consequence of this is that you could write `unsafeCoerce`, as
observed in #19288. This is fixed easily enough, thankfully.
Fixes #19288.
Diffstat (limited to 'libraries/base/tests')
-rw-r--r-- | libraries/base/tests/T19288.hs | 31 | ||||
-rw-r--r-- | libraries/base/tests/T19288.stderr | 3 | ||||
-rw-r--r-- | libraries/base/tests/all.T | 1 |
3 files changed, 35 insertions, 0 deletions
diff --git a/libraries/base/tests/T19288.hs b/libraries/base/tests/T19288.hs new file mode 100644 index 0000000000..7bb5fd2616 --- /dev/null +++ b/libraries/base/tests/T19288.hs @@ -0,0 +1,31 @@ +{-# LANGUAGE DataKinds, PolyKinds, TypeOperators, Safe, TypeFamilies #-} + +module Main where + +import Data.Maybe +import Data.Proxy +import Type.Reflection +import GHC.TypeLits + +data Dat (x :: Proxy 1) = MkD1 + +evil :: Maybe (Nat :~~: Symbol) +evil = eqTypeRep (case (typeRepKind (typeRep :: TypeRep Dat)) of + (Fun (App _ x) _) -> typeRepKind x) + (typeRep :: TypeRep Symbol) + + +data family Cast k l r +newtype instance Cast Nat l r = CastNat { runCastNat :: l } +newtype instance Cast Symbol l r = CastSymbol { runCastSymbol :: r } + +{-# NOINLINE castHelper #-} +castHelper :: Maybe (a :~~: b) -> Cast a l r -> Cast b l r +castHelper (Just HRefl) = id +castHelper Nothing = error "No more bug!" + +cast :: a -> b +cast = runCastSymbol . castHelper evil . CastNat + +main :: IO () +main = print (cast 'a' :: Int) diff --git a/libraries/base/tests/T19288.stderr b/libraries/base/tests/T19288.stderr new file mode 100644 index 0000000000..68f83bff83 --- /dev/null +++ b/libraries/base/tests/T19288.stderr @@ -0,0 +1,3 @@ +T19288: No more bug! +CallStack (from HasCallStack): + error, called at T19288.hs:25:27 in main:Main diff --git a/libraries/base/tests/all.T b/libraries/base/tests/all.T index ac65224ef0..da828cb2c2 100644 --- a/libraries/base/tests/all.T +++ b/libraries/base/tests/all.T @@ -261,3 +261,4 @@ test('T17499', [collect_stats('bytes allocated',5)], compile_and_run, ['-O -w']) test('T16643', normal, compile_and_run, ['']) test('clamp', normal, compile_and_run, ['']) test('T18642', extra_run_opts('+RTS -T -RTS'), compile_and_run, ['-O2']) +test('T19288', exit_code(1), compile_and_run, ['']) |