Sasha Bogicevic pushed to branch wip/27323 at Glasgow Haskell Compiler / GHC

Commits:

20 changed files:

Changes:

  • .gitlab-ci.yml
    ... ... @@ -137,15 +137,37 @@ workflow:
    137 137
     .lint:
    
    138 138
       stage: tool-lint
    
    139 139
       tags:
    
    140
    -    - lint
    
    141
    -  before_script:
    
    142
    -    # Allow Git to read from the runner-owned checkout. This is needed
    
    143
    -    # for example by the lint-author job.
    
    144
    -    - git config --global --add safe.directory "$CI_PROJECT_DIR"
    
    140
    +    - lint-anyarch
    
    141
    +  image: debian:13
    
    145 142
       rules:
    
    146 143
         - *drafts-can-fail-lint
    
    147 144
         - when: always
    
    148 145
     
    
    146
    +.install-ghc-toolchain: &install-ghc-toolchain
    
    147
    +  - apt update
    
    148
    +  - apt install -qy build-essential curl libffi-dev libffi8 libgmp-dev libgmp10 libncurses-dev libncurses6 libtinfo6 pkg-config python3 cmake git happy alex autoconf automake python3 libgmp-dev libnuma-dev libncurses-dev
    
    149
    +  - curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_MINIMAL=1 sh
    
    150
    +  - source /root/.ghcup/env
    
    151
    +  - ghcup --no-verbose install ghc --set --install-targets 'install_bin install_lib update_package_db' '9.10'
    
    152
    +  - ghcup --no-verbose install cabal --set
    
    153
    +  - ghc --info
    
    154
    +  - cabal --version
    
    155
    +
    
    156
    +# linting but we need a boot toolchain
    
    157
    +.lint-ghc-toolchain:
    
    158
    +  extends: .lint
    
    159
    +  before_script:
    
    160
    +    - *install-ghc-toolchain
    
    161
    +    - git config --global --add safe.directory "$CI_PROJECT_DIR"
    
    162
    +
    
    163
    +# linting but we need python
    
    164
    +.lint-python:
    
    165
    +  extends: .lint
    
    166
    +  before_script:
    
    167
    +    - apt update
    
    168
    +    - apt install -qy python3 mypy shellcheck git
    
    169
    +    - git config --global --add safe.directory "$CI_PROJECT_DIR"
    
    170
    +
    
    149 171
     .nightly: &nightly
    
    150 172
       variables:
    
    151 173
         XZ_OPT: "-9"
    
    ... ... @@ -217,11 +239,11 @@ not-interruptible:
    217 239
       stage: not-interruptible
    
    218 240
       script: "true"
    
    219 241
       interruptible: false
    
    220
    -  image: "debian:13"
    
    242
    +  image: debian:13
    
    221 243
       variables:
    
    222 244
         GIT_STRATEGY: none
    
    223 245
       tags:
    
    224
    -    - lint
    
    246
    +    - lint-anyarch
    
    225 247
       rules:
    
    226 248
     #   - if: '$CI_COMMIT_BRANCH == "master"'
    
    227 249
     #      when: always
    
    ... ... @@ -242,7 +264,6 @@ include: '.gitlab/jobs.yaml'
    242 264
     
    
    243 265
     ghc-linters:
    
    244 266
       stage: tool-lint
    
    245
    -  image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13:$DOCKER_REV"
    
    246 267
       extends: .lint-params
    
    247 268
       variables:
    
    248 269
         BUILD_FLAVOUR: default
    
    ... ... @@ -258,16 +279,11 @@ ghc-linters:
    258 279
     # Skipped if the MR has the ~"no-changelog" label.
    
    259 280
     lint-changelog:
    
    260 281
       stage: tool-lint
    
    261
    -  image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13:$DOCKER_REV"
    
    262
    -  extends: .lint
    
    282
    +  extends: .lint-ghc-toolchain
    
    263 283
       variables:
    
    264 284
         CHANGELOG_EXPECT_MR: "$CI_MERGE_REQUEST_IID"
    
    265 285
         GIT_DEPTH: 1
    
    266 286
         GIT_SUBMODULE_STRATEGY: none
    
    267
    -  before_script:
    
    268
    -    - export PATH="/opt/toolchain/bin:$PATH"
    
    269
    -    # workaround for docker permissions
    
    270
    -    - sudo chown ghc:ghc -R .
    
    271 287
       script:
    
    272 288
         - .gitlab/ci.sh lint_changelog
    
    273 289
       dependencies: []
    
    ... ... @@ -279,42 +295,30 @@ lint-changelog:
    279 295
     
    
    280 296
     # Run mypy Python typechecker on linter scripts.
    
    281 297
     lint-linters:
    
    282
    -  image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV"
    
    283
    -  extends: .lint
    
    298
    +  extends: .lint-python
    
    284 299
       variables:
    
    285 300
         GIT_DEPTH: 1
    
    286 301
         GIT_SUBMODULE_STRATEGY: none
    
    287
    -  before_script:
    
    288
    -    # workaround for docker permissions
    
    289
    -    - sudo chown ghc:ghc -R .
    
    290 302
       script:
    
    291 303
         - mypy testsuite/tests/linters/regex-linters/*.py
    
    292 304
       dependencies: []
    
    293 305
     
    
    294 306
     # Check that .T files all parse by listing broken tests.
    
    295 307
     lint-testsuite:
    
    296
    -  image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13:$DOCKER_REV"
    
    297
    -  extends: .lint
    
    308
    +  extends: .lint-ghc-toolchain
    
    298 309
       variables:
    
    299 310
         GIT_DEPTH: 1
    
    300 311
         GIT_SUBMODULE_STRATEGY: none
    
    301
    -  before_script:
    
    302
    -    # workaround for docker permissions
    
    303
    -    - sudo chown ghc:ghc -R .
    
    304 312
       script:
    
    305
    -    - make -Ctestsuite list_broken TEST_HC=$GHC
    
    313
    +    - make -Ctestsuite list_broken TEST_HC=$(which ghc)
    
    306 314
       dependencies: []
    
    307 315
     
    
    308 316
     # Run mypy Python typechecker on testsuite driver
    
    309 317
     typecheck-testsuite:
    
    310
    -  image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV"
    
    311
    -  extends: .lint
    
    318
    +  extends: .lint-python
    
    312 319
       variables:
    
    313 320
         GIT_DEPTH: 1
    
    314 321
         GIT_SUBMODULE_STRATEGY: none
    
    315
    -  before_script:
    
    316
    -    # workaround for docker permissions
    
    317
    -    - sudo chown ghc:ghc -R .
    
    318 322
       script:
    
    319 323
         - mypy testsuite/driver/runtests.py
    
    320 324
       dependencies: []
    
    ... ... @@ -323,7 +327,6 @@ typecheck-testsuite:
    323 327
     # accommodate, e.g., haddock changes not yet upstream) but not on `master` or
    
    324 328
     # Marge jobs.
    
    325 329
     .lint-submods:
    
    326
    -  image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13:$DOCKER_REV"
    
    327 330
       extends: .lint-params
    
    328 331
       variables:
    
    329 332
         BUILD_FLAVOUR: default
    
    ... ... @@ -341,13 +344,9 @@ typecheck-testsuite:
    341 344
     # Check that commits in an MR were not authored with the identity that CI uses
    
    342 345
     # when it needs to create commits itself. This only needs Git history.
    
    343 346
     lint-author:
    
    344
    -  image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13:$DOCKER_REV"
    
    345
    -  extends: .lint
    
    347
    +  extends: .lint-python
    
    346 348
       variables:
    
    347 349
         GIT_SUBMODULE_STRATEGY: none
    
    348
    -  before_script:
    
    349
    -    # workaround for docker permissions
    
    350
    -    - sudo chown ghc:ghc -R .
    
    351 350
       script:
    
    352 351
         - git fetch "$CI_MERGE_REQUEST_PROJECT_URL" $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
    
    353 352
         - base="$(git merge-base FETCH_HEAD $CI_COMMIT_SHA)"
    
    ... ... @@ -425,12 +424,9 @@ lint-submods-branch:
    425 424
     
    
    426 425
     .lint-params:
    
    427 426
       needs: []
    
    428
    -  image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13:$DOCKER_REV"
    
    429 427
       extends: .lint
    
    430 428
       before_script:
    
    431
    -    - export PATH="/opt/toolchain/bin:$PATH"
    
    432
    -    # workaround for docker permissions
    
    433
    -    - sudo chown ghc:ghc -R .
    
    429
    +    - *install-ghc-toolchain
    
    434 430
         - .gitlab/ci.sh setup
    
    435 431
       after_script:
    
    436 432
         - .gitlab/ci.sh save_cache
    
    ... ... @@ -448,18 +444,13 @@ lint-submods-branch:
    448 444
     
    
    449 445
     hadrian-ghc-in-ghci:
    
    450 446
       stage: quick-build
    
    447
    +  extends: .lint-ghc-toolchain
    
    451 448
       needs:
    
    452 449
         - job: lint-linters
    
    453 450
         - job: lint-submods
    
    454 451
           optional: true
    
    455
    -  image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb13:$DOCKER_REV"
    
    456
    -  before_script:
    
    457
    -    # workaround for docker permissions
    
    458
    -    - sudo chown ghc:ghc -R .
    
    459 452
       variables:
    
    460 453
         GHC_FLAGS: -Werror -Wwarn=unused-imports
    
    461
    -  tags:
    
    462
    -    - x86_64-linux
    
    463 454
       script:
    
    464 455
         - git clean -xdf && git submodule foreach git clean -xdf
    
    465 456
         - . .gitlab/ci.sh setup
    
    ... ... @@ -544,6 +535,7 @@ stack-hadrian-build:
    544 535
       extends: hadrian-ghc-in-ghci
    
    545 536
       stage: quick-build
    
    546 537
       script:
    
    538
    +    - ghcup --no-verbose install stack --set
    
    547 539
         - . .gitlab/ci.sh setup
    
    548 540
         - . .gitlab/ci.sh configure
    
    549 541
         - hadrian/build-stack --version
    

  • changelog.d/27845
    1
    +section: compiler
    
    2
    +synopsis: Fix a bug where an argument used lazily only by a function's stable
    
    3
    +  unfolding could be treated as strict in its fields.
    
    4
    +mrs: !16746
    
    5
    +issues: #27845

  • changelog.d/T27323
    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

  • compiler/GHC/HsToCore/Match.hs
    ... ... @@ -383,12 +383,14 @@ tidyEqnInfo :: MatchId -> EquationInfo
    383 383
     
    
    384 384
     tidyEqnInfo _ eqn@(EqnDone {}) = return (idDsWrapper, eqn)
    
    385 385
     
    
    386
    -tidyEqnInfo v eqn@(EqnMatch { eqn_pat = (L loc pat) }) = do
    
    387
    -  (wrap, pat') <- tidy1 v (not . isGoodSrcSpan . locA $ loc) pat
    
    386
    +tidyEqnInfo v eqn@(EqnMatch { eqn_pat = p@(L loc _) }) = do
    
    387
    +  (wrap, pat') <- tidyLPat v p
    
    388 388
       return (wrap, eqn{eqn_pat = L loc pat' })
    
    389 389
     
    
    390
    +tidyLPat :: MatchId -> LPat GhcTc -> DsM (DsWrapper, Pat GhcTc)
    
    391
    +tidyLPat v (L loc pat) = putSrcSpanDsA loc (tidy1 v pat)
    
    392
    +
    
    390 393
     tidy1 :: MatchId             -- The scrutinee
    
    391
    -      -> Bool                -- `True` if the pattern was generated, `False` if it was user-written
    
    392 394
           -> Pat GhcTc           -- The pattern against which it is to be matched
    
    393 395
           -> DsM (DsWrapper,     -- Extra bindings to do before the match
    
    394 396
                   Pat GhcTc)     -- Equivalent pattern
    
    ... ... @@ -399,21 +401,22 @@ tidy1 :: MatchId -- The scrutinee
    399 401
     -- It eliminates many pattern forms (as-patterns, variable patterns,
    
    400 402
     -- list patterns, etc) and returns any created bindings in the wrapper.
    
    401 403
     
    
    402
    -tidy1 v g (ParPat _ pat)      = tidy1 v g (unLoc pat)
    
    403
    -tidy1 v g (SigPat _ pat _)    = tidy1 v g (unLoc pat)
    
    404
    -tidy1 _ _ (WildPat ty)        = return (idDsWrapper, WildPat ty)
    
    405
    -tidy1 v g (BangPat _ (L l p)) = tidy_bang_pat v g l p
    
    406
    -tidy1 v g (ModifiedPat _ _ pat) = tidy1 v g (unLoc pat)
    
    404
    +tidy1 v (ParPat _ pat)        = tidyLPat v pat
    
    405
    +tidy1 v (SigPat _ pat _)      = tidyLPat v pat
    
    406
    +tidy1 _ (WildPat ty)          = return (idDsWrapper, WildPat ty)
    
    407
    +tidy1 v (BangPat _ (L l p))   = putSrcSpanDsA l $ tidy_bang_pat v l p
    
    408
    +tidy1 v (ModifiedPat _ _ pat) = tidyLPat v pat
    
    407 409
     
    
    408 410
             -- case v of { x -> mr[] }
    
    409 411
             -- = case v of { _ -> let x=v in mr[] }
    
    410
    -tidy1 v _ (VarPat _ (L _ var))
    
    412
    +tidy1 v (VarPat _ (L _ var))
    
    411 413
       = return (bindMatchId var v, WildPat (idType var))
    
    412 414
     
    
    413 415
             -- case v of { x@p -> mr[] }
    
    414 416
             -- = case v of { p -> let x=v in mr[] }
    
    415
    -tidy1 v g (AsPat _ (L _ var) pat)
    
    416
    -  = do  { (wrap, pat') <- tidy1 v g (unLoc pat)
    
    417
    +tidy1 v (AsPat _ (L _ var) pat)
    
    418
    +
    
    419
    +  = do  { (wrap, pat') <- tidyLPat v pat
    
    417 420
             ; return (bindMatchId var v . wrap, pat') }
    
    418 421
     
    
    419 422
     {- now, here we handle lazy patterns:
    
    ... ... @@ -427,7 +430,7 @@ tidy1 v g (AsPat _ (L _ var) pat)
    427 430
         The case expr for v_i is just: match [v] [(p, [], \ x -> Var v_i)] any_expr
    
    428 431
     -}
    
    429 432
     
    
    430
    -tidy1 v _ (LazyPat _ pat)
    
    433
    +tidy1 v (LazyPat _ pat)
    
    431 434
         -- This is a convenient place to check for unlifted types under a lazy pattern.
    
    432 435
         -- Doing this check during type-checking is unsatisfactory because we may
    
    433 436
         -- not fully know the zonked types yet. We sure do here.
    
    ... ... @@ -441,14 +444,14 @@ tidy1 v _ (LazyPat _ pat)
    441 444
             ; let sel_binds =  [NonRec b rhs | (b,rhs) <- sel_prs]
    
    442 445
             ; return (mkCoreLets sel_binds, WildPat (matchIdType v)) }
    
    443 446
     
    
    444
    -tidy1 _ _ (ListPat ty pats)
    
    447
    +tidy1 _ (ListPat ty pats)
    
    445 448
       = return (idDsWrapper, unLoc list_ConPat)
    
    446 449
       where
    
    447 450
         list_ConPat = foldr (\ x y -> mkPrefixConPat consDataCon [x, y] [ty])
    
    448 451
                             (mkNilPat ty)
    
    449 452
                             pats
    
    450 453
     
    
    451
    -tidy1 _ _ (TuplePat tys pats boxity)
    
    454
    +tidy1 _ (TuplePat tys pats boxity)
    
    452 455
       = return (idDsWrapper, unLoc tuple_ConPat)
    
    453 456
       where
    
    454 457
         arity = length pats
    
    ... ... @@ -458,34 +461,37 @@ tidy1 _ _ (TuplePat tys pats boxity)
    458 461
                  Boxed   -> tys
    
    459 462
                -- See Note [Unboxed tuple RuntimeRep vars] in TyCon
    
    460 463
     
    
    461
    -tidy1 _ _ (SumPat tys pat alt arity)
    
    464
    +tidy1 _ (SumPat tys pat alt arity)
    
    462 465
       = return (idDsWrapper, unLoc sum_ConPat)
    
    463 466
       where
    
    464 467
         sum_ConPat = mkPrefixConPat (sumDataCon alt arity) [pat] (map getRuntimeRep tys ++ tys)
    
    465 468
                      -- See Note [Unboxed tuple RuntimeRep vars] in TyCon
    
    466 469
     
    
    467 470
     -- LitPats: we *might* be able to replace these w/ a simpler form
    
    468
    -tidy1 _ g (LitPat _ lit)
    
    469
    -  = do { unless g $
    
    471
    +tidy1 _ (LitPat _ lit)
    
    472
    +  = do { in_gen <- inGeneratedCodeDs;
    
    473
    +         unless in_gen $
    
    470 474
                warnAboutOverflowedLit lit
    
    471 475
            ; return (idDsWrapper, tidyLitPat lit) }
    
    472 476
     
    
    473 477
     -- NPats: we *might* be able to replace these w/ a simpler form
    
    474
    -tidy1 _ g (NPat ty (L _ lit@OverLit { ol_val = v }) mb_neg eq)
    
    475
    -  = do { unless g $
    
    478
    +tidy1 _ (NPat ty (L _ lit@OverLit { ol_val = v }) mb_neg eq)
    
    479
    +  = do { in_gen <- inGeneratedCodeDs;
    
    480
    +         unless in_gen $
    
    476 481
                let lit' | Just _ <- mb_neg = lit{ ol_val = negateOverLitVal v }
    
    477 482
                         | otherwise = lit
    
    478 483
                in warnAboutOverflowedOverLit lit'
    
    479 484
            ; return (idDsWrapper, tidyNPat lit mb_neg eq ty) }
    
    480 485
     
    
    481 486
     -- NPlusKPat: we may want to warn about the literals
    
    482
    -tidy1 _ g n@(NPlusKPat _ _ (L _ lit1) lit2 _ _)
    
    483
    -  = do { unless g $ do
    
    487
    +tidy1 _ n@(NPlusKPat _ _ (L _ lit1) lit2 _ _)
    
    488
    +  = do { in_gen <- inGeneratedCodeDs;
    
    489
    +         unless in_gen $ do
    
    484 490
                warnAboutOverflowedOverLit lit1
    
    485 491
                warnAboutOverflowedOverLit lit2
    
    486 492
            ; return (idDsWrapper, n) }
    
    487 493
     
    
    488
    -tidy1 _ _ (OrPat ty lpats)
    
    494
    +tidy1 _ (OrPat ty lpats)
    
    489 495
       -- See Note [Implementation of OrPatterns]. We desugar
    
    490 496
       --   (1; 2; 3)
    
    491 497
       -- to
    
    ... ... @@ -514,44 +520,44 @@ tidy1 _ _ (OrPat ty lpats)
    514 520
         single_grhs e = GRHSs emptyComments [noLocA $ GRHS noAnn [] e] (EmptyLocalBinds noExtField)
    
    515 521
     
    
    516 522
     -- Everything else goes through unchanged...
    
    517
    -tidy1 _ _ non_interesting_pat
    
    523
    +tidy1 _ non_interesting_pat
    
    518 524
       = return (idDsWrapper, non_interesting_pat)
    
    519 525
     
    
    520 526
     --------------------
    
    521
    -tidy_bang_pat :: MatchId -> Bool -> SrcSpanAnnA -> Pat GhcTc
    
    527
    +tidy_bang_pat :: MatchId -> SrcSpanAnnA -> Pat GhcTc
    
    522 528
                   -> DsM (DsWrapper, Pat GhcTc)
    
    523 529
     
    
    524 530
     -- Discard par/sig under a bang
    
    525
    -tidy_bang_pat v g _ (ParPat _ (L l p))   = tidy_bang_pat v g l p
    
    526
    -tidy_bang_pat v g _ (SigPat _ (L l p) _) = tidy_bang_pat v g l p
    
    531
    +tidy_bang_pat v _ (ParPat _ (L l p))   = putSrcSpanDsA l $ tidy_bang_pat v l p
    
    532
    +tidy_bang_pat v _ (SigPat _ (L l p) _) = putSrcSpanDsA l $ tidy_bang_pat v l p
    
    527 533
     
    
    528 534
     -- Push the bang-pattern inwards, in the hope that
    
    529 535
     -- it may disappear next time
    
    530
    -tidy_bang_pat v g l (AsPat x v' p)
    
    531
    -  = tidy1 v g (AsPat x v' (L l (BangPat noExtField p)))
    
    532
    -tidy_bang_pat v g l (XPat (CoPat w p t))
    
    533
    -  = tidy1 v g (XPat $ CoPat w (BangPat noExtField (L l p)) t)
    
    534
    -tidy_bang_pat v g l (OrPat x (p:|ps)) -- push bang into first pat alt
    
    535
    -  = tidy1 v g (OrPat x (L l (BangPat noExtField p) :| ps))
    
    536
    +tidy_bang_pat v l (AsPat x v' p)
    
    537
    +  = tidy1 v (AsPat x v' (L l (BangPat noExtField p)))
    
    538
    +tidy_bang_pat v l (XPat (CoPat w p t))
    
    539
    +  = tidy1 v (XPat $ CoPat w (BangPat noExtField (L l p)) t)
    
    540
    +tidy_bang_pat v l (OrPat x (p:|ps)) -- push bang into first pat alt
    
    541
    +  = tidy1 v (OrPat x (L l (BangPat noExtField p) :| ps))
    
    536 542
     
    
    537 543
     -- Discard bang around strict pattern
    
    538
    -tidy_bang_pat v g _ p@(LitPat {})    = tidy1 v g p
    
    539
    -tidy_bang_pat v g _ p@(ListPat {})   = tidy1 v g p
    
    540
    -tidy_bang_pat v g _ p@(TuplePat {})  = tidy1 v g p
    
    541
    -tidy_bang_pat v g _ p@(SumPat {})    = tidy1 v g p
    
    544
    +tidy_bang_pat v _ p@(LitPat {})    = tidy1 v p
    
    545
    +tidy_bang_pat v _ p@(ListPat {})   = tidy1 v p
    
    546
    +tidy_bang_pat v _ p@(TuplePat {})  = tidy1 v p
    
    547
    +tidy_bang_pat v _ p@(SumPat {})    = tidy1 v p
    
    542 548
     
    
    543 549
     -- Data/newtype constructors
    
    544
    -tidy_bang_pat v g l p@(ConPat { pat_con = L _ (RealDataCon dc)
    
    545
    -                              , pat_args = args
    
    546
    -                              , pat_con_ext = ConPatTc
    
    547
    -                                { cpt_arg_tys = arg_tys
    
    548
    -                                }
    
    549
    -                              })
    
    550
    +tidy_bang_pat v l p@(ConPat { pat_con = L _ (RealDataCon dc)
    
    551
    +                            , pat_args = args
    
    552
    +                            , pat_con_ext = ConPatTc
    
    553
    +                              { cpt_arg_tys = arg_tys
    
    554
    +                              }
    
    555
    +                            })
    
    550 556
       -- Newtypes: push bang inwards (#9844)
    
    551 557
       =
    
    552 558
         if isNewTyCon (dataConTyCon dc)
    
    553
    -      then tidy1 v g (p { pat_args = push_bang_into_newtype_arg l (scaledThing ty) args })
    
    554
    -      else tidy1 v g p  -- Data types: discard the bang
    
    559
    +      then tidy1 v (p { pat_args = push_bang_into_newtype_arg l (scaledThing ty) args })
    
    560
    +      else tidy1 v p  -- Data types: discard the bang
    
    555 561
         where
    
    556 562
           (ty:_) = dataConInstArgTys dc arg_tys
    
    557 563
     
    
    ... ... @@ -570,7 +576,7 @@ tidy_bang_pat v g l p@(ConPat { pat_con = L _ (RealDataCon dc)
    570 576
     --
    
    571 577
     -- NB: SigPatIn, ConPatIn should not happen
    
    572 578
     
    
    573
    -tidy_bang_pat _ _ l p = return (idDsWrapper, BangPat noExtField (L l p))
    
    579
    +tidy_bang_pat _ l p = return (idDsWrapper, BangPat noExtField (L l p))
    
    574 580
     
    
    575 581
     -------------------
    
    576 582
     push_bang_into_newtype_arg :: SrcSpanAnnA
    
    ... ... @@ -954,7 +960,7 @@ matchSinglePatVar var mb_scrut ctx pat ty match_result
    954 960
            ; ldi_nablas <-
    
    955 961
              if  isMatchContextPmChecked_SinglePat dflags FromSource ctx pat
    
    956 962
              then addCoreScrutTmCs (maybeToList mb_scrut) [var] $
    
    957
    -              pmcPatBind (DsMatchContext ctx locn) var (unLoc pat)
    
    963
    +              pmcPatBind (DsMatchContext ctx locn) var pat
    
    958 964
              else getLdiNablas
    
    959 965
     
    
    960 966
            ; let eqn_info = EqnMatch { eqn_pat = decideBangHood dflags pat
    

  • compiler/GHC/HsToCore/Monad.hs
    ... ... @@ -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)
    

  • compiler/GHC/HsToCore/Pmc.hs
    ... ... @@ -104,7 +104,7 @@ whenDoingPmc no_pmc thing_inside
    104 104
                 Ldi nablas -> thing_inside nablas }
    
    105 105
     
    
    106 106
     -- | Check a pattern binding (let, where) for exhaustiveness.
    
    107
    -pmcPatBind :: DsMatchContext -> Id -> Pat GhcTc -> DsM LdiNablas
    
    107
    +pmcPatBind :: DsMatchContext -> Id -> LPat GhcTc -> DsM LdiNablas
    
    108 108
     pmcPatBind ctxt@(DsMatchContext match_ctxt loc) var p
    
    109 109
       = whenDoingPmc NoPmc $ \ !missing ->
    
    110 110
         mb_discard_warnings $ do
    

  • compiler/GHC/HsToCore/Pmc/Desugar.hs
    ... ... @@ -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)
    
    ... ... @@ -374,11 +378,11 @@ desugarConPatOut x con univ_tys ex_tvs dicts = \case
    374 378
           -- tracePm "ConPatOut" (ppr x $$ ppr con $$ ppr arg_ids)
    
    375 379
           pure (con_grd `consGrdDag` arg_grds)
    
    376 380
     
    
    377
    -desugarPatBind :: SrcSpan -> Id -> Pat GhcTc -> DsM (PmPatBind Pre)
    
    381
    +desugarPatBind :: SrcSpan -> Id -> LPat GhcTc -> DsM (PmPatBind Pre)
    
    378 382
     -- See 'GrdPatBind' for how this simply repurposes GrdGRHS.
    
    379 383
     -- See Note [Suppress warnings in PMC desugaring]
    
    380 384
     desugarPatBind loc var pat = discardWarningsDs $
    
    381
    -  PmPatBind . flip PmGRHS (SrcInfo (L loc (ppr pat))) <$> desugarPat var pat
    
    385
    +  PmPatBind . flip PmGRHS (SrcInfo (L loc (ppr pat))) <$> desugarLPat var pat
    
    382 386
     
    
    383 387
     desugarEmptyCase :: Id -> DsM PmEmptyCase
    
    384 388
     desugarEmptyCase var = pure PmEmptyCase { pe_var = var }
    
    ... ... @@ -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
     -}

  • compiler/GHC/HsToCore/Types.hs
    ... ... @@ -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
    

  • compiler/GHC/HsToCore/Utils.hs
    ... ... @@ -1025,6 +1025,9 @@ Specifically:
    1025 1025
     
    
    1026 1026
     
    
    1027 1027
     -- | Use -XStrict to add a ! or remove a ~
    
    1028
    +-- The bang we insert is compiler-generated, so we put it at a generatedSrcSpan.
    
    1029
    +-- The pattern-match checker uses this (via dsl_in_generated_code) to avoid reporting
    
    1030
    +-- such bangs under -Wredundant-bang-patterns (#27323).
    
    1028 1031
     -- See Note [decideBangHood]
    
    1029 1032
     decideBangHood :: DynFlags
    
    1030 1033
                    -> LPat GhcTc  -- ^ Original pattern
    
    ... ... @@ -1040,7 +1043,7 @@ decideBangHood dflags lpat
    1040 1043
                ParPat x p -> L l (ParPat x (go p))
    
    1041 1044
                LazyPat _ lp' -> lp'
    
    1042 1045
                BangPat _ _   -> lp
    
    1043
    -           _             -> L l (BangPat noExtField lp)
    
    1046
    +           _             -> L (noAnnSrcSpan generatedSrcSpan) (BangPat noExtField lp)
    
    1044 1047
     
    
    1045 1048
     isTrueLHsExpr :: LHsExpr GhcTc -> Maybe (CoreExpr -> DsM CoreExpr)
    
    1046 1049
     
    

  • compiler/GHC/Types/Demand.hs
    ... ... @@ -924,6 +924,8 @@ maxCard (Card a) (Card b) = Card ((a .&. b .&. 0b001) .|. ((a .|. b) .&. 0b110))
    924 924
     maxDmd :: Demand -> Demand -> Demand
    
    925 925
     maxDmd BotDmd      dmd2        = dmd2
    
    926 926
     maxDmd dmd1        BotDmd      = dmd1
    
    927
    +maxDmd AbsDmd      dmd2        = dmd2
    
    928
    +maxDmd dmd1        AbsDmd      = dmd1
    
    927 929
     maxDmd (n1 :* sd1) (n2 :* sd2) =
    
    928 930
       maxCard n1 n2 :* maxSubDmd sd1 sd2
    
    929 931
     
    

  • testsuite/tests/dmdanal/should_run/T27845.hs
    1
    +module Main where
    
    2
    +import T27845_Lib (f)
    
    3
    +import System.Environment (getArgs)
    
    4
    +
    
    5
    +{-# NOINLINE mkArg #-}
    
    6
    +mkArg :: Int -> Int
    
    7
    +mkArg n | n < 0     = n
    
    8
    +        | otherwise = error ("boom " ++ show n)
    
    9
    +
    
    10
    +main :: IO ()
    
    11
    +main = do
    
    12
    +  n <- length <$> getArgs
    
    13
    +  let x = mkArg n
    
    14
    +  print (length (f (x, x) n))

  • testsuite/tests/dmdanal/should_run/T27845.stdout
    1
    +0

  • testsuite/tests/dmdanal/should_run/T27845_Lib.hs
    1
    +module T27845_Lib where
    
    2
    +
    
    3
    +{-# INLINABLE [2] f #-}
    
    4
    +f :: a -> Int -> [a]
    
    5
    +f p x = lazyUse p x ++ lazyUse p (x + 1) ++ lazyUse p (x + 2)
    
    6
    +
    
    7
    +{-# NOINLINE lazyUse #-}
    
    8
    +lazyUse :: a -> Int -> [a]
    
    9
    +lazyUse p x = p `seq` replicate x p
    
    10
    +
    
    11
    +{-# RULES "lazyUse" [1] forall p x. lazyUse p x = [] #-}

  • testsuite/tests/dmdanal/should_run/T27845b.hs
    1
    +module Main where
    
    2
    +import T27845b_Lib (outer)
    
    3
    +import System.Environment (getArgs)
    
    4
    +
    
    5
    +{-# NOINLINE mkArg #-}
    
    6
    +mkArg :: Int -> Int
    
    7
    +mkArg n | n < 0     = n
    
    8
    +        | otherwise = error ("boom " ++ show n)
    
    9
    +
    
    10
    +main :: IO ()
    
    11
    +main = do
    
    12
    +  n <- length <$> getArgs
    
    13
    +  let x = mkArg n
    
    14
    +  print (length (outer (x, x) n))

  • testsuite/tests/dmdanal/should_run/T27845b.stdout
    1
    +0

  • testsuite/tests/dmdanal/should_run/T27845b_Lib.hs
    1
    +module T27845b_Lib where
    
    2
    +
    
    3
    +outer :: a -> Int -> [a]
    
    4
    +outer a n =
    
    5
    +  let {-# INLINABLE [2] g #-}
    
    6
    +      g x = lazyUse a (x + 0) ++ lazyUse a (x + 1) ++ lazyUse a (x + 2)
    
    7
    +  in g n ++ g (n + 1) ++ g (n + 2)
    
    8
    +{-# NOINLINE outer #-}
    
    9
    +
    
    10
    +{-# NOINLINE lazyUse #-}
    
    11
    +lazyUse :: a -> Int -> [a]
    
    12
    +lazyUse p x = p `seq` replicate x p
    
    13
    +
    
    14
    +{-# RULES "lazyUse" [1] forall p x. lazyUse p x = [] #-}

  • testsuite/tests/dmdanal/should_run/all.T
    ... ... @@ -37,3 +37,5 @@ test('T25439', normal, compile_and_run, [''])
    37 37
     test('T26748', normal, compile_and_run, [''])
    
    38 38
     test('T26416', [extra_files(['M1.hs'])], multimod_compile_and_run, ['T26416','M1.hs'])
    
    39 39
     test('T27626', [extra_files(['M2.hs'])], multimod_compile_and_run, ['T27626','M2.hs'])
    
    40
    +test('T27845', [extra_files(['T27845_Lib.hs'])], multimod_compile_and_run, ['T27845','T27845_Lib.hs'])
    
    41
    +test('T27845b', [extra_files(['T27845b_Lib.hs'])], multimod_compile_and_run, ['T27845b','T27845b_Lib.hs'])

  • testsuite/tests/pmcheck/should_compile/T27323.hs
    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 ()

  • testsuite/tests/pmcheck/should_compile/T27323b.hs
    1
    +{-# LANGUAGE Strict, MonoLocalBinds #-}
    
    2
    +{-# OPTIONS_GHC -Wredundant-bang-patterns #-}
    
    3
    +module T27323b where
    
    4
    +
    
    5
    +f :: Int -> Int
    
    6
    +f x = let (a, b) = (x, x) in a + b

  • testsuite/tests/pmcheck/should_compile/all.T
    ... ... @@ -190,4 +190,6 @@ 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'])
    
    194
    +test('T27323b', normal, compile, ['-Wredundant-bang-patterns'])
    
    193 195
     test('T27360', normal, compile, [overlapping_incomplete + '-g3'])