checker: fix type mismatch checking for assignments with generics (fix #20298) (#20327)

This commit is contained in:
shove 2024-01-01 19:31:15 +08:00 committed by GitHub
parent b1f64a32e3
commit 41d38d735a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 4 deletions

View File

@ -735,8 +735,7 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
}
}
}
if !is_blank_ident && right_sym.kind != .placeholder && left_sym.kind != .interface_
&& !right_type.has_flag(.generic) && !left_type.has_flag(.generic) {
if !is_blank_ident && right_sym.kind != .placeholder && left_sym.kind != .interface_ {
// Dual sides check (compatibility check)
c.check_expected(right_type_unwrapped, left_type_unwrapped) or {
// allow literal values to auto deref var (e.g.`for mut v in values { v = 1.0 }`)

View File

@ -0,0 +1,7 @@
vlib/v/checker/tests/assign_type_mismatch_with_generics_err.vv:13:9: error: cannot assign to `b`: expected `bool`, not `fn (Bar) bool`
11 | mut b := false
12 | if f.f != none {
13 | b = f.f or { panic(err) }
| ^
14 | } else {
15 | b = true

View File

@ -0,0 +1,28 @@
type Fn[T] = fn (arg T) bool
struct Foo[T] {
f ?Fn[T]
}
@[params]
struct Bar {}
fn (mut f Foo[T]) method(arg T) {
mut b := false
if f.f != none {
b = f.f or { panic(err) }
} else {
b = true
}
if b {
}
}
fn main() {
mut foo := Foo[Bar]{
f: fn (arg Bar) bool {
return true
}
}
foo.method(Bar{})
}

View File

@ -35,8 +35,8 @@ pub fn (mut ec EventController[T]) emit(e T, options EmitOptions) {
for i, w in ec.wait_fors {
mut b := false
if w.check != none {
b = (w.check or { panic(err) })
e
func := w.check or { panic(err) }
b = func(e)
} else {
b = true
}