Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion vlib/v/gen/c/assign.v
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,10 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
mut return_type := ast.void_type
is_decl := node.op == .decl_assign
g.assign_op = node.op
g.inside_assign = true
defer {
g.assign_op = .unknown
g.inside_assign = false
}
op := if is_decl { token.Kind.assign } else { node.op }
right_expr := node.right[0]
Expand Down Expand Up @@ -597,7 +599,8 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
if val.is_auto_deref_var() {
g.write('*')
}
if var_type.has_flag(.option) || gen_or {
if (var_type.has_flag(.option) && val !in [ast.Ident, ast.SelectorExpr])
|| gen_or {
g.expr_with_opt_or_block(val, val_type, left, var_type)
} else if val is ast.ArrayInit {
g.array_init(val, c_name(ident.name))
Expand Down
3 changes: 2 additions & 1 deletion vlib/v/gen/c/cgen.v
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ mut:
inside_ternary int // ?: comma separated statements on a single line
inside_map_postfix bool // inside map++/-- postfix expr
inside_map_infix bool // inside map<</+=/-= infix expr
inside_assign bool
inside_map_index bool
inside_opt_or_res bool
inside_opt_data bool
Expand Down Expand Up @@ -4123,7 +4124,7 @@ fn (mut g Gen) ident(node ast.Ident) {
styp := g.base_type(node.info.typ)
g.write('(*(${styp}*)${name}.data)')
}
if node.or_expr.kind != .absent {
if node.or_expr.kind != .absent && !(g.inside_assign && !g.is_assign_lhs) {
stmt_str := g.go_before_stmt(0).trim_space()
g.empty_line = true
g.or_block(name, node.or_expr, node.info.typ)
Expand Down
1 change: 1 addition & 0 deletions vlib/v/gen/c/if.v
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
} else if branch.cond is ast.IfGuardExpr {
mut var_name := guard_vars[i]
mut short_opt := false
g.left_is_opt = true
if var_name == '' {
short_opt = true // we don't need a further tmp, so use the one we'll get later
var_name = g.new_tmp_var()
Expand Down
2 changes: 1 addition & 1 deletion vlib/v/parser/if_match.v
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr {
p.check(.decl_assign)
comments << p.eat_comments()
expr := p.expr(0)
if expr !in [ast.CallExpr, ast.IndexExpr, ast.PrefixExpr, ast.SelectorExpr] {
if expr !in [ast.CallExpr, ast.IndexExpr, ast.PrefixExpr, ast.SelectorExpr, ast.Ident] {
p.error_with_pos('if guard condition expression is illegal, it should return an Option',
expr.pos())
}
Expand Down
26 changes: 26 additions & 0 deletions vlib/v/tests/option_var_2_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
struct Foo {
name ?string
}

fn test_option_var() {
foo := Foo{}
other := foo.name

println(typeof(other).name)
if name := other {
println('with name: ${name}')
assert false
} else {
println('without name')
assert true
}

mut counter := 0
val := other or {
counter++
'default'
}

assert val == 'default'
assert counter == 1
}