[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 9 commits: testsuite: Explicitly use utf-8 encoding in rts-includes linter.
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
01ecb612 by Andreas Klebinger at 2026-02-04T09:56:25-05:00
testsuite: Explicitly use utf-8 encoding in rts-includes linter.
Not doing so caused failures on windows, as python failed to pick a
reasonable encoding even with locale set.
Fixes #26850
- - - - -
ea0d1317 by Zubin Duggal at 2026-02-04T09:57:06-05:00
Bump transformers submodule to 0.6.3.0
Fixes #26790
- - - - -
3f53fdf3 by Simon Peyton Jones at 2026-02-04T20:42:01-05:00
Fix subtle bug in GHC.Core.Utils.mkTick
This patch fixes a decade-old bug in `mkTick`, which
could generate type-incorrect code! See the diagnosis
in #26772.
The new code is simpler and easier to understand.
(As #26772 says, I think it could be improved further.)
- - - - -
5d2744fc by Simon Peyton Jones at 2026-02-04T20:42:01-05:00
Modify a debug-trace in the Simplifier
...just to show a bit more information.
- - - - -
92b90649 by Simon Peyton Jones at 2026-02-04T20:42:01-05:00
Fix long-standing interaction between ticks and casts
The code for Note [Eliminate Identity Cases] was simply wrong when
ticks and casts interacted. This patch fixes the interaction.
It was shown up when validating #26772, although it's not the exactly
the bug that's reported by #26772. Nor is it easy to reproduce, hence
no regression test.
- - - - -
4821fe9f by Cheng Shao at 2026-02-04T20:42:01-05:00
libraries: bump Cabal submodule to 3.16.1.0
- - - - -
1e6f680f by Cheng Shao at 2026-02-04T20:42:01-05:00
libraries: bump deepseq submodule to 1.5.2.0
Also:
- Get rid of usage of deprecated `NFData` function instance in the
compiler
- `T21391` still relies on `NFData` function instance, add
`-Wno-deprecations` for the time being.
- - - - -
0d198614 by Cheng Shao at 2026-02-04T20:42:01-05:00
libraries: bump directory submodule to 1.3.10.1
- - - - -
baa51223 by Cheng Shao at 2026-02-04T20:42:01-05:00
libraries: bump exceptions submodule to 0.10.12
- - - - -
17 changed files:
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/Tc/Instance/Class.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Unit/Module/ModIface.hs
- libraries/Cabal
- libraries/deepseq
- libraries/directory
- libraries/exceptions
- libraries/transformers
- testsuite/tests/ghci.debugger/scripts/T26042b.stdout
- testsuite/tests/ghci.debugger/scripts/T26042c.stdout
- testsuite/tests/ghci.debugger/scripts/T26042d2.stdout
- testsuite/tests/ghci.debugger/scripts/T26042f2.stdout
- testsuite/tests/linters/regex-linters/check-rts-includes.py
- testsuite/tests/simplCore/should_compile/T21391.hs
Changes:
=====================================
compiler/GHC/Core/Opt/Simplify/Iteration.hs
=====================================
@@ -1713,6 +1713,7 @@ simplCast env body co0 cont0
, sc_hole_ty = coercionLKind co }) }
-- NB! As the cast goes past, the
-- type of the hole changes (#16312)
+
-- (f |> co) e ===> (f (e |> co1)) |> co2
-- where co :: (s1->s2) ~ (t1->t2)
-- co1 :: t1 ~ s1
@@ -1838,7 +1839,7 @@ simpl_lam env bndr body (ApplyToVal { sc_arg = arg, sc_env = arg_se
, not ( isSimplified dup && -- See (SR2) in Note [Avoiding simplifying repeatedly]
not (exprIsTrivial arg) &&
not (isDeadOcc (idOccInfo bndr)) )
- -> do { simplTrace "SimplBindr:inline-uncond3" (ppr bndr) $
+ -> do { simplTrace "SimplBindr:inline-uncond3" (ppr bndr <+> text ":=" <+> ppr arg $$ ppr (seIdSubst env)) $
tick (PreInlineUnconditionally bndr)
; simplLam env' body cont }
=====================================
compiler/GHC/Core/Opt/Simplify/Utils.hs
=====================================
@@ -72,6 +72,7 @@ import GHC.Types.Tickish
import GHC.Types.Demand
import GHC.Types.Var.Set
import GHC.Types.Basic
+import GHC.Types.Name.Env
import GHC.Data.OrdList ( isNilOL )
import GHC.Data.FastString ( fsLit )
@@ -81,9 +82,9 @@ import GHC.Utils.Monad
import GHC.Utils.Outputable
import GHC.Utils.Panic
-import Control.Monad ( when )
+import Control.Monad ( guard, when )
import Data.List ( sortBy )
-import GHC.Types.Name.Env
+import Data.Maybe
import Data.Graph
{- *********************************************************************
@@ -2570,7 +2571,27 @@ Note [Eliminate Identity Case]
True -> True;
False -> False
-and similar friends.
+and similar friends. There are some tricky wrinkles:
+
+(EIC1) Casts. We've seen this:
+ case e of x { _ -> x `cast` c }
+ And we definitely want to eliminate this case, to give
+ e `cast` c
+(EIC2) Ticks. Similarly
+ case e of x { _ -> Tick t x }
+ At least if the tick is 'floatable' we want to eliminate the case
+ to give
+ Tick t e
+
+So `check_eq` strips off enclosing casts and ticks from the RHS of the
+alternative, returning a wrapper function that will rebuild them around
+the scrutinee if case-elim is successful.
+
+(EIC3) What if there are many alternatives, all identities. If casts
+ are involved they must be the same cast, to make the types line up.
+ In principle there could be different ticks in each RHS, but we just
+ pick the ticks from the first alternative. (In the common case there
+ is only one alternative.)
Note [Scrutinee Constant Folding]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2764,45 +2785,47 @@ mkCase mode scrut outer_bndr alts_ty alts
-- See Note [Eliminate Identity Case]
--------------------------------------------------
-mkCase1 _mode scrut case_bndr _ alts@(Alt _ _ rhs1 : alts') -- Identity case
- | all identity_alt alts
+mkCase1 _mode scrut case_bndr _ (alt1 : alts) -- Identity case
+ | Just wrap <- identity_alt alt1 -- `wrap`: see (EIC1) and (EIC2)
+ , all (isJust . identity_alt) alts -- See (EIC3) in Note [Eliminate Identity Case]
= do { tick (CaseIdentity case_bndr)
- ; return (mkTicks ticks $ re_cast scrut rhs1) }
+ ; return (wrap scrut) }
where
- ticks = concatMap (\(Alt _ _ rhs) -> stripTicksT tickishFloatable rhs) alts'
- identity_alt (Alt con args rhs) = check_eq rhs con args
-
- check_eq (Cast rhs co) con args -- See Note [RHS casts]
- = not (any (`elemVarSet` tyCoVarsOfCo co) args) && check_eq rhs con args
- check_eq (Tick t e) alt args
- = tickishFloatable t && check_eq e alt args
-
- check_eq (Lit lit) (LitAlt lit') _ = lit == lit'
- check_eq (Var v) _ _ | v == case_bndr = True
- check_eq (Var v) (DataAlt con) args
- | null arg_tys, null args = v == dataConWorkId con
- -- Optimisation only
- check_eq rhs (DataAlt con) args = cheapEqExpr' tickishFloatable rhs $
- mkConApp2 con arg_tys args
- check_eq _ _ _ = False
+ identity_alt :: CoreAlt -> Maybe (CoreExpr -> CoreExpr)
+ identity_alt (Alt con args rhs) = check_eq con args rhs
+
+ check_eq :: AltCon -> [Var] -> CoreExpr -> Maybe (CoreExpr -> CoreExpr)
+ -- (check_eq con args e) return True if
+ -- e looks like (Tick (Cast (Tick (con args))))
+ -- where (con args) is the LHS of the alternative
+ -- In that case it returns (\e. Tick (Cast (Tick e))),
+ -- a wrapper function that can rebuild the tick/cast stuff
+ -- See (EIC1) and (EIC2) in Note [Eliminate Identity Case]
+ check_eq alt_con args (Cast e co) -- See (EIC1)
+ = do { guard (not (any (`elemVarSet` tyCoVarsOfCo co) args))
+ ; wrap <- check_eq alt_con args e
+ ; return (flip mkCast co . wrap) }
+ check_eq alt_con args (Tick t e) -- See (EIC2)
+ = do { guard (tickishFloatable t)
+ ; wrap <- check_eq alt_con args e
+ ; return (Tick t . wrap) }
+ check_eq alt_con args e
+ | is_id alt_con args e = Just (\e -> e)
+ | otherwise = Nothing
+
+ is_id :: AltCon -> [Var] -> CoreExpr -> Bool
+ is_id _ _ (Var v) | v == case_bndr = True
+ is_id (LitAlt lit') _ (Lit lit) = lit == lit'
+ is_id (DataAlt con) args rhs
+ | Var v <- rhs -- Optimisation only
+ , null arg_tys
+ , null args = v == dataConWorkId con
+ | otherwise = cheapEqExpr' tickishFloatable rhs $
+ mkConApp2 con arg_tys args
+ is_id _ _ _ = False
arg_tys = tyConAppArgs (idType case_bndr)
- -- Note [RHS casts]
- -- ~~~~~~~~~~~~~~~~
- -- We've seen this:
- -- case e of x { _ -> x `cast` c }
- -- And we definitely want to eliminate this case, to give
- -- e `cast` c
- -- So we throw away the cast from the RHS, and reconstruct
- -- it at the other end. All the RHS casts must be the same
- -- if (all identity_alt alts) holds.
- --
- -- Don't worry about nested casts, because the simplifier combines them
-
- re_cast scrut (Cast rhs co) = Cast (re_cast scrut rhs) co
- re_cast scrut _ = scrut
-
mkCase1 mode scrut bndr alts_ty alts = mkCase2 mode scrut bndr alts_ty alts
=====================================
compiler/GHC/Core/Utils.hs
=====================================
@@ -252,7 +252,7 @@ applyTypeToArgs op_ty args
mkCastMCo :: CoreExpr -> MCoercionR -> CoreExpr
mkCastMCo e MRefl = e
-mkCastMCo e (MCo co) = Cast e co
+mkCastMCo e (MCo co) = mkCast e co
-- We are careful to use (MCo co) only when co is not reflexive
-- Hence (Cast e co) rather than (mkCast e co)
@@ -305,40 +305,41 @@ mkCast expr co
-- | Wraps the given expression in the source annotation, dropping the
-- annotation if possible.
mkTick :: CoreTickish -> CoreExpr -> CoreExpr
-mkTick t orig_expr = mkTick' id id orig_expr
+mkTick t orig_expr = mkTick' id orig_expr
where
-- Some ticks (cost-centres) can be split in two, with the
-- non-counting part having laxer placement properties.
canSplit = tickishCanSplit t && tickishPlace (mkNoCount t) /= tickishPlace t
+
-- mkTick' handles floating of ticks *into* the expression.
- -- In this function, `top` is applied after adding the tick, and `rest` before.
- -- This will result in applications that look like (top $ Tick t $ rest expr).
- -- If we want to push the tick deeper, we pre-compose `top` with a function
- -- adding the tick.
- mkTick' :: (CoreExpr -> CoreExpr) -- apply after adding tick (float through)
- -> (CoreExpr -> CoreExpr) -- apply before adding tick (float with)
- -> CoreExpr -- current expression
+ mkTick' :: (CoreExpr -> CoreExpr) -- Apply before adding tick (float with)
+ -- Always a composition of (Tick t) wrappers
+ -> CoreExpr -- Current expression
-> CoreExpr
- mkTick' top rest expr = case expr of
+ -- So in the call (mkTick' rest e), the expression
+ -- (rest e)
+ -- has the same type as e
+ -- Returns an expression equivalent to (Tick t (rest e))
+ mkTick' rest expr = case expr of
-- Float ticks into unsafe coerce the same way we would do with a cast.
Case scrut bndr ty alts@[Alt ac abs _rhs]
| Just rhs <- isUnsafeEqualityCase scrut bndr alts
- -> top $ mkTick' (\e -> Case scrut bndr ty [Alt ac abs e]) rest rhs
+ -> Case scrut bndr ty [Alt ac abs (mkTick' rest rhs)]
-- Cost centre ticks should never be reordered relative to each
-- other. Therefore we can stop whenever two collide.
Tick t2 e
- | ProfNote{} <- t2, ProfNote{} <- t -> top $ Tick t $ rest expr
+ | ProfNote{} <- t2, ProfNote{} <- t -> Tick t $ rest expr
-- Otherwise we assume that ticks of different placements float
-- through each other.
- | tickishPlace t2 /= tickishPlace t -> mkTick' (top . Tick t2) rest e
+ | tickishPlace t2 /= tickishPlace t -> Tick t2 $ mkTick' rest e
-- For annotations this is where we make sure to not introduce
-- redundant ticks.
- | tickishContains t t2 -> mkTick' top rest e
- | tickishContains t2 t -> orig_expr
- | otherwise -> mkTick' top (rest . Tick t2) e
+ | tickishContains t t2 -> mkTick' rest e -- Drop t2
+ | tickishContains t2 t -> rest e -- Drop t
+ | otherwise -> mkTick' (rest . Tick t2) e
-- Ticks don't care about types, so we just float all ticks
-- through them. Note that it's not enough to check for these
@@ -346,14 +347,14 @@ mkTick t orig_expr = mkTick' id id orig_expr
-- expressions below ticks, such constructs can be the result of
-- unfoldings. We therefore make an effort to put everything into
-- the right place no matter what we start with.
- Cast e co -> mkTick' (top . flip Cast co) rest e
- Coercion co -> Coercion co
+ Cast e co -> mkCast (mkTick' rest e) co
+ Coercion co -> Tick t $ rest (Coercion co)
Lam x e
-- Always float through type lambdas. Even for non-type lambdas,
-- floating is allowed for all but the most strict placement rule.
| not (isRuntimeVar x) || tickishPlace t /= PlaceRuntime
- -> mkTick' (top . Lam x) rest e
+ -> Lam x $ mkTick' rest e
-- If it is both counting and scoped, we split the tick into its
-- two components, often allowing us to keep the counting tick on
@@ -362,25 +363,25 @@ mkTick t orig_expr = mkTick' id id orig_expr
-- floated, and the lambda may then be in a position to be
-- beta-reduced.
| canSplit
- -> top $ Tick (mkNoScope t) $ rest $ Lam x $ mkTick (mkNoCount t) e
+ -> Tick (mkNoScope t) $ rest $ Lam x $ mkTick (mkNoCount t) e
App f arg
-- Always float through type applications.
| not (isRuntimeArg arg)
- -> mkTick' (top . flip App arg) rest f
+ -> App (mkTick' rest f) arg
-- We can also float through constructor applications, placement
-- permitting. Again we can split.
| isSaturatedConApp expr && (tickishPlace t==PlaceCostCentre || canSplit)
-> if tickishPlace t == PlaceCostCentre
- then top $ rest $ tickHNFArgs t expr
- else top $ Tick (mkNoScope t) $ rest $ tickHNFArgs (mkNoCount t) expr
+ then rest $ tickHNFArgs t expr
+ else Tick (mkNoScope t) $ rest $ tickHNFArgs (mkNoCount t) expr
Var x
| notFunction && tickishPlace t == PlaceCostCentre
- -> orig_expr
+ -> rest expr -- Drop t
| notFunction && canSplit
- -> top $ Tick (mkNoScope t) $ rest expr
+ -> Tick (mkNoScope t) $ rest expr
where
-- SCCs can be eliminated on variables provided the variable
-- is not a function. In these cases the SCC makes no difference:
@@ -392,10 +393,10 @@ mkTick t orig_expr = mkTick' id id orig_expr
Lit{}
| tickishPlace t == PlaceCostCentre
- -> orig_expr
+ -> rest expr -- Drop t
-- Catch-all: Annotate where we stand
- _any -> top $ Tick t $ rest expr
+ _any -> Tick t $ rest expr
mkTicks :: [CoreTickish] -> CoreExpr -> CoreExpr
mkTicks ticks expr = foldr mkTick expr ticks
=====================================
compiler/GHC/Tc/Instance/Class.hs
=====================================
@@ -49,6 +49,7 @@ import GHC.Core.Make ( mkCharExpr, mkNaturalExpr, mkStringExprFS, mkCoreLams )
import GHC.Core.DataCon
import GHC.Core.TyCon
import GHC.Core.Class
+import GHC.Core.Utils( mkCast )
import GHC.Core ( Expr(..), mkConApp )
import GHC.StgToCmm.Closure ( isSmallFamily )
@@ -455,7 +456,7 @@ matchWithDict [cls_ty, mty]
= mkCoreLams [ runtimeRep1TyVar, openAlphaTyVar, sv, k ] $
Var k `App` (evUnaryDictAppE cls dict_args meth_arg)
where
- meth_arg = Var sv `Cast` mkSubCo (evExprCoercion ev_expr)
+ meth_arg = Var sv `mkCast` mkSubCo (evExprCoercion ev_expr)
; let mk_ev [c] = evDictApp wd_cls [cls_ty, mty] [evWithDict c]
mk_ev e = pprPanic "matchWithDict" (ppr e)
@@ -657,7 +658,7 @@ matchDataToTag dataToTagClass [levity, dty] = do
(mkReflCo Representational intPrimTy)
-> do { addUsedDataCons rdr_env repTyCon -- See wrinkles DTW2 and DTW3
; let mk_ev _ = evDictApp dataToTagClass [levity, dty] $
- [methodRep `Cast` methodCo]
+ [methodRep `mkCast` methodCo]
; pure (OneInst { cir_new_theta = [] -- (Ignore stupid theta.)
, cir_mk_ev = mk_ev
, cir_canonical = EvCanonical
=====================================
compiler/GHC/Tc/Types/Evidence.hs
=====================================
@@ -59,6 +59,7 @@ import GHC.Tc.Utils.TcType
import GHC.Core
import GHC.Core.Coercion.Axiom
import GHC.Core.Coercion
+import GHC.Core.Utils( mkCast )
import GHC.Core.Ppr () -- Instance OutputableBndr TyVar
import GHC.Core.Predicate
import GHC.Core.Type
@@ -930,7 +931,7 @@ evCastE ee co
| assertPpr (coercionRole co == Representational)
(vcat [text "Coercion of wrong role passed to evCastE:", ppr ee, ppr co]) $
isReflCo co = ee
- | otherwise = Cast ee co
+ | otherwise = mkCast ee co
evDFunApp :: DFunId -> [Type] -> [EvExpr] -> EvTerm
-- Dictionary instance application, including when the "dictionary function"
=====================================
compiler/GHC/Unit/Module/ModIface.hs
=====================================
@@ -894,13 +894,7 @@ instance (NFData (IfaceAbiHashesExts phase), NFData (IfaceDeclExts phase)) => NF
`seq` rnf a14
instance NFData IfaceCache where
- rnf (IfaceCache a1 a2 a3 a4)
- = rnf a1
- `seq` rnf a2
- `seq` rnf a3
- `seq` rnf a4
-
-
+ rnf = rwhnf
forceModIface :: ModIface -> IO ()
forceModIface iface = () <$ (evaluate $ force iface)
=====================================
libraries/Cabal
=====================================
@@ -1 +1 @@
-Subproject commit d9b0904b49dc84e0bfc79062daf2bbdf9d22a422
+Subproject commit 8d1f5a33662be0db0654061fb53fb00e3f4417e0
=====================================
libraries/deepseq
=====================================
@@ -1 +1 @@
-Subproject commit ae2762ac241a61852c9ff4c287af234fb1ad931f
+Subproject commit 882f52f51854544a467babd8cb075e3271f5913e
=====================================
libraries/directory
=====================================
@@ -1 +1 @@
-Subproject commit 6442a3cf04f74d82cdf8c9213324313d52b23d28
+Subproject commit 8c712e834f277544fc03e96dfbbb769126dc0a7c
=====================================
libraries/exceptions
=====================================
@@ -1 +1 @@
-Subproject commit 81bfd6e0ca631f315658201ae02e30046678f056
+Subproject commit a3da039855479e3c8542e8b45986599d0414ff68
=====================================
libraries/transformers
=====================================
@@ -1 +1 @@
-Subproject commit cee47cca7705edafe0a5839439e679edbd61890a
+Subproject commit 0d615bc2457d5d2c695dcfdb902d88c1225beff3
=====================================
testsuite/tests/ghci.debugger/scripts/T26042b.stdout
=====================================
@@ -22,30 +22,18 @@ _result ::
-> (# GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld,
Int #) = _
Stopped in Main.foo, T26042b.hs:14:3-18
-_result ::
- GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld
- -> (# GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld,
- Int #) = _
+_result :: IO Int = _
13 y = 4
14 n <- bar (x + y)
^^^^^^^^^^^^^^^^
15 return n
-_result ::
- GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld
- -> (# GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld,
- Int #) = _
+_result :: IO Int = _
Stopped in Main.main, T26042b.hs:5:3-26
-_result ::
- GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld
- -> (# GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld,
- () #) = _
+_result :: IO () = _
4 main = do
5 a <- foo False undefined
^^^^^^^^^^^^^^^^^^^^^^^^
6 print a
-_result ::
- GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld
- -> (# GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld,
- () #) = _
+_result :: IO () = _
14
14
=====================================
testsuite/tests/ghci.debugger/scripts/T26042c.stdout
=====================================
@@ -1,18 +1,12 @@
Breakpoint 0 activated at T26042c.hs:10:15-22
Stopped in Main.foo, T26042c.hs:10:15-22
-_result ::
- GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld
- -> (# GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld,
- Int #) = _
+_result :: IO Int = _
9 foo :: Bool -> Int -> IO Int
10 foo True i = return i
^^^^^^^^
11 foo False _ = do
Stopped in Main.main, T26042c.hs:5:3-26
-_result ::
- GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld
- -> (# GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld,
- () #) = _
+_result :: IO () = _
4 main = do
5 a <- foo False undefined
^^^^^^^^^^^^^^^^^^^^^^^^
=====================================
testsuite/tests/ghci.debugger/scripts/T26042d2.stdout
=====================================
@@ -1,10 +1,7 @@
Breakpoint 0 activated at T26042d2.hs:11:3-21
hello1
Stopped in Main.f, T26042d2.hs:11:3-21
-_result ::
- GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld
- -> (# GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld,
- () #) = _
+_result :: IO () = _
10 f = do
11 putStrLn "hello2.1"
^^^^^^^^^^^^^^^^^^^
=====================================
testsuite/tests/ghci.debugger/scripts/T26042f2.stdout
=====================================
@@ -1,6 +1,6 @@
Breakpoint 0 activated at T26042f.hs:(20,7)-(21,14)
Stopped in T8.t, T26042f.hs:(20,7)-(21,14)
-_result :: Int = _
+_result :: Identity Int = _
x :: Int = 450
19 t :: Int -> Identity Int
vv
@@ -18,12 +18,12 @@ _result :: Identity Int = _
^^^^^^^^^^^^
15 n <- pure (a+a)
Stopped in T8.f, T26042f.hs:8:3-14
-_result :: Identity Int = _
+_result :: Int = _
x :: Int = 15
7 f x = do
8 b <- g (x*x)
^^^^^^^^^^^^
9 y <- pure (b+b)
x :: Int = 15
-_result :: Identity Int = _
+_result :: Int = _
7248
=====================================
testsuite/tests/linters/regex-linters/check-rts-includes.py
=====================================
@@ -12,12 +12,16 @@ import re
INCLUDE_RE = re.compile('# *include ([<"][^">]+[>"])')
def get_includes(file: Path) -> List[Tuple[int, str]]:
- txt = file.read_text()
- return [ (line_no+1, m.group(1) )
- for (line_no, line) in enumerate(txt.split('\n'))
- for m in [INCLUDE_RE.match(line)]
- if m is not None
- if m.group(1) != "rts/PosixSource.h"]
+ try:
+ txt = file.read_text(encoding="utf-8")
+ return [ (line_no+1, m.group(1) )
+ for (line_no, line) in enumerate(txt.split('\n'))
+ for m in [INCLUDE_RE.match(line)]
+ if m is not None
+ if m.group(1) != "rts/PosixSource.h"]
+ except Exception as e:
+ e.add_note(f"While reading includes from {file}")
+ raise
def in_rts_dir(path: Path) -> bool:
return len(path.parts) > 0 and path.parts[0] == 'rts'
@@ -40,9 +44,14 @@ class RtsHIncludeOrderLinter(Linter):
'"ghcplatform.h"',
}
- includes = get_includes(path)
- headers = [x[1] for x in includes]
- lines = path.read_text().split('\n')
+ try:
+ includes = get_includes(path)
+ headers = [x[1] for x in includes]
+ lines = path.read_text(encoding="utf-8").split('\n')
+ # #26850
+ except Exception as e:
+ e.add_note(f"Error while decoding path {path}")
+ raise e
if '"PosixSource.h"' in headers:
for line_no, header in includes:
@@ -69,18 +78,22 @@ class PrivateIncludeLinter(Linter):
def lint(self, path: Path):
private = False
- lines = path.read_text().split('\n')
- for line_no, include in get_includes(path):
- if include == '"BeginPrivate.h"':
- private = True
- elif include == '"EndPrivate.h"':
- private = False
- elif private:
- self.add_warning(Warning(
- path=path,
- line_no=line_no,
- line_content=lines[line_no-1],
- message='System header %s found inside of
participants (1)
-
Marge Bot (@marge-bot)