Skip to content

Commit 28fb4e6

Browse files
committed
all: more deref fixes
1 parent da7e362 commit 28fb4e6

14 files changed

Lines changed: 92 additions & 35 deletions

vlib/v/checker/assign.v

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
313313
c.expr(mut right)
314314
}
315315
}
316-
if right.is_auto_deref_var() {
316+
if right.is_auto_deref_var() && right_type.is_ptr() {
317317
left_type = ast.mktyp(right_type.deref())
318318
} else {
319319
left_type = ast.mktyp(right_type)
@@ -754,7 +754,11 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
754754
.assign {} // No need to do single side check for =. But here put it first for speed.
755755
.plus_assign, .minus_assign {
756756
// allow literal values to auto deref var (e.g.`for mut v in values { v += 1.0 }`)
757-
left_deref := if left.is_auto_deref_var() { left_type.deref() } else { left_type }
757+
left_deref := if left.is_auto_deref_var() && left_type.is_ptr() {
758+
left_type.deref()
759+
} else {
760+
left_type
761+
}
758762
if left_deref == ast.string_type {
759763
if node.op != .plus_assign {
760764
c.error('operator `${node.op}` not defined on left operand type `${left_sym.name}`',
@@ -917,11 +921,11 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
917921
}
918922
// Dual sides check (compatibility check)
919923
c.check_expected(right_type_unwrapped, left_type_unwrapped) or {
920-
if left.is_auto_deref_arg() {
924+
if left.is_auto_deref_arg() && left_type.is_ptr() {
921925
left_deref := left_type.deref()
922926
right_deref := if right.is_pure_literal() {
923927
right.get_pure_type()
924-
} else if right.is_auto_deref_var() {
928+
} else if right.is_auto_deref_var() && right_type.is_ptr() {
925929
right_type.deref()
926930
} else {
927931
right_type
@@ -932,14 +936,14 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
932936
}
933937
// allow literal values to auto deref var (e.g.`for mut v in values { v = 1.0 }`)
934938
if left.is_auto_deref_var() || right.is_auto_deref_var() {
935-
left_deref := if left.is_auto_deref_var() {
939+
left_deref := if left.is_auto_deref_var() && left_type.is_ptr() {
936940
left_type.deref()
937941
} else {
938942
left_type
939943
}
940944
right_deref := if right.is_pure_literal() {
941945
right.get_pure_type()
942-
} else if right.is_auto_deref_var() {
946+
} else if right.is_auto_deref_var() && right_type.is_ptr() {
943947
right_type.deref()
944948
} else {
945949
right_type

vlib/v/checker/check_types.v

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,10 +1263,11 @@ fn (mut c Checker) infer_fn_generic_types(func &ast.Fn, mut node ast.CallExpr) {
12631263
// Use param.typ (not param_infer_typ) to get the actual pointer
12641264
// count including mut lowering, so that e.g. `mut val T` with
12651265
// param.typ=&T correctly strips the pointer from the arg type.
1266-
// Explicit `mut arg` calls should preserve the source-level
1267-
// reference type of the argument, even when the current scope
1268-
// variable is auto-dereferenced.
1269-
if param.typ.nr_muls() > 0 && typ.nr_muls() > 0 && !arg.is_mut {
1266+
// For auto-deref vars passed as mut, also strip pointers since
1267+
// the auto-deref var's type already includes the pointer level
1268+
// that mut adds.
1269+
if param.typ.nr_muls() > 0 && typ.nr_muls() > 0
1270+
&& (!arg.is_mut || arg.expr.is_auto_deref_var()) {
12701271
param_muls := param.typ.nr_muls()
12711272
arg_muls := typ.nr_muls()
12721273
typ = if arg_muls >= param_muls {

vlib/v/checker/infix.v

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
322322
.array {
323323
if left_sym.kind !in [.sum_type, .interface] {
324324
elem_type := right_final_sym.array_info().elem_type
325-
if node.left.is_auto_deref_var() {
325+
if node.left.is_auto_deref_var() && left_type.is_ptr() {
326326
left_type = left_type.deref()
327327
}
328328
c.check_expected(left_type, elem_type) or {
@@ -339,7 +339,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
339339
}
340340
} else {
341341
elem_type := right_final_sym.array_info().elem_type
342-
if node.left.is_auto_deref_var() {
342+
if node.left.is_auto_deref_var() && left_type.is_ptr() {
343343
left_type = left_type.deref()
344344
}
345345
c.check_expected(left_type, elem_type) or {
@@ -509,12 +509,13 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
509509
}
510510
}
511511
} else if node.left.is_auto_deref_var() || node.right.is_auto_deref_var() {
512-
deref_left_type := if node.left.is_auto_deref_var() {
512+
deref_left_type := if node.left.is_auto_deref_var() && unwrapped_left_type.is_ptr() {
513513
unwrapped_left_type.deref()
514514
} else {
515515
unwrapped_left_type
516516
}
517-
deref_right_type := if node.right.is_auto_deref_var() {
517+
deref_right_type := if node.right.is_auto_deref_var()
518+
&& unwrapped_right_type.is_ptr() {
518519
unwrapped_right_type.deref()
519520
} else {
520521
unwrapped_right_type
@@ -967,8 +968,16 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
967968
mut deref_right_type := right_type
968969
if (!types_match || pointer_value_mismatch)
969970
&& (left_allows_auto_deref || right_allows_auto_deref) {
970-
deref_left_type = if left_allows_auto_deref { left_type.deref() } else { left_type }
971-
deref_right_type = if right_allows_auto_deref { right_type.deref() } else { right_type }
971+
deref_left_type = if left_allows_auto_deref && left_type.is_ptr() {
972+
left_type.deref()
973+
} else {
974+
left_type
975+
}
976+
deref_right_type = if right_allows_auto_deref && right_type.is_ptr() {
977+
right_type.deref()
978+
} else {
979+
right_type
980+
}
972981
types_match_after_deref = c.symmetric_check(deref_left_type, deref_right_type)
973982
&& c.symmetric_check(deref_right_type, deref_left_type)
974983
}

vlib/v/checker/tests/check_err_msg_with_generics.out

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
vlib/datatypes/bstree.v:54:10: warning: cannot assign a reference to a value (this will be an error soon) left=datatypes.BSTreeNode[Result[[]Token, Err[string]]] false right=datatypes.BSTreeNode[Result[[]Token, Err[string]]] true ptr=true
2+
52 | node.value = to_bind.value
3+
53 | node.is_init = to_bind.is_init
4+
54 | to_bind = new_none_node[T](false)
5+
| ^
6+
55 | }
7+
56 |
8+
vlib/datatypes/bstree.v:143:9: warning: cannot assign a reference to a value (this will be an error soon) left=datatypes.BSTreeNode[Result[[]Token, Err[string]]] false right=datatypes.BSTreeNode[Result[[]Token, Err[string]]] true ptr=true
9+
141 | parent.right = new_none_node[T](false)
10+
142 | }
11+
143 | node = new_none_node[T](false)
12+
| ^
13+
144 | }
14+
145 | return true
115
vlib/v/checker/tests/check_err_msg_with_generics.vv:15:10: error: cannot cast struct `datatypes.BSTree[Result[[]Token, Err[string]]]` to `int`
216
13 | fn test_err_msg() {
317
14 | typ := datatypes.BSTree[Result[[]Token, Err[string]]]{}

vlib/v/checker/tests/generic_interface_err.out

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,3 @@ vlib/v/checker/tests/generic_interface_err.vv:10:6: error: can not find method `
1414
9 | s := Struct{7}
1515
10 | i := Interface(s)
1616
| ~~~~~~~~~~~~
17-
vlib/v/checker/tests/generic_interface_err.vv:10:6: error: `Struct` does not implement interface `Interface`, cannot cast `Struct` to interface `Interface`
18-
8 |
19-
9 | s := Struct{7}
20-
10 | i := Interface(s)
21-
| ~~~~~~~~~~~~

vlib/v/checker/tests/generic_mut_struct_index_err.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ vlib/v/checker/tests/generic_mut_struct_index_err.vv:7:3: error: type `mut Heap[
55
| ~~~~~
66
8 | }
77
9 |
8-
vlib/v/checker/tests/generic_mut_struct_index_err.vv:7:11: error: cannot assign to `h[pos]`: expected `Heap[int]`, not `&int`
8+
vlib/v/checker/tests/generic_mut_struct_index_err.vv:7:11: error: cannot assign to `h[pos]`: expected `Heap[int]`, not `int`
99
5 |
1010
6 | fn (mut h Heap[T]) insert(mut element T, pos int) {
1111
7 | h[pos] = element
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
vlib/datatypes/bstree.v:54:10: warning: cannot assign a reference to a value (this will be an error soon) left=datatypes.BSTreeNode[KeyVal[int]] false right=datatypes.BSTreeNode[KeyVal[int]] true ptr=true
2+
52 | node.value = to_bind.value
3+
53 | node.is_init = to_bind.is_init
4+
54 | to_bind = new_none_node[T](false)
5+
| ^
6+
55 | }
7+
56 |
8+
vlib/datatypes/bstree.v:143:9: warning: cannot assign a reference to a value (this will be an error soon) left=datatypes.BSTreeNode[KeyVal[int]] false right=datatypes.BSTreeNode[KeyVal[int]] true ptr=true
9+
141 | parent.right = new_none_node[T](false)
10+
142 | }
11+
143 | node = new_none_node[T](false)
12+
| ^
13+
144 | }
14+
145 | return true

vlib/v/checker/tests/generics_undefined_operation_2.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
vlib/v/checker/tests/generics_undefined_operation_2.vv:23:18: error: undefined operation `&INode` < `&INode`
1+
vlib/v/checker/tests/generics_undefined_operation_2.vv:23:18: error: mismatched types `INode` and `&INode`
22
21 | fn (mut h IHeap[T]) percolateup(hl u64, mut element T) {
33
22 | mut hole := hl
44
23 | for hole > 1 && element < h.array[hole / 2] {

vlib/v/checker/tests/implements_generic_err.out

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,23 @@ vlib/v/checker/tests/implements_generic_err.vv:22:31: error: unknown generic typ
1919
| ~~
2020
23 | a int
2121
24 | b T
22+
vlib/v/checker/tests/implements_generic_err.vv:28:2: error: `println` can not print void expressions
23+
26 |
24+
27 | fn (foo Foo1[T]) fa() {
25+
28 | println(foo.b)
26+
| ~~~~~~~~~~~~~~
27+
29 | }
28+
30 |
29+
vlib/v/checker/tests/implements_generic_err.vv:32:2: error: `println` can not print void expressions
30+
30 |
31+
31 | fn (foo Foo2[T]) fa() {
32+
32 | println(foo.b)
33+
| ~~~~~~~~~~~~~~
34+
33 | }
35+
34 |
36+
vlib/v/checker/tests/implements_generic_err.vv:36:2: error: `println` can not print void expressions
37+
34 |
38+
35 | fn (foo Foo3[T]) fa() {
39+
36 | println(foo.b)
40+
| ~~~~~~~~~~~~~~
41+
37 | }

vlib/v/checker/tests/interface_generic_err.out

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,3 @@ vlib/v/checker/tests/interface_generic_err.vv:8:8: error: could not infer generi
1414
7 | what := What{}
1515
8 | why := Why(what)
1616
| ~~~~~~~~~
17-
vlib/v/checker/tests/interface_generic_err.vv:8:8: error: `What` does not implement interface `Why`, cannot cast `What` to interface `Why`
18-
6 | // no segfault without generic
19-
7 | what := What{}
20-
8 | why := Why(what)
21-
| ~~~~~~~~~

0 commit comments

Comments
 (0)