From 41d38d735addcf9a08e99e242e2abe22e21f91d3 Mon Sep 17 00:00:00 2001 From: shove Date: Mon, 1 Jan 2024 19:31:15 +0800 Subject: [PATCH] checker: fix type mismatch checking for assignments with generics (fix #20298) (#20327) --- vlib/v/checker/assign.v | 3 +- ...assign_type_mismatch_with_generics_err.out | 7 +++++ .../assign_type_mismatch_with_generics_err.vv | 28 +++++++++++++++++++ vlib/v/tests/generics_chans_select_test.v | 4 +-- 4 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 vlib/v/checker/tests/assign_type_mismatch_with_generics_err.out create mode 100644 vlib/v/checker/tests/assign_type_mismatch_with_generics_err.vv diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v index dfc01eccdc..33d5abc229 100644 --- a/vlib/v/checker/assign.v +++ b/vlib/v/checker/assign.v @@ -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 }`) diff --git a/vlib/v/checker/tests/assign_type_mismatch_with_generics_err.out b/vlib/v/checker/tests/assign_type_mismatch_with_generics_err.out new file mode 100644 index 0000000000..b16915eae4 --- /dev/null +++ b/vlib/v/checker/tests/assign_type_mismatch_with_generics_err.out @@ -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 diff --git a/vlib/v/checker/tests/assign_type_mismatch_with_generics_err.vv b/vlib/v/checker/tests/assign_type_mismatch_with_generics_err.vv new file mode 100644 index 0000000000..77a8ecc7a3 --- /dev/null +++ b/vlib/v/checker/tests/assign_type_mismatch_with_generics_err.vv @@ -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{}) +} diff --git a/vlib/v/tests/generics_chans_select_test.v b/vlib/v/tests/generics_chans_select_test.v index 412e0ba1e5..baa05edbd2 100644 --- a/vlib/v/tests/generics_chans_select_test.v +++ b/vlib/v/tests/generics_chans_select_test.v @@ -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 }