From 64c8fb061d6fc9f096357ddb99da224e0b0dc867 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sun, 9 Jan 2022 01:19:45 +0800 Subject: [PATCH] ast: fix generics with nested generic type parameter (fix #13077) (#13088) --- vlib/v/ast/table.v | 18 +++++++++++++++++ ..._with_nested_generic_type_parameter_test.v | 20 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 vlib/v/tests/generics_with_nested_generic_type_parameter_test.v diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v index ba0cc99931..a70ed95f4e 100644 --- a/vlib/v/ast/table.v +++ b/vlib/v/ast/table.v @@ -1540,6 +1540,7 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concrete_types []Type) Type { mut final_concrete_types := []Type{} mut fields := []StructField{} + mut needs_unwrap_types := []Type{} mut nrt := '' mut c_nrt := '' ts := t.sym(typ) @@ -1627,6 +1628,20 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr } if final_concrete_types.len > 0 { for method in ts.methods { + for i in 1 .. method.params.len { + if method.params[i].typ.has_flag(.generic) + && method.params[i].typ != method.params[0].typ { + if method.params[i].typ !in needs_unwrap_types { + needs_unwrap_types << method.params[i].typ + } + } + if method.return_type.has_flag(.generic) + && method.return_type != method.params[0].typ { + if method.return_type !in needs_unwrap_types { + needs_unwrap_types << method.return_type + } + } + } t.register_fn_concrete_types(method.fkey(), final_concrete_types) } } @@ -1648,6 +1663,9 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr mod: ts.mod info: info ) + for typ_ in needs_unwrap_types { + t.unwrap_generic_type(typ_, generic_names, concrete_types) + } return new_type(new_idx).derive(typ).clear_flag(.generic) } Interface { diff --git a/vlib/v/tests/generics_with_nested_generic_type_parameter_test.v b/vlib/v/tests/generics_with_nested_generic_type_parameter_test.v new file mode 100644 index 0000000000..3e8f9411fe --- /dev/null +++ b/vlib/v/tests/generics_with_nested_generic_type_parameter_test.v @@ -0,0 +1,20 @@ +module main + +pub struct Randomizer { +} + +pub struct Element { +} + +fn test_generics_with_nested_generic_type_parameter() { + a := new_randomizer() + println(a) + assert '$a' == '&Randomizer{}' +} + +pub fn new_randomizer() &Randomizer { + return &Randomizer{} +} + +pub fn (mut r Randomizer) add_multiple(elements []Element) { +}