v.checker: fix multi insts of generics struct with array (#11142)

pull/11156/head
yuyi 2021-08-11 21:59:13 +08:00 committed by GitHub
parent a64a4d932c
commit 90adf4d092
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 9 deletions

View File

@ -3372,12 +3372,10 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
return ast.string_type
}
//
old_selector_expr := c.inside_selector_expr
c.inside_selector_expr = true
typ := c.expr(node.expr)
c.inside_selector_expr = old_selector_expr
//
c.using_new_err_struct = using_new_err_struct_save
if typ == ast.void_type_idx {
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)
}
field_name := node.field_name
utyp := c.unwrap_generic(typ)
sym := c.table.get_type_symbol(utyp)
sym := c.table.get_type_symbol(typ)
if (typ.has_flag(.variadic) || sym.kind == .array_fixed) && field_name == 'len' {
node.typ = 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 {
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) {
has_field = true
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)
if field_sym.kind in [.sum_type, .interface_] {
if !prevent_sum_type_unwrapping_once {
if scope_field := node.scope.find_struct_field(node.expr.str(), utyp,
field_name)
{
if scope_field := node.scope.find_struct_field(node.expr.str(), typ, field_name) {
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()
&& 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)
c.check_expected(right_type_unwrapped, left_type_unwrapped) or {
// allow for ptr += 2

View File

@ -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']
}