diff --git a/vlib/v/checker/interface.v b/vlib/v/checker/interface.v index f150e4bbc5..0e95f57229 100644 --- a/vlib/v/checker/interface.v +++ b/vlib/v/checker/interface.v @@ -303,10 +303,16 @@ fn (mut c Checker) resolve_generic_interface(typ ast.Type, interface_type ast.Ty } for i, iparam in imethod.params { param := method.params[i] or { ast.Param{} } - if iparam.typ.has_flag(.generic) { + mut need_inferred_type := false + if !iparam.typ.has_flag(.generic) && iparam.typ == param.typ + && imethod.return_type == method.return_type + && imethod.name == method.name { + need_inferred_type = true + } + if iparam.typ.has_flag(.generic) || need_inferred_type { param_sym := c.table.sym(iparam.typ) arg_sym := c.table.sym(param.typ) - if c.table.get_type_name(iparam.typ) == gt_name { + if c.table.get_type_name(iparam.typ) == gt_name || need_inferred_type { inferred_type = param.typ } else if arg_sym.info is ast.Array && param_sym.info is ast.Array { mut arg_elem_typ, mut param_elem_typ := arg_sym.info.elem_type, param_sym.info.elem_type diff --git a/vlib/v/tests/generics_interface_with_generic_method_using_generic_struct_test.v b/vlib/v/tests/generics_interface_with_generic_method_using_generic_struct_test.v new file mode 100644 index 0000000000..7754247a6a --- /dev/null +++ b/vlib/v/tests/generics_interface_with_generic_method_using_generic_struct_test.v @@ -0,0 +1,25 @@ +struct Store[Z] { +mut: + event_handlers []IEventHandler[Z] +} + +fn (mut me Store[Z]) add_event_handler(event_handler IEventHandler[Z]) { + me.event_handlers << IEventHandler[Z](event_handler) +} + +interface IEventHandler[Z] { +mut: + apply(event Z) +} + +struct UserEvent {} + +struct UserEventHandler {} + +pub fn (mut me UserEventHandler) apply(event UserEvent) {} + +fn test_generic_interface_with_method_using_generic_struct() { + mut s := Store[UserEvent]{} + s.add_event_handler(UserEventHandler{}) + assert s.event_handlers.len > 0 +}