v.checker: fix multi insts of generics struct with array (#11142)
parent
a64a4d932c
commit
90adf4d092
|
@ -3372,12 +3372,10 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
||||||
return ast.string_type
|
return ast.string_type
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
old_selector_expr := c.inside_selector_expr
|
old_selector_expr := c.inside_selector_expr
|
||||||
c.inside_selector_expr = true
|
c.inside_selector_expr = true
|
||||||
typ := c.expr(node.expr)
|
typ := c.expr(node.expr)
|
||||||
c.inside_selector_expr = old_selector_expr
|
c.inside_selector_expr = old_selector_expr
|
||||||
//
|
|
||||||
c.using_new_err_struct = using_new_err_struct_save
|
c.using_new_err_struct = using_new_err_struct_save
|
||||||
if typ == ast.void_type_idx {
|
if typ == ast.void_type_idx {
|
||||||
c.error('`void` type has no fields', node.pos)
|
c.error('`void` type has no fields', node.pos)
|
||||||
|
@ -3390,8 +3388,7 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
||||||
node.pos)
|
node.pos)
|
||||||
}
|
}
|
||||||
field_name := node.field_name
|
field_name := node.field_name
|
||||||
utyp := c.unwrap_generic(typ)
|
sym := c.table.get_type_symbol(typ)
|
||||||
sym := c.table.get_type_symbol(utyp)
|
|
||||||
if (typ.has_flag(.variadic) || sym.kind == .array_fixed) && field_name == 'len' {
|
if (typ.has_flag(.variadic) || sym.kind == .array_fixed) && field_name == 'len' {
|
||||||
node.typ = ast.int_type
|
node.typ = ast.int_type
|
||||||
return ast.int_type
|
return ast.int_type
|
||||||
|
@ -3447,7 +3444,7 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if typ.has_flag(.generic) && !has_field {
|
if typ.has_flag(.generic) && !has_field {
|
||||||
gs := c.table.get_type_symbol(typ)
|
gs := c.table.get_type_symbol(c.unwrap_generic(typ))
|
||||||
if f := c.table.find_field(gs, field_name) {
|
if f := c.table.find_field(gs, field_name) {
|
||||||
has_field = true
|
has_field = true
|
||||||
field = f
|
field = f
|
||||||
|
@ -3473,9 +3470,7 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
||||||
field_sym := c.table.get_type_symbol(field.typ)
|
field_sym := c.table.get_type_symbol(field.typ)
|
||||||
if field_sym.kind in [.sum_type, .interface_] {
|
if field_sym.kind in [.sum_type, .interface_] {
|
||||||
if !prevent_sum_type_unwrapping_once {
|
if !prevent_sum_type_unwrapping_once {
|
||||||
if scope_field := node.scope.find_struct_field(node.expr.str(), utyp,
|
if scope_field := node.scope.find_struct_field(node.expr.str(), typ, field_name) {
|
||||||
field_name)
|
|
||||||
{
|
|
||||||
return scope_field.smartcasts.last()
|
return scope_field.smartcasts.last()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4183,7 +4178,7 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
||||||
}
|
}
|
||||||
if !is_blank_ident && !left.is_auto_deref_var() && !right.is_auto_deref_var()
|
if !is_blank_ident && !left.is_auto_deref_var() && !right.is_auto_deref_var()
|
||||||
&& right_sym.kind != .placeholder && left_sym.kind != .interface_
|
&& right_sym.kind != .placeholder && left_sym.kind != .interface_
|
||||||
&& !right_type_unwrapped.has_flag(.generic) && !left_type_unwrapped.has_flag(.generic) {
|
&& !right_type.has_flag(.generic) && !left_type.has_flag(.generic) {
|
||||||
// Dual sides check (compatibility check)
|
// Dual sides check (compatibility check)
|
||||||
c.check_expected(right_type_unwrapped, left_type_unwrapped) or {
|
c.check_expected(right_type_unwrapped, left_type_unwrapped) or {
|
||||||
// allow for ptr += 2
|
// allow for ptr += 2
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
struct Set<T> {
|
||||||
|
pub mut:
|
||||||
|
arr []T
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut s Set<T>) add(elem T) bool {
|
||||||
|
return match s.has(elem) {
|
||||||
|
true {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
s.arr << elem
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (s Set<T>) has(elem T) bool {
|
||||||
|
return elem in s.arr
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_generics_struct_with_array() {
|
||||||
|
mut s1 := Set<int>{}
|
||||||
|
println('declared a int-Set $s1')
|
||||||
|
s1.add(1)
|
||||||
|
println('the int-Set $s1')
|
||||||
|
assert s1.arr == [1]
|
||||||
|
|
||||||
|
mut s2 := Set<bool>{}
|
||||||
|
println('declared a bool-Set $s2')
|
||||||
|
s2.add(true)
|
||||||
|
println('the bool-Set $s2')
|
||||||
|
assert s2.arr == [true]
|
||||||
|
|
||||||
|
mut s3 := Set<f64>{}
|
||||||
|
println('declared a float-Set $s3')
|
||||||
|
s3.add(2.22)
|
||||||
|
println('the float-Set $s3')
|
||||||
|
assert s3.arr == [2.22]
|
||||||
|
|
||||||
|
mut s4 := Set<string>{}
|
||||||
|
println('declared a string-Set $s4')
|
||||||
|
s4.add('smth')
|
||||||
|
println('the string-Set $s4 ')
|
||||||
|
assert s4.arr == ['smth']
|
||||||
|
}
|
Loading…
Reference in New Issue