diff --git a/vlib/net/http/http.v b/vlib/net/http/http.v index 61ffca492a..a31a4ac867 100644 --- a/vlib/net/http/http.v +++ b/vlib/net/http/http.v @@ -20,7 +20,7 @@ pub mut: url string user_agent string verbose bool -mut: +//mut: user_ptr voidptr ws_func voidptr } diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index bacf844feb..e3f696d70f 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -1371,7 +1371,7 @@ fn (mut g Gen) assign_expr(node ast.AssignExpr) { tmp_opt := if gen_or { g.new_tmp_var() } else { '' } if gen_or { rstyp := g.typ(return_type) - g.write('$rstyp $tmp_opt =') + g.write('/*q*/ $rstyp $tmp_opt = ') } g.is_assign_rhs = true if ast.expr_is_blank_ident(node.left) { @@ -1406,12 +1406,16 @@ fn (mut g Gen) assign_expr(node ast.AssignExpr) { } } else { g.assign_op = node.op - g.expr(node.left) - // arr[i] = val => `array_set(arr, i, val)`, not `array_get(arr, i) = val` - if !g.is_array_set && !str_add { - g.write(' $node.op.str() ') - } else if str_add { - g.write(', ') + if !gen_or { + // Don't need to generate `var = ` in `or {}` expressions, since we are doing + // `Option_X tmp = ...; var = *(X*)tmp.data;` + g.expr(node.left) + // arr[i] = val => `array_set(arr, i, val)`, not `array_get(arr, i) = val` + if !g.is_array_set && !str_add { + g.write(' $node.op.str() ') + } else if str_add { + g.write(', ') + } } g.is_assign_lhs = false // right_sym := g.table.get_type_symbol(node.right_type) @@ -1436,7 +1440,22 @@ fn (mut g Gen) assign_expr(node ast.AssignExpr) { g.right_is_opt = false } if gen_or { + // g.write('/*777 $tmp_opt*/') g.or_block(tmp_opt, or_stmts, return_type) + unwrapped_type_str := g.typ(return_type.set_flag(.unset)) + ident := node.left as ast.Ident + if ident.info is ast.IdentVar { + ident_var := ident.info as ast.IdentVar + if ident_var.is_optional { + // var is already an optional, just copy the value + // `var = tmp;` + g.write('\n$ident.name = $tmp_opt') + } else { + // var = *(X*)tmp.data;` + g.write('\n$ident.name = *($unwrapped_type_str*)${tmp_opt}.data') + } + } + // g.expr(node.left) } g.is_assign_rhs = false } diff --git a/vlib/v/tests/option_test.v b/vlib/v/tests/option_test.v index 1943ad90a3..585898c0d6 100644 --- a/vlib/v/tests/option_test.v +++ b/vlib/v/tests/option_test.v @@ -9,7 +9,7 @@ fn test_err_with_code() { return } assert false - println(v) // suppress not used error + println(v) // suppress not used error } fn opt_err() ?string { @@ -22,7 +22,7 @@ fn test_err() { return } assert false - println(v) // suppress not used error + println(v) // suppress not used error } fn err_call(ok bool) ?int { @@ -84,6 +84,25 @@ fn test_q() { // assert foo_ok()? == true } +fn test_reassignment() { + mut x2 := foo_ok() or { + assert false + return + } + assert x2 == 777 + x2 = 100 + assert x2 == 100 + x2 += 1 + assert x2 == 101 + /// + mut x3 := 0 + x3 = foo_ok() or { + assert false + return + } + assert x3 == 777 +} + struct Person { mut: name string @@ -111,7 +130,7 @@ fn test_field_or() { 'default' } assert mytitle == 'default' -*/ + */ } struct Thing { @@ -126,7 +145,7 @@ fn test_opt_field() { t.opt = 5 val := t.opt or { return } assert val == 5 -*/ + */ } fn opt_ptr(a &int) ?&int { @@ -137,6 +156,13 @@ fn opt_ptr(a &int) ?&int { } fn test_opt_ptr() { + if true { + + } + // + else{ + + } a := 3 mut r := opt_ptr(&a) or { &int(0)