Repository navigation
feat(hardhat-slang): slang stack traces via debugSymbols, solidityVersion in settings - #8691
Merged
Merged
Conversation
The slang compiler emits no solc AST, so EDR builds slang stack traces from the per-source debugSymbols table next to the DWARF debugInfo. Without it EDR loads the build info but every frame is an unrecognized contract. It is a file-level output, so it goes under `["*"][""]`, and, like debugInfo, into the resolved config so the build-id hash covers it.
Builds the with-debug-info fixture with the slang profile, reverts in Counter._checkPositive over a network connection, and checks the error stack names the Solidity frames. It needs a pinned release that emits debugSymbols (solx #786) and an EDR that reads them (EDR #1811), so it is gated on HARDHAT_SLANG_EXPECT_STACK_TRACES like the debugInfo test. With EDR 0.22.0, network.connect() fails with "Failed to process AST"; with EDR #1811 and solx #786 at 1cc6ed70 via `path`, it passes.
slang takes the Solidity version to compile as from `settings.solidityVersion` in standard JSON (solx #787) and rejects `--solidity-version` next to `--standard-json`. Setting it in the resolved config puts it in the solcInput, so a build info reproduces its compile on its own and the build id tells two versions apart. The release row's `targetVersionFlag` and the compiler's `targetSolidityVersion` have no remaining use. A binary without #787, like the pinned prerelease, ignores the key.
|
The 2026-10-01 prerelease predates debugSymbols, so with the stack-trace selectors every slang compile failed on "unknown variant debugSymbols", and it ignored settings.solidityVersion. 5e6ec5e1 carries DWARF, the ABI, debugSymbols and solidityVersion, and publishes its binaries as slang-*, so the asset prefix follows. The debugInfo test no longer needs its opt-in since the pin emits it. A new test compiles through the plugin and then reruns the job's input at 0.8.20: slang refuses the ^0.8.34 pragma there, which the old binary, reading no solidityVersion, compiled.
The settings.solidityVersion default also runs on override entries, whose version can differ from the profile's compilers; only the compilers had a test.
Hardhat picks a compiler entry by matching pragmas against its version, and the plugin passes that version to slang as settings.solidityVersion. A user value that differs would make slang compile a language version Hardhat didn't choose, and the plugin overwrote it silently. It is now a config error at the setting's path; an equal value is harmless and accepted. Entries with their own binary are checked too, since the setting reaches whatever binary compiles them.
Hardhat requests `ast` from every compiler, but slang's AST is not the solc AST its consumers read: EDR builds slang stack traces from debugSymbols, and the EIP-712 collector skips anything that isn't a solc SourceUnit. On OpenZeppelin it is 60 of the 77 MB slang returns, and leaving it out saves ~2.4 s of Hardhat parsing and writing the output (18.0 s -> 14.3 s cold, local). compile() drops it from the input it hands the binary rather than from the job's input: Hardhat appends its default selection when it builds that input, and the hook that could change it is deprecated. The build info's input therefore still lists `ast`; its output has none.
marianfe
reviewed
Oct 16, 2026
marianfe
approved these changes
Oct 16, 2026
marianfe
left a comment
Contributor
There was a problem hiding this comment.
lgtm with one minor comment , thanks!
The validation error already explains a mismatched solidityVersion; the README sentence confused more than it helped (review on #8691).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Claude summary
Slang stack traces end to end, and the Solidity version passed the way slang now expects it. EDR builds slang stack traces from two compiler outputs, the DWARF
debugInfothe plugin already requests and the per-sourcedebugSymbolstable (NomicFoundation/solx#786), which stands in for the solc AST. This adds the second one, and pins the first slang prerelease that emits everything EDR reads.Commits
feat:augmentIfSlangaddsdebugSymbolsto the file-level["*"][""]selectors, next toast, so it reaches the solcInput and the build-id hash like the other defaults.addSlangDebugInfoSelectorsbecomesaddSlangStackTraceSelectors, since it now covers both outputs.test: builds thewith-debug-infofixture with the slang profile, reverts inCounter._checkPositiveover a network connection, and checks the error stack names the Solidity frames. It needs a release that emitsdebugSymbolsand an EDR that reads them, so it is gated onHARDHAT_SLANG_EXPECT_STACK_TRACES, like thedebugInfotest.feat:augmentIfSlangsetssettings.solidityVersionto the entry'sversion. slang reads the version from standard JSON since feat(slang): add a Solidity version setting solx#787 and rejects--solidity-versionnext to--standard-json("Solidity version must be passed via standard JSON input."). In the solcInput, a build info reproduces its compile on its own and the build id tells two versions apart.targetVersionFlagon the release row andtargetSolidityVersiononSlangCompilergo, with their three tests. The prerelease pinned at this point ignores the key; commit 4 pins one that reads it.feat: pins0.1.0-pre.2026-10-14, solx prerelease5e6ec5e1(slang v0.2.0, Solidity 0.8.0 to 0.8.37), which carries Use custom error for http provider errors #767, Update Buidler EVM to support solc >= 0.6.9 #702, add buidler-log-remover to plugin list #786 and Improvements of multi-solc implementation #787. Its binaries are published asslang-*, so the platform asset prefix follows. The debugInfo test loses its opt-in now that the pin emits it, and runs like hardhat-slang-solx's real-binary test. A new test compilesCounter.solthrough the plugin at its entry's version, then reruns the same input at0.8.20, which slang must refuse for^0.8.34.test: an override entry gets thesolidityVersionof its ownversion, not the profile's.feat: a usersettings.solidityVersionthat differs from the entry'sversionis a config error at that setting's path. Hardhat picks the entry by matching pragmas againstversion, so a different value would compile a language version Hardhat didn't choose; until now the plugin overwrote it silently. An equal value is accepted. Entries with their own binary (path) are checked too.perf:SlangCompiler.compileleavesastout of the selection it hands the binary. Hardhat requests it from every compiler, but slang's AST isn't the solc AST any consumer reads (EDR usesdebugSymbols; the EIP-712 collector skips non-solc ASTs). On OpenZeppelin it is 60 of the 77 MB slang returns, and dropping it takes a local cold compile from 18.0 s to 14.3 s. It is dropped at compile time because Hardhat appends its default selection when building the job's input and the hook that could change that is deprecated, so the build info's input still listsastwhile its output has none.docs: the README no longer tells users to leavesettings.solidityVersionunset; commit 6's validation error says so where it matters.What it takes to turn on
debugSymbolsoutput5e6ec5e1compilerType: "slang"build infos@nomicfoundation/edrbumppackages/hardhathardhat-slang'speerDependencies.hardhatfloor,^3.15.0todaypackages/hardhat-slangUntil the EDR bump, a slang build info breaks every network connection, not just stack traces: EDR 0.23.0 does not know
"slang"and falls back to the solc path. This is already the case onmain(network.connect()throwsFailed to parse build info: missing field 'abi'); with this PR the error namesastinstead, so merging it ahead of the bump changes no working setup. On EDR 0.22.0, Solidity tests still ran and printed the error as a stack-trace warning.Verification
Local run with the pinned release downloaded by the plugin, and EDR#1811 at
0438a27dc(napi build linked intopackages/hardhat):hardhat test solidityStack Trace Warning: Failed to process ASTnetwork.connect()throwsFailed to process ASTCounter._checkPositive (contracts/Counter.sol:13)←Counter.set (contracts/Counter.sol:8)←CounterTest.testSetZeroReverts (contracts/Counter.t.sol:9)SolidityErrorwith the same twoCounterframesThe Solidity-test row used a throwaway
Counter.t.solin thewith-debug-infofixture.pnpm testinpackages/hardhat-slang: 121 pass. Each new test was seen failing first:unknown variant debugSymbols). Run directly, that binary compiles^0.8.34at0.8.20, which is what the test's last assertion rules out;solidityVersionline inaugmentIfSlang, and commit 6's two rejection tests without its check;compile, which forwarded the input unchanged.HARDHAT_SLANG_EXPECT_STACK_TRACES=trueagainst EDR#1811, and fails on EDR 0.22.0.HARDHAT_RUN_MIRROR_TESTS=true: every asset and checksum of the new pin is served.main(a90e19617), the gated stack-trace test passes with an napi build of EDRmain1da28b28aand fails on Hardhat's EDR 0.23.0. With the pinned release, every source gets adebugSymbolstable, including pragma-only, free-function-only and interface-only files, so EDR's new error for a source without one does not fire on plugin output.pnpm lintandpnpm buildclean.Notes for review
5e6ec5e1's release name ends indebug-fast; the plugin only uses it as the asset suffix.HARDHAT_DISABLE_SLOW_TESTSis set.