Skip to content

v3: lower value-context match/if block operands with !/? propagation (fix #28000) - #28011

Open
medvednikov wants to merge 37 commits into
masterfrom
v3-match-if-block-value-propagation-28000
Open

v3: lower value-context match/if block operands with !/? propagation (fix #28000)#28011
medvednikov wants to merge 37 commits into
masterfrom
v3-match-if-block-value-propagation-28000

Conversation

@medvednikov

Copy link
Copy Markdown
Member

Fix #28000 (v3 backend)

This is the v3-only portion of #28002, split out per request (the vlib/v compiler changes from that PR are dropped here). #28002 is being closed in favor of this.

A match/if used as the value of another expression — a cast, a string-interpolation part, dump(), a prefix/infix operand, an index expression, a selector receiver, or an as operand — must have its (possibly propagating, !/?) branch tails lowered as values. Previously the v3 transformer lowered them in a value-less statement context, which produced an empty ternary / expression for the propagated result.

Change

  • vlib/v3/transform/transform.v: add transform_value_operand and is_value_match_or_if_operand helpers. The latter looks through transparent wrappers — (...) parens, unsafe { } blocks, and a trailing expr_stmt (including compositions like i64(unsafe { match ... })). Route the affected operands (string-interp parts, dump(), infix/prefix operands, index children, selector base, cast operands, and block-expr value tails) through target-typed lowering.
  • vlib/v3/transform/sum.v: handle a match/if operand of an as cast by materializing it into a value temp first, then re-running the as conversion.

Test

vlib/v3/tests/match_as_if_expr_value_propagation_codegen_test.v — covers !/? propagation for a match used as an if-guard value, and wrapped in parens / unsafe / cast / interpolation / dump / prefix / index / selector operands.

Reproduction from the issue now compiles and runs correctly:

fn select_value(node ?Node) !int {
	result := if value := node {
		match value {
			First { lower_first(value)! }
			Second { lower_second(value)! }
		}
	} else {
		0
	}
	return result
}

Loading
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: match with !-propagating arms used as an if-expression value emits _t4 = ; (expected expression)

1 participant