diff options
Diffstat (limited to 'compiler/GHC/Prelude.hs')
-rw-r--r-- | compiler/GHC/Prelude.hs | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/compiler/GHC/Prelude.hs b/compiler/GHC/Prelude.hs index 95c2d4b190..d538adfefb 100644 --- a/compiler/GHC/Prelude.hs +++ b/compiler/GHC/Prelude.hs @@ -10,15 +10,17 @@ -- * Is compiled with -XNoImplicitPrelude -- * Explicitly imports GHC.Prelude -module GHC.Prelude (module X) where +module GHC.Prelude + (module X + ,module Bits + ,shiftL, shiftR + ) where + -- We export the 'Semigroup' class but w/o the (<>) operator to avoid -- clashing with the (Outputable.<>) operator which is heavily used -- through GHC's code-base. -import Prelude as X hiding ((<>)) -import Data.Foldable as X (foldl') - {- Note [Why do we import Prelude here?] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -31,3 +33,56 @@ NoImplicitPrelude. There are two motivations for this: giving a smoother development experience when adding new extensions. -} + +import Prelude as X hiding ((<>)) +import Data.Foldable as X (foldl') + +#if MIN_VERSION_base(4,15,0) +import GHC.Bits as Bits hiding (shiftL, shiftR) +# if defined(DEBUG) +import qualified GHC.Bits as Bits (shiftL, shiftR) +# endif + +#else +--base <4.15 +import Data.Bits as Bits hiding (shiftL, shiftR) +# if defined(DEBUG) +import qualified Data.Bits as Bits (shiftL, shiftR) +# endif +#endif + +{- Note [Default to unsafe shifts inside GHC] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The safe shifts can introduce branches which come +at the cost of performance. We still want the additional +debugability for debug builds. So we define it as one or the +other depending on the DEBUG setting. + +Why do we then continue on to re-export the rest of Data.Bits? +If we would not what is likely to happen is: +* Someone imports Data.Bits, uses xor. Things are fine. +* They add a shift and get an ambigious definition error. +* The are puzzled for a bit. +* They either: + + Remove the import of Data.Bits and get an error because xor is not in scope. + + Add the hiding clause to the Data.Bits import for the shifts. + +Either is quite annoying. Simply re-exporting all of Data.Bits avoids this +making for a smoother developer experience. At the cost of having a few more +names in scope at all time. But that seems like a fair tradeoff. + +See also #19618 +-} + +-- We always want the Data.Bits method to show up for rules etc. +{-# INLINE shiftL #-} +{-# INLINE shiftR #-} +shiftL, shiftR :: Bits.Bits a => a -> Int -> a +#if defined(DEBUG) +shiftL = Bits.shiftL +shiftR = Bits.shiftR +#else +shiftL = Bits.unsafeShiftL +shiftR = Bits.unsafeShiftR +#endif + |