ast: fix error for generic sumtype init in generic fn call (#13238)

pull/13246/head
yuyi 2022-01-21 20:46:55 +08:00 committed by GitHub
parent 79cb0db2ff
commit 05ff8f516d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 2 deletions

View File

@ -1668,6 +1668,41 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr
} }
return new_type(new_idx).derive(typ).clear_flag(.generic) return new_type(new_idx).derive(typ).clear_flag(.generic)
} }
SumType {
mut variants := ts.info.variants.clone()
for i in 0 .. variants.len {
if variants[i].has_flag(.generic) {
sym := t.sym(variants[i])
if sym.kind in [.struct_, .sum_type, .interface_] {
variants[i] = t.unwrap_generic_type(variants[i], generic_names,
concrete_types)
} else {
if t_typ := t.resolve_generic_to_concrete(variants[i], generic_names,
concrete_types)
{
variants[i] = t_typ
}
}
}
}
mut info := ts.info
info.is_generic = false
info.concrete_types = final_concrete_types
info.parent_type = typ
info.fields = fields
info.variants = variants
new_idx := t.register_sym(
kind: .sum_type
name: nrt
cname: util.no_dots(c_nrt)
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 { Interface {
// resolve generic types inside methods // resolve generic types inside methods
mut imethods := ts.info.methods.clone() mut imethods := ts.info.methods.clone()

View File

@ -980,14 +980,13 @@ pub mut:
} }
pub struct SumType { pub struct SumType {
pub:
variants []Type
pub mut: pub mut:
fields []StructField fields []StructField
found_fields bool found_fields bool
is_anon bool is_anon bool
// generic sumtype support // generic sumtype support
is_generic bool is_generic bool
variants []Type
generic_types []Type generic_types []Type
concrete_types []Type concrete_types []Type
parent_type Type parent_type Type

View File

@ -0,0 +1,28 @@
pub type Result<S> = Ok<S> | string
pub fn (x Result<S>) unwrap<S>() ?S {
match x {
Ok<S> {
return x.value
}
string {
return error(x)
}
}
}
struct Ok<S> {
value S
}
pub fn ok<S>(value S) Result<S> {
return Ok<S>{value}
}
fn test_generic_symtype_init_in_generic_fn_call() {
x := ok<int>(42)
ret := x.unwrap() or { 0 }
println(ret)
assert ret == 42
}