From 7d29afec39e023df3b8b2e6feabc4cb1bf858aef Mon Sep 17 00:00:00 2001 From: shove Date: Thu, 4 Jan 2024 18:09:34 +0800 Subject: [PATCH] checker: optimize error messages for must specify the generic type names (fix #20362) (#20382) --- vlib/v/checker/fn.v | 7 ++++--- .../generics_method_receiver_type_err_b.out | 17 ++++++++++++----- .../generics_method_receiver_type_err_b.vv | 14 ++++++++++++-- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 6f50141049b3c9..b35475a9e96444 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -232,6 +232,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { c.error('Result type argument is not supported currently', param.type_pos) } arg_typ_sym := c.table.sym(param.typ) + pure_sym_name := arg_typ_sym.embed_name() if arg_typ_sym.info is ast.Struct { if !param.typ.is_ptr() && arg_typ_sym.info.is_heap { // set auto_heap to promote value parameter mut v := node.scope.find_var(param.name) or { continue } @@ -239,19 +240,19 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { } if arg_typ_sym.info.generic_types.len > 0 && !param.typ.has_flag(.generic) && arg_typ_sym.info.concrete_types.len == 0 { - c.error('generic struct `${arg_typ_sym.name}` in fn declaration must specify the generic type names, e.g. ${arg_typ_sym.name}[T]', + c.error('generic struct `${pure_sym_name}` in fn declaration must specify the generic type names, e.g. ${pure_sym_name}[T]', param.type_pos) } } else if arg_typ_sym.info is ast.Interface { if arg_typ_sym.info.generic_types.len > 0 && !param.typ.has_flag(.generic) && arg_typ_sym.info.concrete_types.len == 0 { - c.error('generic interface `${arg_typ_sym.name}` in fn declaration must specify the generic type names, e.g. ${arg_typ_sym.name}[T]', + c.error('generic interface `${pure_sym_name}` in fn declaration must specify the generic type names, e.g. ${pure_sym_name}[T]', param.type_pos) } } else if arg_typ_sym.info is ast.SumType { if arg_typ_sym.info.generic_types.len > 0 && !param.typ.has_flag(.generic) && arg_typ_sym.info.concrete_types.len == 0 { - c.error('generic sumtype `${arg_typ_sym.name}` in fn declaration must specify the generic type names, e.g. ${arg_typ_sym.name}[T]', + c.error('generic sumtype `${pure_sym_name}` in fn declaration must specify the generic type names, e.g. ${pure_sym_name}[T]', param.type_pos) } } diff --git a/vlib/v/checker/tests/generics_method_receiver_type_err_b.out b/vlib/v/checker/tests/generics_method_receiver_type_err_b.out index 546ff70c47b969..61197ad31d4e08 100644 --- a/vlib/v/checker/tests/generics_method_receiver_type_err_b.out +++ b/vlib/v/checker/tests/generics_method_receiver_type_err_b.out @@ -1,7 +1,14 @@ -vlib/v/checker/tests/generics_method_receiver_type_err_b.vv:8:12: error: generic struct `ConsumableResources` in fn declaration must specify the generic type names, e.g. ConsumableResources[T] - 6 | used_resources map[T]Resources +vlib/v/checker/tests/generics_method_receiver_type_err_b.vv:9:12: error: generic struct `ConsumableResources` in fn declaration must specify the generic type names, e.g. ConsumableResources[T] 7 | } - 8 | pub fn (cr &ConsumableResources) get_total_resources() Resources { + 8 | + 9 | pub fn (cr &ConsumableResources) get_total_resources() Resources { | ~~~~~~~~~~~~~~~~~~~~ - 9 | return cr.total_resources - 10 | } + 10 | return cr.total_resources + 11 | } +vlib/v/checker/tests/generics_method_receiver_type_err_b.vv:19:11: error: generic struct `Foo` in fn declaration must specify the generic type names, e.g. Foo[T] + 17 | } + 18 | + 19 | pub fn (f Foo) method() { + | ~~~ + 20 | } + 21 | diff --git a/vlib/v/checker/tests/generics_method_receiver_type_err_b.vv b/vlib/v/checker/tests/generics_method_receiver_type_err_b.vv index 844c5972832506..8493aae90f1d41 100644 --- a/vlib/v/checker/tests/generics_method_receiver_type_err_b.vv +++ b/vlib/v/checker/tests/generics_method_receiver_type_err_b.vv @@ -1,13 +1,23 @@ -pub struct Resources{} +pub struct Resources {} pub struct ConsumableResources[T] { mut: total_resources Resources - used_resources map[T]Resources + used_resources map[T]Resources } + pub fn (cr &ConsumableResources) get_total_resources() Resources { return cr.total_resources } +// for issue 20362 +struct Foo[T] {} + +pub fn new_foo[F](arg F) !Foo[F] { +} + +pub fn (f Foo) method() { +} + fn main() { }