Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
-
2f3cc9ff
by Simon Jakobi at 2026-06-08T07:55:49-04:00
-
eb3bf6e7
by Alan Zimmerman at 2026-06-08T07:56:32-04:00
-
0dc97b12
by Brian McKenna at 2026-06-09T06:38:48-04:00
-
3465c065
by David Eichmann at 2026-06-09T06:38:49-04:00
8 changed files:
- + changelog.d/T27314.md
- compiler/GHC/HsToCore/Pmc/Solver.hs
- hadrian/src/Rules/BinaryDist.hs
- testsuite/mk/test.mk
- + testsuite/tests/pmcheck/should_compile/T27314.hs
- testsuite/tests/pmcheck/should_compile/all.T
- utils/check-exact/Main.hs
- utils/check-exact/Transform.hs
Changes:
| 1 | +section: compiler
|
|
| 2 | +issues: #27314
|
|
| 3 | +mrs: !16118
|
|
| 4 | +synopsis:
|
|
| 5 | + Fix spurious ``-Wincomplete-uni-patterns`` warning under ``-finfo-table-map``.
|
|
| 6 | +description:
|
|
| 7 | + The pattern-match checker now ignores ticks when comparing scrutinees in
|
|
| 8 | + its CoreMap, so long-distance information is no longer lost across
|
|
| 9 | + function-application scrutinees because debug source annotations
|
|
| 10 | + (e.g. SourceNotes added by ``-finfo-table-map``) were inserted. |
| ... | ... | @@ -1000,8 +1000,9 @@ makeDictsCoherent (Case scrut bndr ty alts) |
| 1000 | 1000 | , let expr' = makeDictsCoherent expr ]
|
| 1001 | 1001 | makeDictsCoherent (Cast expr co)
|
| 1002 | 1002 | = Cast (makeDictsCoherent expr) co
|
| 1003 | -makeDictsCoherent (Tick tick expr)
|
|
| 1004 | - = Tick tick (makeDictsCoherent expr)
|
|
| 1003 | +makeDictsCoherent (Tick _tick expr)
|
|
| 1004 | + -- See Wrinkle (UD1) in Note [Unique dictionaries in the TmOracle CoreMap]
|
|
| 1005 | + = makeDictsCoherent expr
|
|
| 1005 | 1006 | makeDictsCoherent ty@(Type {})
|
| 1006 | 1007 | = ty
|
| 1007 | 1008 | makeDictsCoherent co@(Coercion {})
|
| ... | ... | @@ -1061,6 +1062,25 @@ In the end, replacing dictionaries with an error value in the pattern-match |
| 1061 | 1062 | checker was the most self-contained, although we might want to revisit once
|
| 1062 | 1063 | we implement a more robust approach to computing equality in the pattern-match
|
| 1063 | 1064 | checker (see #19272).
|
| 1065 | + |
|
| 1066 | +Wrinkle (UD1): ticks
|
|
| 1067 | +--------------------
|
|
| 1068 | +'makeDictsCoherent' also drops all ticks. The CoreMap key represents
|
|
| 1069 | +value-level equality, which ticks never affect.
|
|
| 1070 | + |
|
| 1071 | +Example (#27314): with -finfo-table-map every record-selector use site is
|
|
| 1072 | +wrapped in a 'SourceNote' carrying that site's span (see
|
|
| 1073 | +Note [Record-selector ticks] in GHC.HsToCore.Ticks). Given
|
|
| 1074 | + |
|
| 1075 | + data Box = Box { unBox :: Maybe Int }
|
|
| 1076 | + f b = case unBox b of
|
|
| 1077 | + Nothing -> 0
|
|
| 1078 | + Just _ -> let Just x = unBox b in x
|
|
| 1079 | + |
|
| 1080 | +the two `unBox b`s carry different SourceNote spans. Without tick stripping
|
|
| 1081 | +the CoreMap treats them as distinct expressions. Long-distance information
|
|
| 1082 | +from the outer `Just _` branch therefore never reaches the let-pattern, and
|
|
| 1083 | +`Just x = unBox b` is wrongly reported as non-exhaustive.
|
|
| 1064 | 1084 | -}
|
| 1065 | 1085 | |
| 1066 | 1086 | {- Note [The Pos/Neg invariant]
|
| ... | ... | @@ -290,23 +290,25 @@ bindistRules = do |
| 290 | 290 | copyFile ("hadrian" -/- "cfg" -/- "default.target.in") (bindistFilesDir -/- "default.target.in")
|
| 291 | 291 | copyFile ("hadrian" -/- "cfg" -/- "default.host.target.in") (bindistFilesDir -/- "default.host.target.in")
|
| 292 | 292 | |
| 293 | - -- todo: do we need these wrappers on windows
|
|
| 294 | - forM_ bin_targets $ \(pkg, _) -> do
|
|
| 295 | - needed_wrappers <- pkgToWrappers pkg
|
|
| 296 | - forM_ needed_wrappers $ \wrapper_name -> do
|
|
| 297 | - let suffix = if useGhcPrefix pkg
|
|
| 298 | - then "ghc-" ++ version
|
|
| 299 | - else version
|
|
| 300 | - wrapper_content <- wrapper wrapper_name
|
|
| 301 | - let unversioned_wrapper_path = bindistFilesDir -/- "wrappers" -/- wrapper_name
|
|
| 302 | - versioned_wrapper = wrapper_name ++ "-" ++ suffix
|
|
| 303 | - versioned_wrapper_path = bindistFilesDir -/- "wrappers" -/- versioned_wrapper
|
|
| 304 | - -- Write the wrapper to the versioned path
|
|
| 305 | - writeFile' versioned_wrapper_path wrapper_content
|
|
| 306 | - -- Create a symlink from the non-versioned to the versioned.
|
|
| 307 | - liftIO $ do
|
|
| 308 | - IO.removeFile unversioned_wrapper_path <|> return ()
|
|
| 309 | - IO.createFileLink versioned_wrapper unversioned_wrapper_path
|
|
| 293 | + -- These wrapper scripts are only necessary in the configure/install
|
|
| 294 | + -- workflow which is not supported on windows.
|
|
| 295 | + unless windowsHost $ do
|
|
| 296 | + forM_ bin_targets $ \(pkg, _) -> do
|
|
| 297 | + needed_wrappers <- pkgToWrappers pkg
|
|
| 298 | + forM_ needed_wrappers $ \wrapper_name -> do
|
|
| 299 | + let suffix = if useGhcPrefix pkg
|
|
| 300 | + then "ghc-" ++ version
|
|
| 301 | + else version
|
|
| 302 | + wrapper_content <- wrapper wrapper_name
|
|
| 303 | + let unversioned_wrapper_path = bindistFilesDir -/- "wrappers" -/- wrapper_name
|
|
| 304 | + versioned_wrapper = wrapper_name ++ "-" ++ suffix
|
|
| 305 | + versioned_wrapper_path = bindistFilesDir -/- "wrappers" -/- versioned_wrapper
|
|
| 306 | + -- Write the wrapper to the versioned path
|
|
| 307 | + writeFile' versioned_wrapper_path wrapper_content
|
|
| 308 | + -- Create a symlink from the non-versioned to the versioned.
|
|
| 309 | + liftIO $ do
|
|
| 310 | + IO.removeFile unversioned_wrapper_path <|> return ()
|
|
| 311 | + IO.createFileLink versioned_wrapper unversioned_wrapper_path
|
|
| 310 | 312 | |
| 311 | 313 | let buildBinDist compressor = do
|
| 312 | 314 | win_target <- isWinTarget
|
| ... | ... | @@ -109,9 +109,11 @@ endif |
| 109 | 109 | HAVE_GDB := $(shell if gdb --version > /dev/null 2> /dev/null; then echo YES; else echo NO; fi)
|
| 110 | 110 | HAVE_READELF := $(shell if readelf --version > /dev/null 2> /dev/null; then echo YES; else echo NO; fi)
|
| 111 | 111 | |
| 112 | -# we need a better way to find which backend is selected and if --check flag is
|
|
| 113 | -# used
|
|
| 114 | -BIGNUM_GMP := $(shell "$(GHC_PKG)" field ghc-bignum exposed-modules | grep GMP)
|
|
| 112 | +# Detect whether the fast (GMP) bignum backend is in use. The GMP backend module
|
|
| 113 | +# in ghc-internal is hidden, so we look instead for the gmp library it links
|
|
| 114 | +# against: GMP_LIBS adds gmp to ghc-internal's extra-libraries only on a GMP
|
|
| 115 | +# build.
|
|
| 116 | +BIGNUM_GMP := $(shell "$(GHC_PKG)" field ghc-internal extra-libraries 2>/dev/null | grep gmp)
|
|
| 115 | 117 | |
| 116 | 118 | ifeq "$(filter thr, $(GhcRTSWays))" "thr"
|
| 117 | 119 | RUNTEST_OPTS += -e config.ghc_with_threaded_rts=True
|
| 1 | +module T27314 where
|
|
| 2 | + |
|
| 3 | +data Box = Box { unBox :: Maybe Int }
|
|
| 4 | + |
|
| 5 | +f :: Box -> Int
|
|
| 6 | +f b = case unBox b of
|
|
| 7 | + Nothing -> 0
|
|
| 8 | + Just _ -> let Just x = unBox b in x |
| ... | ... | @@ -93,6 +93,7 @@ test('T21360', normal, compile, [overlapping_incomplete+'-Wincomplete-record-upd |
| 93 | 93 | test('T21360b', normal, compile, [overlapping_incomplete+'-Wincomplete-record-updates'])
|
| 94 | 94 | test('T23520', normal, compile, [overlapping_incomplete+'-Wincomplete-record-updates'])
|
| 95 | 95 | test('T25164', [extra_files(['T25164_aux.hs']), req_th], multimod_compile, ['T25164', '-v0'])
|
| 96 | +test('T27314', normal, compile, ['-Wincomplete-uni-patterns -finfo-table-map'])
|
|
| 96 | 97 | |
| 97 | 98 | # Other tests
|
| 98 | 99 | test('pmc001', [], compile, [overlapping_incomplete])
|
| ... | ... | @@ -646,7 +646,7 @@ addLocaLDecl3 :: Changer |
| 646 | 646 | addLocaLDecl3 libdir top = do
|
| 647 | 647 | Right newDecl <- withDynFlags libdir (\df -> parseDecl df "decl" "nn = 2")
|
| 648 | 648 | let
|
| 649 | - doAddLocal = replaceDecls (anchorEof lp) [parent',d2']
|
|
| 649 | + doAddLocal = replaceDecls (addModuleCommentOrigDeltas lp) [parent',d2']
|
|
| 650 | 650 | where
|
| 651 | 651 | lp = top
|
| 652 | 652 | (de1:d2:_) = hsDecls lp
|
| ... | ... | @@ -667,7 +667,7 @@ addLocaLDecl4 libdir lp = do |
| 667 | 667 | Right newDecl <- withDynFlags libdir (\df -> parseDecl df "decl" "nn = 2")
|
| 668 | 668 | Right newSig <- withDynFlags libdir (\df -> parseDecl df "sig" "nn :: Int")
|
| 669 | 669 | let
|
| 670 | - doAddLocal = replaceDecls (anchorEof lp) (parent':ds)
|
|
| 670 | + doAddLocal = replaceDecls (addModuleCommentOrigDeltas lp) (parent':ds)
|
|
| 671 | 671 | where
|
| 672 | 672 | (parent:ds) = hsDecls (makeDeltaAst lp)
|
| 673 | 673 | |
| ... | ... | @@ -781,7 +781,7 @@ rmDecl3 _libdir lp = do |
| 781 | 781 | rmDecl4 :: Changer
|
| 782 | 782 | rmDecl4 _libdir lp = do
|
| 783 | 783 | let
|
| 784 | - doRmDecl = replaceDecls (anchorEof lp) [de1',sd1]
|
|
| 784 | + doRmDecl = replaceDecls (addModuleCommentOrigDeltas lp) [de1',sd1]
|
|
| 785 | 785 | where
|
| 786 | 786 | [de1] = hsDecls lp
|
| 787 | 787 | (de1',Just sd1) = modifyValD (getLocA de1) de1 $ \_m [sd1a,sd2] ->
|
| ... | ... | @@ -65,7 +65,7 @@ module Transform |
| 65 | 65 | , balanceComments
|
| 66 | 66 | , balanceCommentsList
|
| 67 | 67 | , balanceCommentsListA
|
| 68 | - , anchorEof
|
|
| 68 | + , addModuleCommentOrigDeltas
|
|
| 69 | 69 | |
| 70 | 70 | -- ** Managing lists, pure functions
|
| 71 | 71 | , captureOrderBinds
|
| ... | ... | @@ -724,8 +724,8 @@ balanceSameLineComments (L la (Match anm mctxt pats (GRHSs x grhss lb))) |
| 724 | 724 | |
| 725 | 725 | -- ---------------------------------------------------------------------
|
| 726 | 726 | |
| 727 | -anchorEof :: ParsedSource -> ParsedSource
|
|
| 728 | -anchorEof (L l m@(HsModule (XModulePs an _lo _ _) _mn _exps _imps _decls)) = L l (m { hsmodExt = (hsmodExt m){ hsmodAnn = an' } })
|
|
| 727 | +addModuleCommentOrigDeltas :: ParsedSource -> ParsedSource
|
|
| 728 | +addModuleCommentOrigDeltas (L l m@(HsModule (XModulePs an _lo _ _) _mn _exps _imps _decls)) = L l (m { hsmodExt = (hsmodExt m){ hsmodAnn = an' } })
|
|
| 729 | 729 | where
|
| 730 | 730 | an' = addCommentOrigDeltasAnn an
|
| 731 | 731 |