diff options
author | Sylvain Henry <sylvain@haskus.fr> | 2021-02-11 14:11:29 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-02-13 21:33:56 -0500 |
commit | 5e71dd3379ec4738c3f88271803d0de9b77e004f (patch) | |
tree | af9264330075bf1bc139b3d23153dcd822b0673d /libraries | |
parent | 3331b3ad0db55193832617f3af3b18182dc1d4af (diff) | |
download | haskell-5e71dd3379ec4738c3f88271803d0de9b77e004f.tar.gz |
Bignum: fix bogus rewrite rule (#19345)
Fix the following rule:
"fromIntegral/Int->Natural" fromIntegral = naturalFromWord . fromIntegral
Its type wasn't constrained to Int hence #19345.
Diffstat (limited to 'libraries')
-rw-r--r-- | libraries/base/GHC/Real.hs | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/libraries/base/GHC/Real.hs b/libraries/base/GHC/Real.hs index ee61e34e70..4329bb7355 100644 --- a/libraries/base/GHC/Real.hs +++ b/libraries/base/GHC/Real.hs @@ -580,14 +580,25 @@ fromIntegral = fromInteger . toInteger #-} {-# RULES -"fromIntegral/Natural->Natural" fromIntegral = id :: Natural -> Natural -"fromIntegral/Natural->Integer" fromIntegral = toInteger :: Natural->Integer -"fromIntegral/Natural->Word" fromIntegral = naturalToWord +"fromIntegral/Natural->Natural" fromIntegral = id :: Natural -> Natural +"fromIntegral/Natural->Integer" fromIntegral = toInteger :: Natural -> Integer +"fromIntegral/Natural->Word" fromIntegral = naturalToWord :: Natural -> Word #-} +-- Don't forget the type signatures in the following rules! Without a type +-- signature we end up with the rule: +-- +-- "fromIntegral/Int->Natural" forall a (d::Integral a). +-- fromIntegral @a @Natural = naturalFromWord . fromIntegral @a d +-- +-- but this rule is certainly not valid for every Integral type a! +-- +-- This rule wraps any Integral input into Word's range. As a consequence, +-- (2^64 :: Integer) was incorrectly wrapped to (0 :: Natural), see #19345. + {-# RULES -"fromIntegral/Word->Natural" fromIntegral = naturalFromWord -"fromIntegral/Int->Natural" fromIntegral = naturalFromWord . fromIntegral +"fromIntegral/Word->Natural" fromIntegral = naturalFromWord :: Word -> Natural +"fromIntegral/Int->Natural" fromIntegral = naturalFromWord . fromIntegral :: Int -> Natural #-} -- | general coercion to fractional types |