{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreicbuv7g2s7c3lrdzovwqim6go273b7a6vu7i3iywi3ls5skw3zitu",
"uri": "at://did:plc:pi6woz4d47bkuws673w2il2r/app.bsky.feed.post/3mpjec6rge4q2"
},
"path": "/t/clc-proposals-rfc/14334#post_3",
"publishedAt": "2026-06-30T14:43:47.000Z",
"site": "https://discourse.haskell.org",
"tags": [
"github.com/haskell/core-libraries-committee",
"Add withEmptyCallStack to GHC.Stack (part of the new -Wdefaulted-callstack GHC warning)",
"arybczak",
"@-Wdefaulted-callstack",
"@main"
],
"textContent": "github.com/haskell/core-libraries-committee\n\n#### Add withEmptyCallStack to GHC.Stack (part of the new -Wdefaulted-callstack GHC warning)\n\nopened 04:03PM - 21 Jun 26 UTC\n\n\n\n arybczak\n \n\nThis is a small part of https://gitlab.haskell.org/ghc/ghc/-/merge_requests/1617…4 that needs a CLC proposal since it modifies `base`. To recap: this MR adds a new warning `-Wdefaulted-callstack` (disabled by default) which warns the user about calls to functions that include `HasCallStack` constraint in scope where this constraint is not available, i.e. it's implicitly defaulted to the empty stack. This is somewhat similar to the [require-callstack](https://hackage.haskell.org/package/require-callstack) library, except usage of require-callstack needs code change (using [`RequireCallStack`](https://hackage.haskell.org/package/require-callstack-0.2.0.1/docs/RequireCallStack.html#t:RequireCallStack) instead of `HasCallStack`) and forces all downstream users to explicitly use [`provideCallStack`](https://hackage.haskell.org/package/require-callstack-0.2.0.1/docs/RequireCallStack.html#v:provideCallStack) to discharge it, which will usually be too heavy of a cost (I considered using require-callstack in some of my packages, but ultimately decided against it for these reasons). `-Wdefaulted-callstack` solves this problem, because now you can ensure that your library propagates `HasCallStack` constraints properly within your package, while it will continue to work as usual for people who don't bother with call stacks for whatever reason. However, if the warning is enabled project-wide (which is what you want if you want to ensure good call stack propagation), for it to be usable it needs the addition of the following function to GHC.Stack: ```haskell -- | Explicitly bring the empty call stack into scope. -- -- Mostly useful for silencing warnings generated by @-Wdefaulted-callstack@ in -- places such as: -- -- - The body of a class method in an instance of an externally defined type -- class whose type signature doesn't contain a 'HasCallStack' constraint. -- -- - The body of the @main@ function. withEmptyCallStack :: (HasCallStack => a) -> a withEmptyCallStack do_this = let ?callStack = emptyCallStack in do_this ``` It's needed to suppress the warning in the two cases haddock describes. For the record, the first case describes the following scenario: External package: ```haskell module External class C a where foo :: a -> IO () ``` My package: ```haskell {-# OPTIONS_GHC -Wdefaulted-callstack #-} module Local where import External data X = X instance C X where -- Call to `error` emits the warning, no way to eliminate -- since I don't control type signature of `foo`. foo X = error \"x\" ``` It needs to be ```haskell instance C X where foo X = withEmptyCallStack $ do -- no warning here error \"x\" ``` This is a small function (its usage in scope without `HasCallStack` compiles to the same code GHC would generate without it, it simply makes the empty call stack defaulting explicit) with a very distinct name (hoogle finds no such functions in stackage packages), so I hope there will be no issues with including it.",
"title": "CLC proposals RFC"
}