Sasha Bogicevic pushed to branch wip/27323 at Glasgow Haskell Compiler / GHC
Commits:
-
f14b27ba
by Sasha Bogicevic at 2026-09-03T11:28:23+02:00
7 changed files:
- + changelog.d/T27323
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/HsToCore/Types.hs
- compiler/GHC/HsToCore/Utils.hs
- + testsuite/tests/pmcheck/should_compile/T27323.hs
- testsuite/tests/pmcheck/should_compile/all.T
Changes:
| 1 | +section: compiler
|
|
| 2 | +synopsis: Don't report ``-XStrict``-generated bang patterns under ``-Wredundant-bang-patterns``
|
|
| 3 | +description:
|
|
| 4 | + Bangs introduced by ``-XStrict`` are no longer reported as redundant under
|
|
| 5 | + ``-Wredundant-bang-patterns``, as they are not user-written.
|
|
| 6 | +issues: #27323
|
|
| 7 | +mrs: !16395 |
| ... | ... | @@ -15,7 +15,7 @@ module GHC.HsToCore.Monad ( |
| 15 | 15 | duplicateLocalDs, newSysLocalDs, newSysLocalsDs,
|
| 16 | 16 | newSysLocalMDs, newSysLocalsMDs, newFailLocalMDs,
|
| 17 | 17 | newUniqueId, newPredVarDs, newStaticId,
|
| 18 | - getSrcSpanDs, putSrcSpanDs, putSrcSpanDsA,
|
|
| 18 | + getSrcSpanDs, inGeneratedCodeDs, putSrcSpanDs, putSrcSpanDsA,
|
|
| 19 | 19 | mkNamePprCtxDs,
|
| 20 | 20 | newUnique,
|
| 21 | 21 | UniqSupply, newUniqueSupply,
|
| ... | ... | @@ -584,6 +584,7 @@ mkDsEnvs unit_env mod rdr_env type_env fam_inst_env tcm_plugins ptc msg_var |
| 584 | 584 | , dsl_loc = real_span
|
| 585 | 585 | , dsl_nablas = Ldi initNablas
|
| 586 | 586 | , dsl_unspecables = Just emptyVarSet
|
| 587 | + , dsl_in_generated_code = False
|
|
| 587 | 588 | }
|
| 588 | 589 | in (gbl_env, lcl_env)
|
| 589 | 590 | |
| ... | ... | @@ -676,13 +677,17 @@ getSrcSpanDs :: DsM SrcSpan |
| 676 | 677 | getSrcSpanDs = do { env <- getLclEnv
|
| 677 | 678 | ; return (RealSrcSpan (dsl_loc env) Strict.Nothing) }
|
| 678 | 679 | |
| 680 | +-- | See 'dsl_in_generated_code'
|
|
| 681 | +inGeneratedCodeDs :: DsM Bool
|
|
| 682 | +inGeneratedCodeDs = dsl_in_generated_code <$> getLclEnv
|
|
| 683 | + |
|
| 679 | 684 | putSrcSpanDs :: SrcSpan -> DsM a -> DsM a
|
| 680 | 685 | putSrcSpanDs (RealSrcSpan real_span _) thing_inside
|
| 681 | - = updLclEnv (\ env -> env {dsl_loc = real_span}) thing_inside
|
|
| 686 | + = updLclEnv (\ env -> env {dsl_loc = real_span, dsl_in_generated_code = False}) thing_inside
|
|
| 682 | 687 | putSrcSpanDs UnhelpfulSpan{} thing_inside
|
| 683 | 688 | = thing_inside
|
| 684 | 689 | putSrcSpanDs GeneratedSrcSpan{} thing_inside
|
| 685 | - = thing_inside
|
|
| 690 | + = updLclEnv (\ env -> env {dsl_in_generated_code = True}) thing_inside
|
|
| 686 | 691 | |
| 687 | 692 | putSrcSpanDsA :: EpAnn ann -> DsM a -> DsM a
|
| 688 | 693 | putSrcSpanDsA loc = putSrcSpanDs (locA loc)
|
| ... | ... | @@ -155,11 +155,15 @@ desugarPat x pat = case pat of |
| 155 | 155 | VarPat _ y -> pure (mkPmLetVar (unLoc y) x)
|
| 156 | 156 | ParPat _ p -> desugarLPat x p
|
| 157 | 157 | LazyPat _ _ -> pure GdEnd -- like a wildcard
|
| 158 | - BangPat _ p@(L l p') ->
|
|
| 158 | + BangPat _ p@(L l p') -> do
|
|
| 159 | 159 | -- Add the bang in front of the list, because it will happen before any
|
| 160 | 160 | -- nested stuff.
|
| 161 | + in_gen <- inGeneratedCodeDs
|
|
| 162 | + -- A bang inserted by -XStrict (decideBangHood) has no SrcInfo: it is
|
|
| 163 | + -- divergence-checked but never reported as redundant (#27323).
|
|
| 164 | + let pm_loc | in_gen = Nothing
|
|
| 165 | + | otherwise = Just (SrcInfo (L (locA l) (ppr p')))
|
|
| 161 | 166 | consGrdDag (PmBang x pm_loc) <$> desugarLPat x p
|
| 162 | - where pm_loc = Just (SrcInfo (L (locA l) (ppr p')))
|
|
| 163 | 167 | |
| 164 | 168 | -- (x@pat) ==> Desugar pat with x as match var and handle impedance
|
| 165 | 169 | -- mismatch with incoming match var
|
| ... | ... | @@ -311,7 +315,7 @@ desugarPatV pat = do |
| 311 | 315 | pure (x, grds)
|
| 312 | 316 | |
| 313 | 317 | desugarLPat :: Id -> LPat GhcTc -> DsM GrdDag
|
| 314 | -desugarLPat x = desugarPat x . unLoc
|
|
| 318 | +desugarLPat x (L loc pat) = putSrcSpanDsA loc (desugarPat x pat)
|
|
| 315 | 319 | |
| 316 | 320 | -- | 'desugarLPat', but also select and return a new match var.
|
| 317 | 321 | desugarLPatV :: LPat GhcTc -> DsM (Id, GrdDag)
|
| ... | ... | @@ -650,4 +654,19 @@ user *had* written a bang: |
| 650 | 654 | + In an equation for ‘idV’: idV !v = ...
|
| 651 | 655 | |
| 652 | 656 | So we live with the duplication.
|
| 657 | + |
|
| 658 | +Note that 'decideBangHood' places the bangs it inserts at a 'generatedSrcSpan'.
|
|
| 659 | +When 'desugarLPat' enters such a span, 'putSrcSpanDs' (GHC.HsToCore.Monad)
|
|
| 660 | +records in 'dsl_in_generated_code' that we are desugaring compiler-generated
|
|
| 661 | +code. For a bang in generated code, 'desugarPat' emits a 'PmBang' with no
|
|
| 662 | +'SrcInfo': the checker still performs the divergence check (so the
|
|
| 663 | +inaccessible-RHS warning above survives), but -Wredundant-bang-patterns only
|
|
| 664 | +ever reports bangs the user actually wrote (#27323). See
|
|
| 665 | +Note [Dead bang patterns] in GHC.HsToCore.Pmc.Check.
|
|
| 666 | + |
|
| 667 | +Eventually the bangs inserted by -XStrict should become expanded patterns,
|
|
| 668 | +following Note [Handling overloaded and rebindable constructs] in
|
|
| 669 | +GHC.Rename.Expr. That would let warnings always display the original
|
|
| 670 | +user-written code, making the decideBangHood duplication described above
|
|
| 671 | +unnecessary. This is tracked as #27677.
|
|
| 653 | 672 | -} |
| ... | ... | @@ -11,7 +11,7 @@ module GHC.HsToCore.Types ( |
| 11 | 11 | DsMetaEnv, DsMetaVal(..), CompleteMatches
|
| 12 | 12 | ) where
|
| 13 | 13 | |
| 14 | -import GHC.Prelude (Int)
|
|
| 14 | +import GHC.Prelude (Bool, Int)
|
|
| 15 | 15 | |
| 16 | 16 | import Data.IORef
|
| 17 | 17 | |
| ... | ... | @@ -125,6 +125,7 @@ data DsLclEnv |
| 125 | 125 | -- ^ See Note [Desugaring non-canonical evidence]
|
| 126 | 126 | -- This field collects all un-specialisable evidence variables in scope.
|
| 127 | 127 | -- Nothing <=> don't collect this info (used for the LHS of Rules)
|
| 128 | + , dsl_in_generated_code :: Bool -- Desugaring compiler-generated or user-written code
|
|
| 128 | 129 | }
|
| 129 | 130 | |
| 130 | 131 | -- Inside [| |] brackets, the desugarer looks
|
| ... | ... | @@ -951,6 +951,9 @@ Specifically: |
| 951 | 951 | |
| 952 | 952 | |
| 953 | 953 | -- | Use -XStrict to add a ! or remove a ~
|
| 954 | +-- The bang we insert is compiler-generated, so we put it at a generatedSrcSpan.
|
|
| 955 | +-- The pattern-match checker uses this (via dsl_in_generated_code) to avoid reporting
|
|
| 956 | +-- such bangs under -Wredundant-bang-patterns (#27323).
|
|
| 954 | 957 | -- See Note [decideBangHood]
|
| 955 | 958 | decideBangHood :: DynFlags
|
| 956 | 959 | -> LPat GhcTc -- ^ Original pattern
|
| ... | ... | @@ -966,7 +969,7 @@ decideBangHood dflags lpat |
| 966 | 969 | ParPat x p -> L l (ParPat x (go p))
|
| 967 | 970 | LazyPat _ lp' -> lp'
|
| 968 | 971 | BangPat _ _ -> lp
|
| 969 | - _ -> L l (BangPat noExtField lp)
|
|
| 972 | + _ -> L (noAnnSrcSpan generatedSrcSpan) (BangPat noExtField lp)
|
|
| 970 | 973 | |
| 971 | 974 | isTrueLHsExpr :: LHsExpr GhcTc -> Maybe (CoreExpr -> DsM CoreExpr)
|
| 972 | 975 |
| 1 | +{-# LANGUAGE MagicHash, Strict #-}
|
|
| 2 | +{-# OPTIONS_GHC -Wredundant-bang-patterns #-}
|
|
| 3 | + |
|
| 4 | +import GHC.Prim (Int#)
|
|
| 5 | + |
|
| 6 | +idInt# :: Int# -> Int#
|
|
| 7 | +idInt# x = x
|
|
| 8 | + |
|
| 9 | +main = pure () |
| ... | ... | @@ -190,4 +190,5 @@ test('T24845', [], compile, [overlapping_incomplete]) |
| 190 | 190 | test('T22652', [], compile, [overlapping_incomplete])
|
| 191 | 191 | test('T22652a', [], compile, [overlapping_incomplete])
|
| 192 | 192 | test('T24867', [], compile_fail, [overlapping_incomplete])
|
| 193 | +test('T27323', normal, compile, ['-Wredundant-bang-patterns'])
|
|
| 193 | 194 | test('T27360', normal, compile, [overlapping_incomplete + '-g3']) |