Skip to content

cgen: fix option reference string interpolation - #27760

Open
cyphercodes wants to merge 3 commits into
vlang:masterfrom
cyphercodes:fix-option-ref-interpolation
Open

cgen: fix option reference string interpolation#27760
cyphercodes wants to merge 3 commits into
vlang:masterfrom
cyphercodes:fix-option-ref-interpolation

Conversation

@cyphercodes

Copy link
Copy Markdown

Fixes #27752

This fixes C generation for string interpolation of references to option values, such as ${&val} where val is ?int.

The interpolation stringification path now materializes the existing option-payload-reference lowering into a temporary before adding the generated nil check/string call, avoiding invalid generated C such as &&val.data.

A regression test covers both a payload option and none.

Tests

V_C_ERROR_BUG_REPORT_DISABLED=1 ./v test vlib/v/tests/builtin_strings_and_interpolation/string_interpolation_test.v
V_C_ERROR_BUG_REPORT_DISABLED=1 ./v test vlib/v/tests/options/option_reference_of_option_test.v
git diff --check

@GGRei

GGRei commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

This looks good for the direct ?int case, but one case mentioned in #27752 is still missing, an alias such as type MaybeInt = ?int still generates &&val.data and fails during C compilation.

Could you also handle the aliased option type and add a regression case for it? After that, the issue should be fully covered.

@medvednikov

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

Reviewed commit: b6a80fd4e5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@medvednikov

Copy link
Copy Markdown
Member

lots of ci errors

@cyphercodes

Copy link
Copy Markdown
Author

Updated this to cover the aliased option case from the review.

What changed:

  • detect option aliases when deciding whether &option string interpolation needs an option-payload temporary
  • generate the temporary as ?&T after unaliasing, so aliased ?T avoids the bad &&val.data C output
  • added regression coverage for type MaybeInt = ?int

Verification run locally:

  • ./v self
  • ./v -showcc -cg -keepc -o /tmp/alias_option_ref /tmp/alias_option_ref.v (prints &Option(42))
  • ./v -showcc -cg -keepc -o /tmp/string_interp_test vlib/v/tests/builtin_strings_and_interpolation/string_interpolation_test.v
  • /tmp/string_interp_test
  • git diff --check

@GGRei

GGRei commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: 79a5bc77f0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@GGRei

GGRei commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

The red CI jobs appear to share the same root cause, the chained && match right_expr { ... } expression in vlib/v/gen/c/str.v generates invalid C around a goto. The build then stops early, causing the remaining CI failures.

Can you fix it plz?

@cyphercodes

Copy link
Copy Markdown
Author

Updated to avoid the && match right_expr { ... } condition in vlib/v/gen/c/str.v that was generating invalid C around a goto.

Verification run locally:

  • make -j2
  • ./v self
  • ./v -cc gcc -showcc -cg -keepc -o /tmp/alias_option_ref /tmp/alias_option_ref.v + /tmp/alias_option_ref (prints &Option(42))
  • ./v -cc gcc -showcc -cg -keepc -o /tmp/string_interp_test vlib/v/tests/builtin_strings_and_interpolation/string_interpolation_test.v + /tmp/string_interp_test
  • git diff --check

@GGRei

GGRei commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 878448e175

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread vlib/v/gen/c/str.v
Comment on lines +260 to +261
exp_typ =
g.table.fully_unaliased_type(expr.right_type).clear_option_and_result().ref().set_flag(.option)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve option payload aliases when building the temp

When val has type ?Alias and Alias defines its own str(), this rebuilds the interpolation temporary from fully_unaliased_type(expr.right_type), turning the semantic ?&Alias into ?&<parent>. The g.get_str_fn(exp_typ) call below then generates/calls the parent type's stringifier instead of the alias override, so ${&val} silently loses the alias-specific formatting even though plain ${val} preserves it; only the option detection needs unaliasing, while the temporary type should keep the original payload alias when the option flag is already present.

Useful? React with 👍 / 👎.

Comment thread vlib/v/gen/c/str.v
Comment on lines +248 to +252
mut option_payload_ref_tmp := false
if expr is ast.PrefixExpr {
right_expr := expr.right.remove_par()
right_type := g.table.fully_unaliased_type(expr.right_type)
if expr.op == .amp && right_type.has_flag(.option) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Hoist option-ref lowering before enum stringification

Because this option-reference lowering is added only inside the later auto-string branch, option references whose payload symbol is handled by an earlier branch never use it. For example, with enum Color { red } and val := ?Color(.red), ${&val} enters the sym.kind == .enum path above before this block and still passes the original ?Color storage to the ?&Color stringifier, leaving this fix incomplete for option enum payloads.

Useful? React with 👍 / 👎.

Comment thread vlib/v/gen/c/str.v
Comment on lines +251 to +252
right_type := g.table.fully_unaliased_type(expr.right_type)
if expr.op == .amp && right_type.has_flag(.option) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Resolve generic right types before detecting option refs

In generic instantiations where T is an option, the prefix expression's right_type can still be the generic parameter while the interpolation expression type has already been resolved for the concrete call. Testing expr.right_type directly leaves option_payload_ref_tmp false for ${&val} inside fn f[T](val T) called as f[?int](...), so it falls back to the old address-of emission instead of the new option-payload temporary; resolve/unwrap the right type before checking the option flag.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cgen: ${&val} on an option value emits &&val and fails to C-compile

3 participants