fix standalone comptime diagnostics - #27683
Open
medvednikov wants to merge 1 commit into
Open
Conversation
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.
What changed
$embed_file(...)expressions, including parenthesized forms, parenthesizedif/matchresult forms, selectors rooted in$embed_file(...), and discarded field selections after embed-producingor {}/lockfallbacks, with the existingexpression evaluated but not usedparser diagnostic instead of letting discarded embedded data reach later stages.$embed_file(...)under value-only wrappers such as infix expressions, containers, casts, selectors, string interpolations, attachedor {}fallbacks, lock bodies, and nested value-result branches, instead of only checking expressions rooted directly at$embed_file(...).$embed_file(...)values when they are actually consumed as final values ofif/matchexpression branches, usedor {}fallbacks, single-expressionunsafe { ... }results, and value-producinglock/rlockexpressions.unsafe {}result context to nested value-producingif/matchexpressions andor {}fallbacks inside that unsafe block.or {}handlers, unused unsafe statements, unused lock statements, discarded selector-only postfix chains, newline-separated pseudo-calls, and non-final nested branch statements still reject discarded$embed_file(...)values.if/matchresults consumed by outer operators, parenthesized nestedif/matchresults consumed by postfix calls, and unused call statements whose receiver is a parenthesized branch value.lock/rlockresult values used as postfix call receivers, e.g.(rlock s { ... }).to_string().or {}blocks, braced literals, braced literals passed as call arguments, called anonymous function bodies, nested branch expressions,unsafe {}blocks, andlock/rlockbodies while locating the real body of nestedif/matchresult expressions.$dbg;through generatedmain, including when it appears inside an initial comptime$ifor$matchbranch, while still rejecting debugger statements outside functions in non-script contexts.$embed_filediagnostics, valid branch/or/unsafe/lock result values, nested condition lookahead cases, nested value constructs inside used unsafe results, condition literal argument delimiters, parenthesized unused branch expressions, selectors rooted in embeds, discarded field selections after embed fallbacks, wrapped selector fallbacks, wrapped lock selectors, parenthesized lock postfix calls, parenthesized nested branch postfix calls, unused parenthesized branch receiver calls, newline-separated selector/call lookalikes, infix expressions and string interpolations hiding discarded embeds, and leading script debugger wrapping.Root cause
The parser previously allowed direct
$...expression statements too broadly, so a discarded$embed_file(...)could survive parsing and fail later. The new diagnostic needs to distinguish real value-result contexts from any arbitrary following}. The parser now tracks the exact scopes where a final expression value is consumed, includingif/matchbranches, usedor {}handlers, used single-expressionunsafe {}bodies, and usedlock/rlockbodies. Nested scopes only inherit that state when their expression is the actual result expression.expr_no_value()reparses parenthesized contents withp.expr(0), soexpecting_valuealone is not reliable inside an unused parenthesized statement. Value-use detection now also respects the current parenthesized-used state and detects postfix receiver calls after the closing parenthesis, while still preserving real consumed contexts such as call arguments. Selector statements remain generally allowed, but selectors whose receiver contains discarded embedded data are rejected unless the selector value is actually consumed.Postfix handling for embed-producing
or {}/lock/unsaferesults must distinguish selector-only chains from call chains. A plain.pathstill discards the value, while.to_string()or.field.method()consumes the value as a call receiver; the parser now only suppresses the inner embed diagnostic for postfix chains that reach a same-line call, matchingexpr_with_left()call parsing. The same postfix-call continuation logic is used when deciding whether a parenthesized nestedif/matchexpression is the current branch result or the receiver of an otherwise allowed call statement.Discarded expression detection needs to look through all value-producing wrappers that can hide an embed, not just the root node. String interpolations store their payload expressions and dynamic format expressions separately, so the embed search now descends into
StringInterLiteral.exprs,fwidth_exprs, andprecision_exprs. It also descends into call/selector receiver and argument subexpressions plus attachedor {}blocks, so a consumed fallback cannot disappear inside a larger discarded wrapper. Lock bodies are scanned directly during parsing rather than relying on checker-populatedLockExpr.is_expr.A used single-expression
unsafe {}body is itself a value-result scope. Without including that scope in the shared value-result helper, nestedif/matchexpressions andor {}fallbacks inside the unsafe body were parsed as statement-only even though their value becomes the unsafe expression result.Condition lookahead for nested
if/matchresult expressions must skip braced constructs that belong to the condition, including braced literals used as call arguments andlock/rlockresult bodies. Otherwise those condition-side braces are mistaken for the nested branch body and valid final$embed_file(...)branch values are parsed as statement-only. Parenthesized lock results also need postfix-call handling through closing parentheses, because a closing)before.to_string()still means the value is consumed as a receiver.The checker also accepted top-level
ast.DebuggerStmt, which let cgen emit debugger code outside a function. Script parsing now wraps leading script debugger statements, including initial comptime branches containing them, into the syntheticmainbefore checking.Fixes #27681.
Fixes #27682.
Validation
Latest follow-up:
./v -g -keepc -o ./vnew cmd/v./vnew -check vlib/v/tests/debugger_reserved_arg_name_test.v$if linux { #include <stdint.h>; $dbg } $else { #include <stdint.h>; $dbg }compiled with./vnew -o ... main.v.$match @OS { 'linux' { #include <stdint.h>; $dbg } $else { #include <stdint.h>; $dbg } }compiled with./vnew -o ... main.v.git diff --check -- vlib/v/parser/parser.v vlib/v/tests/debugger_reserved_arg_name_test.vgit diff --cached --check./vnew fmt -w vlib/v/parser/parser.v vlib/v/tests/debugger_reserved_arg_name_test.v, but compilingcmd/tools/vfmt.vcurrently fails on existingvlib/v/parser/fn.venum inference errors.Earlier checks on this PR included targeted compiler-error fixtures, embed-file tests, debugger tests, repeated formatting, rebuilds, and staged diff checks. Broad
./vnew -silent test vlib/v/was started earlier and then stopped/skipped per request.