Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
-
815149f3
by Andrzej Rybczak at 2026-07-25T15:06:43+00:00
21 changed files:
- + changelog.d/warn-defaulted-callstack
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Types/Error/Codes.hs
- docs/users_guide/using-warnings.rst
- libraries/base/changelog.md
- libraries/base/src/GHC/Stack.hs
- libraries/ghc-internal/src/GHC/Internal/Stack.hs
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- + testsuite/tests/typecheck/should_compile/WarnDefaultedCallStack.hs
- + testsuite/tests/typecheck/should_compile/WarnDefaultedCallStack.stderr
- testsuite/tests/typecheck/should_compile/all.T
Changes:
| 1 | +section: compiler
|
|
| 2 | +issues: #27077
|
|
| 3 | +mrs: !16174
|
|
| 4 | +synopsis: Add ``-Wdefaulted-callstack``
|
|
| 5 | +description:
|
|
| 6 | + GHC now supports a new warning, ``-Wdefaulted-callstack``, which warns when an
|
|
| 7 | + implicit ``CallStack`` parameter is defaulted to the empty stack. In
|
|
| 8 | + particular, this includes call sites where a function with a ``HasCallStack``
|
|
| 9 | + constraint is called from a definition that does *not* provide one. At such
|
|
| 10 | + call sites the call stack is cut off and does not include the enclosing
|
|
| 11 | + definition's callers, which can be a source of surprise if the user wants
|
|
| 12 | + complete call stacks. |
| ... | ... | @@ -1135,6 +1135,7 @@ data WarningFlag = |
| 1135 | 1135 | | Opt_WarnPatternNamespaceSpecifier -- ^ @since 9.14
|
| 1136 | 1136 | | Opt_WarnUnrecognisedModifiers -- ^ @since 10.0
|
| 1137 | 1137 | | Opt_WarnSemaphoreOpenFailure -- Since 10.0.1
|
| 1138 | + | Opt_WarnDefaultedCallStack -- ^ @since 10.2
|
|
| 1138 | 1139 | deriving (Eq, Ord, Show, Enum, Bounded)
|
| 1139 | 1140 | |
| 1140 | 1141 | -- | Return the names of a WarningFlag
|
| ... | ... | @@ -1258,6 +1259,7 @@ warnFlagNames wflag = case wflag of |
| 1258 | 1259 | Opt_WarnPatternNamespaceSpecifier -> "pattern-namespace-specifier" :| []
|
| 1259 | 1260 | Opt_WarnUnrecognisedModifiers -> "unrecognised-modifiers" :| []
|
| 1260 | 1261 | Opt_WarnSemaphoreOpenFailure -> "semaphore-open-failure" :| []
|
| 1262 | + Opt_WarnDefaultedCallStack -> "defaulted-callstack" :| []
|
|
| 1261 | 1263 | |
| 1262 | 1264 | -- -----------------------------------------------------------------------------
|
| 1263 | 1265 | -- Standard sets of warning options
|
| ... | ... | @@ -2446,6 +2446,7 @@ wWarningFlagsDeps = [minBound..maxBound] >>= \x -> case x of |
| 2446 | 2446 | Opt_WarnPatternNamespaceSpecifier -> warnSpec x
|
| 2447 | 2447 | Opt_WarnUnrecognisedModifiers -> warnSpec x
|
| 2448 | 2448 | Opt_WarnSemaphoreOpenFailure -> warnSpec x
|
| 2449 | + Opt_WarnDefaultedCallStack -> warnSpec x
|
|
| 2449 | 2450 | |
| 2450 | 2451 | warningGroupsDeps :: [(Deprecation, FlagSpec WarningGroup)]
|
| 2451 | 2452 | warningGroupsDeps = map mk warningGroups
|
| ... | ... | @@ -1941,6 +1941,19 @@ instance Diagnostic TcRnMessage where |
| 1941 | 1941 | = vcat [ text "Future versions of GHC will turn this warning into an error." ]
|
| 1942 | 1942 | proposal
|
| 1943 | 1943 | = vcat [ text "See GHC Proposal #330." ]
|
| 1944 | + TcRnDefaultedCallStack ct_loc
|
|
| 1945 | + -> mkSimpleDecorated $ case ctLocOrigin ct_loc of
|
|
| 1946 | + -- Suggestion makes sense only for this particular case.
|
|
| 1947 | + PushedCallStackOrigin{} -> vcat [ header, suggestion ]
|
|
| 1948 | + _ -> header
|
|
| 1949 | + where
|
|
| 1950 | + header, suggestion :: SDoc
|
|
| 1951 | + header
|
|
| 1952 | + = vcat [ text "Defaulting to the empty call stack"
|
|
| 1953 | + , nest 2 $ pprCtOrigin (ctLocOrigin ct_loc) <> text "." ]
|
|
| 1954 | + suggestion
|
|
| 1955 | + = text "Add a" <+> quotes (text "HasCallStack") <+>
|
|
| 1956 | + text "constraint to the enclosing definition to extend the call stack."
|
|
| 1944 | 1957 | TcRnImplicitImportOfPrelude
|
| 1945 | 1958 | -> mkSimpleDecorated $
|
| 1946 | 1959 | text "Module" <+> quotes (text "Prelude") <+> text "implicitly imported."
|
| ... | ... | @@ -2671,6 +2684,8 @@ instance Diagnostic TcRnMessage where |
| 2671 | 2684 | -> WarningWithFlag Opt_WarnNonCanonicalMonadInstances
|
| 2672 | 2685 | TcRnDefaultedExceptionContext{}
|
| 2673 | 2686 | -> WarningWithFlag Opt_WarnDefaultedExceptionContext
|
| 2687 | + TcRnDefaultedCallStack{}
|
|
| 2688 | + -> WarningWithFlag Opt_WarnDefaultedCallStack
|
|
| 2674 | 2689 | TcRnImplicitImportOfPrelude {}
|
| 2675 | 2690 | -> WarningWithFlag Opt_WarnImplicitPrelude
|
| 2676 | 2691 | TcRnMissingMain {}
|
| ... | ... | @@ -3404,6 +3419,8 @@ instance Diagnostic TcRnMessage where |
| 3404 | 3419 | -> suggestNonCanonicalDefinition reason
|
| 3405 | 3420 | TcRnDefaultedExceptionContext _
|
| 3406 | 3421 | -> noHints
|
| 3422 | + TcRnDefaultedCallStack{}
|
|
| 3423 | + -> noHints
|
|
| 3407 | 3424 | TcRnImplicitImportOfPrelude {}
|
| 3408 | 3425 | -> noHints
|
| 3409 | 3426 | TcRnMissingMain {}
|
| ... | ... | @@ -4426,6 +4426,17 @@ data TcRnMessage where |
| 4426 | 4426 | -}
|
| 4427 | 4427 | TcRnDefaultedExceptionContext :: CtLoc -> TcRnMessage
|
| 4428 | 4428 | |
| 4429 | + {-| TcRnDefaultedCallStack is a warning that is triggered when an implicit
|
|
| 4430 | + @CallStack@ constraint is defaulted to the empty call stack because there
|
|
| 4431 | + is no enclosing @HasCallStack@ constraint to solve it from. The 'CtLoc' is
|
|
| 4432 | + the location and origin of the defaulted constraint.
|
|
| 4433 | + |
|
| 4434 | + See Note [Warn about defaulted CallStacks] in GHC.Tc.Solver.Dict.
|
|
| 4435 | + |
|
| 4436 | + Test cases: WarnDefaultedCallStack
|
|
| 4437 | + -}
|
|
| 4438 | + TcRnDefaultedCallStack :: CtLoc -> TcRnMessage
|
|
| 4439 | + |
|
| 4429 | 4440 | {-| TcRnOutOfArityTyVar is an error raised when the arity of a type synonym
|
| 4430 | 4441 | (as determined by the SAKS and the LHS) is insufficiently high to
|
| 4431 | 4442 | accommodate an implicit binding for a free variable that occurs in the
|
| ... | ... | @@ -461,7 +461,12 @@ defaultCallStack :: CtDefaultingStrategy |
| 461 | 461 | defaultCallStack ct
|
| 462 | 462 | | ClassPred cls tys <- classifyPredType (ctPred ct)
|
| 463 | 463 | , isJust (isCallStackPred cls tys)
|
| 464 | - = do { solveCallStack (ctEvidence ct) EvCsEmpty
|
|
| 464 | + = do { dflags <- getDynFlags
|
|
| 465 | + -- See Note [Warn about defaulted CallStacks] in GHC.Tc.Solver.Dict.
|
|
| 466 | + ; when (wopt Opt_WarnDefaultedCallStack dflags) $
|
|
| 467 | + do { let loc = ctLoc ct
|
|
| 468 | + ; ctLocWarnTcS loc (TcRnDefaultedCallStack loc) }
|
|
| 469 | + ; solveCallStack (ctEvidence ct) EvCsEmpty
|
|
| 465 | 470 | ; return emptyWC }
|
| 466 | 471 | | otherwise
|
| 467 | 472 | = noDefaulting ct
|
| ... | ... | @@ -25,8 +25,6 @@ import GHC.Tc.Solver.Types |
| 25 | 25 | import GHC.Tc.Utils.TcType
|
| 26 | 26 | import GHC.Tc.Utils.Unify( uType, mightEqualLater )
|
| 27 | 27 | |
| 28 | -import GHC.Hs.Type( HsIPName(..) )
|
|
| 29 | - |
|
| 30 | 28 | import GHC.Core
|
| 31 | 29 | import GHC.Core.Make
|
| 32 | 30 | import GHC.Core.Type
|
| ... | ... | @@ -55,7 +53,6 @@ import GHC.Utils.Misc |
| 55 | 53 | import GHC.Unit.Module
|
| 56 | 54 | |
| 57 | 55 | import GHC.Data.Bag
|
| 58 | -import GHC.Data.FastString
|
|
| 59 | 56 | |
| 60 | 57 | import GHC.Driver.DynFlags
|
| 61 | 58 | |
| ... | ... | @@ -121,8 +118,8 @@ canDictCt ev cls tys |
| 121 | 118 | -- so set the fuel to doNotExpand to avoid repeating expansion
|
| 122 | 119 | |
| 123 | 120 | | CtWanted (WantedCt { ctev_rewriters = rws }) <- ev
|
| 124 | - , Just ip_name <- isCallStackPred cls tys
|
|
| 125 | - , Just fun_fs <- isPushCallStackOrigin_maybe orig
|
|
| 121 | + , isJust (isCallStackPred cls tys)
|
|
| 122 | + , Just fun_fs <- isPushCallStackOrigin_maybe orig
|
|
| 126 | 123 | -- If we're given a CallStack constraint that arose from a function
|
| 127 | 124 | -- call, we need to push the current call-site onto the stack instead
|
| 128 | 125 | -- of solving it directly from a given.
|
| ... | ... | @@ -132,11 +129,13 @@ canDictCt ev cls tys |
| 132 | 129 | do { -- First we emit a new constraint that will capture the
|
| 133 | 130 | -- given CallStack.
|
| 134 | 131 | |
| 135 | - let new_loc = setCtLocOrigin loc (IPOccOrigin (HsIPName $ fastStringToShortText ip_name))
|
|
| 136 | - -- We change the origin to IPOccOrigin so
|
|
| 137 | - -- this rule does not fire again.
|
|
| 132 | + let new_loc = setCtLocOrigin loc (PushedCallStackOrigin fun_fs)
|
|
| 133 | + -- PushedCallStackOrigin solves like IPOccOrigin, so
|
|
| 134 | + -- this rule does not fire again, but retains fun_fs
|
|
| 135 | + -- for -Wdefaulted-callstack.
|
|
| 138 | 136 | -- See Note [Overview of implicit CallStacks]
|
| 139 | 137 | -- in GHC.Tc.Types.Evidence
|
| 138 | + -- and Note [Warn about defaulted CallStacks]
|
|
| 140 | 139 | |
| 141 | 140 | ; new_ev <- CtWanted <$> newWantedEvVarNC new_loc rws pred
|
| 142 | 141 | |
| ... | ... | @@ -214,6 +213,80 @@ evCallStack pred (EvCsPushCall fs loc tm) |
| 214 | 213 | ; return (mkCoreApps (Var push_cs_id)
|
| 215 | 214 | [mkCoreTup [name_expr, loc_expr], outer_stk]) }
|
| 216 | 215 | |
| 216 | +{- Note [Warn about defaulted CallStacks]
|
|
| 217 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 218 | +A call stack only records the chain of calls as long as every function in the
|
|
| 219 | +chain carries a HasCallStack constraint. When a function with a HasCallStack
|
|
| 220 | +constraint is called from a definition that does /not/ have one, the implicit
|
|
| 221 | +CallStack parameter emitted for the call cannot be solved from any enclosing
|
|
| 222 | +Given and is defaulted to the empty call stack (see Note [Overview of implicit
|
|
| 223 | +CallStacks] in GHC.Tc.Types.Evidence, point 4): the stack stops at this call
|
|
| 224 | +site, omitting the caller and everything above it.
|
|
| 225 | + |
|
| 226 | +This can be just what you want; e.g. perhaps you selectively add some
|
|
| 227 | +HasCallStack constraints to help you isolate the caller of a failing call to
|
|
| 228 | +`head`. But it can also be a source of surprise if you want complete call
|
|
| 229 | +stacks. Hence, `-Wdefaulted-callstack` reports every such defaulting point
|
|
| 230 | +(including a bare use of an implicit parameter of type CallStack that defaults).
|
|
| 231 | + |
|
| 232 | +Examples:
|
|
| 233 | + |
|
| 234 | + bad :: Int
|
|
| 235 | + bad = error "boom" -- -Wdefaulted-callstack fires: `bad` has no
|
|
| 236 | + -- HasCallStack constraint, so the call stack for the
|
|
| 237 | + -- call to `error` is defaulted to the empty stack
|
|
| 238 | + |
|
| 239 | + good :: HasCallStack => Int
|
|
| 240 | + good = error "boom" + x -- no warning: the call extends `good`'s call stack
|
|
| 241 | + where
|
|
| 242 | + x = error "splat" -- no warning either, even though `x` has no
|
|
| 243 | + -- HasCallStack constraint of its own: `good`'s
|
|
| 244 | + -- HasCallStack brings a `?callStack` Given into scope
|
|
| 245 | + -- over the whole of `good`, including its where/let
|
|
| 246 | + -- bindings, so this call is solved from that Given
|
|
| 247 | + -- (it floats up to it) and extends `good`'s stack
|
|
| 248 | + |
|
| 249 | + stk :: CallStack
|
|
| 250 | + stk = ?stk -- -Wdefaulted-callstack fires: implicit parameters
|
|
| 251 | + -- of type CallStack default too
|
|
| 252 | + |
|
| 253 | +We emit the warning from `defaultCallStack` (in GHC.Tc.Solver.Default), the one
|
|
| 254 | +and only place a CallStack is solved with the empty stack `EvCsEmpty`.
|
|
| 255 | +Defaulting runs once, at the top level (`simplifyTopWanteds`), after every
|
|
| 256 | +constraint has had the chance to float up and be solved against all enclosing
|
|
| 257 | +Givens, so a constraint that reaches it really is defaulted.
|
|
| 258 | + |
|
| 259 | +The message renders the defaulted constraint's `CtOrigin` (just like
|
|
| 260 | +`-Wdefaulted-exception-context`): for a function call (plan PUSH, see Note
|
|
| 261 | +[Overview of implicit CallStacks] in GHC.Tc.Types.Evidence, point 2) that origin
|
|
| 262 | +is `PushedCallStackOrigin fun_fs`, naming the called function; for a bare use of
|
|
| 263 | +an implicit parameter of type `CallStack` it is `IPOccOrigin`. Either way the
|
|
| 264 | +`CtLoc` points at the use site.
|
|
| 265 | + |
|
| 266 | +In cases when a HasCallStack constraint cannot be supplied using a type
|
|
| 267 | +signature (e.g. the body of `main` or a method in an instance of a class whose
|
|
| 268 | +type signature lacks a HasCallStack constraint) the user can silence the warning
|
|
| 269 | +by bringing an empty stack into scope explicitly with
|
|
| 270 | +`GHC.Stack.withEmptyCallStack`:
|
|
| 271 | + |
|
| 272 | +main :: IO ()
|
|
| 273 | +main = withEmptyCallStack $ do
|
|
| 274 | + ...
|
|
| 275 | + error "oops" -- no warning here
|
|
| 276 | + ...
|
|
| 277 | + |
|
| 278 | +Caveat (under-reporting within a single definition): identical Wanted CallStack
|
|
| 279 | +constraints are CSE'd by the constraint solver, so several defaulting call sites
|
|
| 280 | +within the /same/ definition collapse to a single warning:
|
|
| 281 | + |
|
| 282 | + twoErrors :: Int
|
|
| 283 | + twoErrors = error "a" + error "b" -- one -Wdefaulted-callstack warning
|
|
| 284 | + |
|
| 285 | +We do, however, report defaulting in /every/ top-level definition (see Note
|
|
| 286 | +[When to build an implication] in GHC.Tc.Utils.Unify). This is what counts,
|
|
| 287 | +because it allows the user to take action on all affected bindings at once.
|
|
| 288 | +-}
|
|
| 289 | + |
|
| 217 | 290 | {- Note [Solving CallStack constraints]
|
| 218 | 291 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 219 | 292 | See Note [Overview of implicit CallStacks] in GHc.Tc.Types.Evidence.
|
| ... | ... | @@ -231,7 +304,7 @@ Suppose f :: HasCallStack => blah. Then |
| 231 | 304 | pushing the call-site info on the stack, and changing the CtOrigin
|
| 232 | 305 | to record that has been done.
|
| 233 | 306 | Bind: s1 = pushCallStack <site-info> s2
|
| 234 | - [W] s2 :: IP "callStack" CallStack -- CtOrigin = IPOccOrigin
|
|
| 307 | + [W] s2 :: IP "callStack" CallStack -- CtOrigin = PushedCallStackOrigin f
|
|
| 235 | 308 | |
| 236 | 309 | * Then, and only then, we can solve the constraint from an enclosing
|
| 237 | 310 | Given.
|
| ... | ... | @@ -1137,7 +1137,7 @@ implicit parameter is not important, see (CS5) below) are solved as follows: |
| 1137 | 1137 | We do /not/ solve this constraint from Givens, or from other
|
| 1138 | 1138 | Wanteds. Rather, have a built-in mechanism in that solves it thus:
|
| 1139 | 1139 | d := EvCsPushCall "foo" <details of call-site of `foo`> d2
|
| 1140 | - [W] d2 :: (?stk :: CallStack) CtOrigin = IPOccOrigin
|
|
| 1140 | + [W] d2 :: (?stk :: CallStack) CtOrigin = PushedCallStackOrigin "foo"
|
|
| 1141 | 1141 | |
| 1142 | 1142 | That is, `d` is a call-stack that has the `foo` call-site pushed on top of
|
| 1143 | 1143 | `d2`, which can now be solved normally (as in (1) above). This is done as follows:
|
| ... | ... | @@ -1148,6 +1148,9 @@ implicit parameter is not important, see (CS5) below) are solved as follows: |
| 1148 | 1148 | |
| 1149 | 1149 | * solve it normally (plan NORMAL above)
|
| 1150 | 1150 | - IPOccOrigin (discussed above)
|
| 1151 | + - PushedCallStackOrigin (the new Wanted emitted by plan PUSH; behaves
|
|
| 1152 | + like IPOccOrigin but retains the function name for
|
|
| 1153 | + -Wdefaulted-callstack, see Note [Warn about defaulted CallStacks])
|
|
| 1151 | 1154 | - GivenOrigin (see (CS1) below)
|
| 1152 | 1155 | |
| 1153 | 1156 | * push an item on the stack and emit a new constraint (plan PUSH above)
|
| ... | ... | @@ -1189,6 +1192,10 @@ the resulting CallStack will include the call to `undefined` in `head` |
| 1189 | 1192 | and the call to `error` in `undefined`, but *not* the call to `head`
|
| 1190 | 1193 | in `g`, because `head` did not explicitly request a CallStack.
|
| 1191 | 1194 | |
| 1195 | +The `-Wdefaulted-callstack` warning flags exactly these points where the stack
|
|
| 1196 | +is defaulted to empty (here, the call to `undefined` in `head`). See
|
|
| 1197 | +Note [Warn about defaulted CallStacks] in GHC.Tc.Solver.Dict.
|
|
| 1198 | + |
|
| 1192 | 1199 | |
| 1193 | 1200 | Wrinkles
|
| 1194 | 1201 | |
| ... | ... | @@ -1240,11 +1247,14 @@ Wrinkles |
| 1240 | 1247 | call-site onto a given stack (See GHC.HsToCore.Binds.dsEvCallStack)
|
| 1241 | 1248 | |
| 1242 | 1249 | (CS7) When we emit a new wanted CallStack in plan PUSH we set its origin to
|
| 1243 | - `IPOccOrigin ip_name` instead of the original `OccurrenceOf func`
|
|
| 1244 | - (see GHC.Tc.Solver.Dict.tryInertDicts).
|
|
| 1245 | - |
|
| 1246 | - This is a bit shady, but is how we ensure that the new wanted is
|
|
| 1247 | - solved like a regular IP.
|
|
| 1250 | + `PushedCallStackOrigin func` instead of the original `OccurrenceOf func`
|
|
| 1251 | + (see GHC.Tc.Solver.Dict.canDictCt).
|
|
| 1252 | + |
|
| 1253 | + This is a bit shady, but is how we ensure that the new wanted is solved like
|
|
| 1254 | + a regular IP (isPushCallStackOrigin_maybe returns Nothing for it, as for
|
|
| 1255 | + IPOccOrigin). Unlike IPOccOrigin it retains the called function's name, which
|
|
| 1256 | + -Wdefaulted-callstack uses if the stack is ultimately defaulted to empty.
|
|
| 1257 | + See Note [Warn about defaulted CallStacks] in GHC.Tc.Solver.Dict.
|
|
| 1248 | 1258 | -}
|
| 1249 | 1259 | |
| 1250 | 1260 | mkEvScSelectors -- Assume class (..., D ty, ...) => C a b
|
| ... | ... | @@ -412,6 +412,13 @@ data CtOrigin |
| 412 | 412 | CtOrigin -- CtOrigin of the original type equality
|
| 413 | 413 | |
| 414 | 414 | | IPOccOrigin HsIPName -- Occurrence of an implicit parameter
|
| 415 | + | PushedCallStackOrigin FastString
|
|
| 416 | + -- ^ The Wanted CallStack emitted by plan PUSH (see Note [Overview of
|
|
| 417 | + -- implicit CallStacks] in GHC.Tc.Types.Evidence) when a call site for the
|
|
| 418 | + -- named function is pushed onto the call stack. Solved like
|
|
| 419 | + -- 'IPOccOrigin', but retains the function name so that
|
|
| 420 | + -- @-Wdefaulted-callstack@ can report which call had its stack defaulted.
|
|
| 421 | + -- See Note [Warn about defaulted CallStacks] in GHC.Tc.Solver.Dict.
|
|
| 415 | 422 | | OverLabelOrigin FastString -- Occurrence of an overloaded label
|
| 416 | 423 | |
| 417 | 424 | | LiteralOrigin (HsOverLit GhcRn) -- Occurrence of a literal
|
| ... | ... | @@ -786,6 +793,7 @@ ppr_br (OccurrenceOf name) = hsep [text "a use of", quotes (ppr name)] |
| 786 | 793 | ppr_br (OccurrenceOfRecSel name) = hsep [text "a use of", quotes (ppr name)]
|
| 787 | 794 | ppr_br AppOrigin = text "an application"
|
| 788 | 795 | ppr_br (IPOccOrigin name) = hsep [text "a use of implicit parameter", quotes (ppr name)]
|
| 796 | +ppr_br (PushedCallStackOrigin fs) = hsep [text "a use of", quotes (ftext fs)]
|
|
| 789 | 797 | ppr_br (OverLabelOrigin l) = hsep [text "the overloaded label"
|
| 790 | 798 | ,quotes (char '#' <> ppr l)]
|
| 791 | 799 | ppr_br (RecordUpdOrigin {}) = text "a record update"
|
| ... | ... | @@ -897,6 +905,7 @@ foldMapCtOrigin f = go |
| 897 | 905 | SpecPragOrigin {} -> f orig
|
| 898 | 906 | TypeEqOrigin {}-> f orig
|
| 899 | 907 | IPOccOrigin {} -> f orig
|
| 908 | + PushedCallStackOrigin {} -> f orig
|
|
| 900 | 909 | OverLabelOrigin {} -> f orig
|
| 901 | 910 | LiteralOrigin {} -> f orig
|
| 902 | 911 | QualLiteralOrigin {} -> f orig
|
| ... | ... | @@ -978,6 +987,7 @@ isPushCallStackOrigin_maybe :: CtOrigin -> Maybe FastString |
| 978 | 987 | isPushCallStackOrigin_maybe (GivenOrigin {}) = Nothing
|
| 979 | 988 | isPushCallStackOrigin_maybe (GivenSCOrigin {}) = Nothing
|
| 980 | 989 | isPushCallStackOrigin_maybe (IPOccOrigin {}) = Nothing
|
| 990 | +isPushCallStackOrigin_maybe (PushedCallStackOrigin {}) = Nothing
|
|
| 981 | 991 | isPushCallStackOrigin_maybe (OccurrenceOf fun) = Just (occNameFS (getOccName fun))
|
| 982 | 992 | isPushCallStackOrigin_maybe orig = Just orig_fs
|
| 983 | 993 | -- This fall-through case is important to deal with call stacks
|
| ... | ... | @@ -587,7 +587,8 @@ implicationNeeded skol_info skol_tvs given |
| 587 | 587 | -- we must build an implication
|
| 588 | 588 | ; return (gopt Opt_DeferTypeErrors dflags ||
|
| 589 | 589 | gopt Opt_DeferTypedHoles dflags ||
|
| 590 | - gopt Opt_DeferOutOfScopeVariables dflags) } }
|
|
| 590 | + gopt Opt_DeferOutOfScopeVariables dflags ||
|
|
| 591 | + wopt Opt_WarnDefaultedCallStack dflags ) } }
|
|
| 591 | 592 | |
| 592 | 593 | | otherwise -- Non-empty skolems or givens
|
| 593 | 594 | = return True -- Definitely need an implication
|
| ... | ... | @@ -676,6 +677,14 @@ take care: |
| 676 | 677 | literally nothing to do with each other. #14185 is an example.
|
| 677 | 678 | Building an implication keeps them separate.
|
| 678 | 679 | |
| 680 | +* If -Wdefaulted-callstack is on, we build an implication around each top-level
|
|
| 681 | + binding so that their implicit CallStack parameters are solved (and hence
|
|
| 682 | + defaulted) in isolation. Otherwise each top-level binding's wanteds float
|
|
| 683 | + into a single pool and end up CSE'd, so only one of them reaches
|
|
| 684 | + `defaultCallStack` where the warning is generated; the per-binding implication
|
|
| 685 | + lets us report every top-level definition that defaults its call stack. See
|
|
| 686 | + also Note [Warn about defaulted CallStacks] in GHC.Tc.Solver.Dict.
|
|
| 687 | + |
|
| 679 | 688 | Note [Herald for matchExpectedFunTys]
|
| 680 | 689 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 681 | 690 | The 'herald' always looks like:
|
| ... | ... | @@ -676,6 +676,7 @@ type family GhcDiagnosticCode c = n | n -> c where |
| 676 | 676 | GhcDiagnosticCode "NonCanonicalMonoid" = 50928
|
| 677 | 677 | GhcDiagnosticCode "NonCanonicalMonad" = 22705
|
| 678 | 678 | GhcDiagnosticCode "TcRnDefaultedExceptionContext" = 46235
|
| 679 | + GhcDiagnosticCode "TcRnDefaultedCallStack" = 39361
|
|
| 679 | 680 | GhcDiagnosticCode "TcRnImplicitImportOfPrelude" = 20540
|
| 680 | 681 | GhcDiagnosticCode "TcRnMissingMain" = 67120
|
| 681 | 682 | GhcDiagnosticCode "TcRnGhciUnliftedBind" = 17999
|
| ... | ... | @@ -2619,7 +2619,7 @@ of ``-W(no-)*``. |
| 2619 | 2619 | implicit parameter is defaulted to
|
| 2620 | 2620 | :base-ref:`Control.Exception.Context.emptyExceptionContext`.
|
| 2621 | 2621 | :type: dynamic
|
| 2622 | - :reverse: -Wnop-defaulted-exception-context
|
|
| 2622 | + :reverse: -Wno-defaulted-exception-context
|
|
| 2623 | 2623 | |
| 2624 | 2624 | :since: 9.10.1
|
| 2625 | 2625 | |
| ... | ... | @@ -2631,6 +2631,42 @@ of ``-W(no-)*``. |
| 2631 | 2631 | evidence is available. As this behavior may result in dropped exception context
|
| 2632 | 2632 | this warning is provided to give notice when defaulting occurs.
|
| 2633 | 2633 | |
| 2634 | +.. ghc-flag:: -Wdefaulted-callstack
|
|
| 2635 | + :shortdesc: warn when an implicit :base-ref:`GHC.Stack.CallStack` parameter
|
|
| 2636 | + is defaulted to the empty stack.
|
|
| 2637 | + :type: dynamic
|
|
| 2638 | + :reverse: -Wno-defaulted-callstack
|
|
| 2639 | + |
|
| 2640 | + :since: 10.2.1
|
|
| 2641 | + |
|
| 2642 | + When a function with a :base-ref:`GHC.Stack.HasCallStack` constraint is
|
|
| 2643 | + called from a definition that does *not* provide one, the implicit
|
|
| 2644 | + :base-ref:`GHC.Stack.CallStack` parameter is defaulted to the empty stack,
|
|
| 2645 | + so at such call sites the call stack is cut off and does not include the
|
|
| 2646 | + enclosing definition's callers.
|
|
| 2647 | + |
|
| 2648 | + This might be desirable; e.g. perhaps the user selectively added some
|
|
| 2649 | + :base-ref:`GHC.Stack.HasCallStack` constraints to help isolate the caller of
|
|
| 2650 | + a failing call to ``head``. But it can also be a source of surprise if the
|
|
| 2651 | + user wants complete call stacks. Hence, ``-Wdefaulted-callstack`` (off by
|
|
| 2652 | + default) reports every such defaulting point (including a bare use of an
|
|
| 2653 | + implicit parameter of type :base-ref:`GHC.Stack.CallStack` that defaults).
|
|
| 2654 | + |
|
| 2655 | + In cases when a :base-ref:`GHC.Stack.HasCallStack` constraint cannot be
|
|
| 2656 | + supplied using a type signature (e.g. the body of ``main`` or a method in an
|
|
| 2657 | + instance of a class whose type signature lacks a
|
|
| 2658 | + :base-ref:`GHC.Stack.HasCallStack` constraint), the user can silence the
|
|
| 2659 | + warning by bringing an empty stack into scope explicitly with
|
|
| 2660 | + :base-ref:`GHC.Stack.withEmptyCallStack`:
|
|
| 2661 | + |
|
| 2662 | + .. code-block:: haskell
|
|
| 2663 | + |
|
| 2664 | + main :: IO ()
|
|
| 2665 | + main = withEmptyCallStack $ do
|
|
| 2666 | + ...
|
|
| 2667 | + error "oops" -- no warning here
|
|
| 2668 | + ...
|
|
| 2669 | + |
|
| 2634 | 2670 | .. ghc-flag:: -Wview-pattern-signatures
|
| 2635 | 2671 | :shortdesc: warn when a view pattern is used with type signature without
|
| 2636 | 2672 | explicit parens
|
| ... | ... | @@ -8,6 +8,7 @@ |
| 8 | 8 | * Ensure that `Data.List.elem` and `notElem` can be specialized even when no list fusion happens. ([CLC proposal #412)(https://github.com/haskell/core-libraries-committee/issues/412))
|
| 9 | 9 | * Introduce `Data.Double` and `Data.Float` modules. ([CLC proposal #378](https://github.com/haskell/core-libraries-committee/issues/378))
|
| 10 | 10 | * Change `Generically a`'s `Monoid` definition to require a `Semigroup` constraint, and define its `mconcat` using `(<>)` from that constraint. ([CLC proposal #413](https://github.com/haskell/core-libraries-committee/issues/413))
|
| 11 | + * Add `withEmptyCallStack` to `GHC.Stack`. ([CLC proposal #428](https://github.com/haskell/core-libraries-committee/issues/428))
|
|
| 11 | 12 | |
| 12 | 13 | ## 4.23.0.0 *TBA*
|
| 13 | 14 | * Add `System.IO.hGetNewlineMode`. ([CLC proposal #370](https://github.com/haskell/core-libraries-committee/issues/370))
|
| ... | ... | @@ -31,6 +31,7 @@ module GHC.Stack |
| 31 | 31 | prettyCallStack,
|
| 32 | 32 | pushCallStack,
|
| 33 | 33 | withFrozenCallStack,
|
| 34 | + withEmptyCallStack,
|
|
| 34 | 35 | -- * Source locations
|
| 35 | 36 | SrcLoc(..),
|
| 36 | 37 | prettySrcLoc,
|
| ... | ... | @@ -49,4 +50,4 @@ module GHC.Stack |
| 49 | 50 | renderStack
|
| 50 | 51 | ) where
|
| 51 | 52 | |
| 52 | -import GHC.Internal.Stack |
|
| \ No newline at end of file | ||
| 53 | +import GHC.Internal.Stack |
| ... | ... | @@ -29,7 +29,7 @@ module GHC.Internal.Stack ( |
| 29 | 29 | -- * HasCallStack call stacks
|
| 30 | 30 | CallStack, HasCallStack, callStack, emptyCallStack, freezeCallStack,
|
| 31 | 31 | fromCallSiteList, getCallStack, popCallStack,
|
| 32 | - pushCallStack, withFrozenCallStack,
|
|
| 32 | + pushCallStack, withFrozenCallStack, withEmptyCallStack,
|
|
| 33 | 33 | prettyCallStackLines, prettyCallStack,
|
| 34 | 34 | |
| 35 | 35 | -- * Source locations
|
| ... | ... | @@ -105,6 +105,23 @@ withFrozenCallStack do_this = |
| 105 | 105 | let ?callStack = freezeCallStack (popCallStack callStack)
|
| 106 | 106 | in do_this
|
| 107 | 107 | |
| 108 | +-- | Explicitly bring the empty call stack into scope.
|
|
| 109 | +--
|
|
| 110 | +-- Mostly useful for silencing warnings generated by @-Wdefaulted-callstack@ in
|
|
| 111 | +-- places such as:
|
|
| 112 | +--
|
|
| 113 | +-- - The body of a class method in an instance of an externally defined type
|
|
| 114 | +-- class whose type signature doesn't contain a 'HasCallStack' constraint.
|
|
| 115 | +--
|
|
| 116 | +-- - The body of the @main@ function.
|
|
| 117 | +--
|
|
| 118 | +-- @since 4.24.0.0
|
|
| 119 | +withEmptyCallStack :: (HasCallStack => a) -> a
|
|
| 120 | +withEmptyCallStack do_this =
|
|
| 121 | + -- See Note [Warn about defaulted CallStacks]
|
|
| 122 | + let ?callStack = emptyCallStack
|
|
| 123 | + in do_this
|
|
| 124 | + |
|
| 108 | 125 | -- prettySrcLoc and prettyCallStack are defined here to avoid hs-boot
|
| 109 | 126 | -- files. See Note [Definition of CallStack]
|
| 110 | 127 |
| 1 | +{-# LANGUAGE ImplicitParams #-}
|
|
| 2 | +module WarnDefaultedCallStack where
|
|
| 3 | + |
|
| 4 | +import GHC.Stack
|
|
| 5 | + |
|
| 6 | +intCs :: HasCallStack => Int
|
|
| 7 | +intCs = 0
|
|
| 8 | + |
|
| 9 | +topLevelNoWarning :: HasCallStack => Int
|
|
| 10 | +topLevelNoWarning = intCs
|
|
| 11 | + |
|
| 12 | +outerNoWarning :: HasCallStack => IO ()
|
|
| 13 | +outerNoWarning = innerNoWarning (1000::Int)
|
|
| 14 | + where
|
|
| 15 | + innerNoWarning = \case
|
|
| 16 | + 0 -> error "inner" -- gets CallStack from outerNoWarning
|
|
| 17 | + n -> innerNoWarning $ n - 1
|
|
| 18 | + |
|
| 19 | +topLevelExplicitEmptyCallStackNoWarning :: IO ()
|
|
| 20 | +topLevelExplicitEmptyCallStackNoWarning = withEmptyCallStack $ do
|
|
| 21 | + print $ intCs + localWarns
|
|
| 22 | + where
|
|
| 23 | + -- No enclosing CallStack, intCs warns.
|
|
| 24 | + localWarns = intCs + localNoWarning
|
|
| 25 | + |
|
| 26 | + -- Implicit parameters of type CallStack also default.
|
|
| 27 | + implicitWarns :: CallStack
|
|
| 28 | + implicitWarns = ?other
|
|
| 29 | + |
|
| 30 | + localNoWarning :: HasCallStack => Int
|
|
| 31 | + localNoWarning = intCs + nestedNoWarning
|
|
| 32 | + where
|
|
| 33 | + nestedNoWarning = intCs -- gets CallStack from localNoWarn
|
|
| 34 | + |
|
| 35 | +topLevelWarns :: IO ()
|
|
| 36 | +topLevelWarns = print intCs
|
|
| 37 | + |
|
| 38 | +separateTopLevelWarns :: Int
|
|
| 39 | +separateTopLevelWarns = topLevelNoWarning
|
|
| 40 | + |
|
| 41 | +withinDefUnderReports :: Int
|
|
| 42 | +withinDefUnderReports =
|
|
| 43 | + -- Only one warning reported here, the other absent due to a CSE'd wanted.
|
|
| 44 | + intCs + intCs |
| 1 | +WarnDefaultedCallStack.hs:24:18: warning: [GHC-39361] [-Wdefaulted-callstack]
|
|
| 2 | + Defaulting to the empty call stack
|
|
| 3 | + arising from a use of ‘intCs’.
|
|
| 4 | + Add a ‘HasCallStack’ constraint to the enclosing definition to extend the call stack.
|
|
| 5 | + |
|
| 6 | +WarnDefaultedCallStack.hs:28:21: warning: [GHC-39361] [-Wdefaulted-callstack]
|
|
| 7 | + Defaulting to the empty call stack
|
|
| 8 | + arising from a use of implicit parameter ‘?other’.
|
|
| 9 | + |
|
| 10 | +WarnDefaultedCallStack.hs:36:23: warning: [GHC-39361] [-Wdefaulted-callstack]
|
|
| 11 | + Defaulting to the empty call stack
|
|
| 12 | + arising from a use of ‘intCs’.
|
|
| 13 | + Add a ‘HasCallStack’ constraint to the enclosing definition to extend the call stack.
|
|
| 14 | + |
|
| 15 | +WarnDefaultedCallStack.hs:39:25: warning: [GHC-39361] [-Wdefaulted-callstack]
|
|
| 16 | + Defaulting to the empty call stack
|
|
| 17 | + arising from a use of ‘topLevelNoWarning’.
|
|
| 18 | + Add a ‘HasCallStack’ constraint to the enclosing definition to extend the call stack.
|
|
| 19 | + |
|
| 20 | +WarnDefaultedCallStack.hs:44:3: warning: [GHC-39361] [-Wdefaulted-callstack]
|
|
| 21 | + Defaulting to the empty call stack
|
|
| 22 | + arising from a use of ‘intCs’.
|
|
| 23 | + Add a ‘HasCallStack’ constraint to the enclosing definition to extend the call stack. |
| ... | ... | @@ -926,6 +926,7 @@ test('T21206', normal, compile, ['']) |
| 926 | 926 | test('T17594a', req_th, compile, [''])
|
| 927 | 927 | test('T17594f', normal, compile, [''])
|
| 928 | 928 | test('WarnDefaultedExceptionContext', normal, compile, ['-Wdefaulted-exception-context'])
|
| 929 | +test('WarnDefaultedCallStack', normal, compile, ['-Wdefaulted-callstack'])
|
|
| 929 | 930 | test('T24470b', normal, compile, [''])
|
| 930 | 931 | test('T24566', [], makefile_test, [])
|
| 931 | 932 | test('T23764', normal, compile, [''])
|