table: fix generics struct with anon fn fields (#10024)

pull/10029/head
yuyi 2021-05-07 01:24:08 +08:00 committed by GitHub
parent ac2eaa05c7
commit a6764e3cc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 21 deletions

View File

@ -63,7 +63,6 @@ pub fn (t &Table) panic(message string) {
pub struct Fn {
pub:
return_type Type
is_variadic bool
language Language
generic_names []string
@ -79,10 +78,10 @@ pub:
mod string
ctdefine string // compile time define. "myflag", when [if myflag] tag
attrs []Attr
//
pos token.Position
return_type_pos token.Position
pub mut:
return_type Type
name string
params []Param
source_fn voidptr // set in the checker, while processing fn declarations
@ -1108,6 +1107,26 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
}
return new_type(idx).derive(generic_type).clear_flag(.generic)
}
} else if mut sym.info is FnType {
mut func := sym.info.func
if func.return_type.has_flag(.generic) {
if typ := t.resolve_generic_to_concrete(func.return_type, generic_names, concrete_types,
is_inst)
{
func.return_type = typ
}
}
for mut param in func.params {
if param.typ.has_flag(.generic) {
if typ := t.resolve_generic_to_concrete(param.typ, generic_names, concrete_types,
is_inst)
{
param.typ = typ
}
}
}
idx := t.find_or_register_fn_type('', func, true, false)
return new_type(idx).derive(generic_type).clear_flag(.generic)
}
return none
}

View File

@ -0,0 +1,14 @@
struct Scope<T> {
before fn () T
specs []fn (T) T
after fn (T)
}
fn test_generics_struct_anon_fn_fields() {
s := Scope<u32>{}
println(s)
ts := '$s'
assert ts.contains('before: fn () u32')
assert ts.contains('specs: []')
assert ts.contains('after: fn (u32)')
}