ast.table: simplify resolve_generic_by_names/types() (#9834)
parent
dd00c79861
commit
d02822f456
|
@ -989,10 +989,10 @@ pub fn (mut t Table) bitsize_to_type(bit_size int) Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve_generic_by_names resolves generics to real types T => int.
|
// resolve_generic_to_concrete resolves generics to real types T => int.
|
||||||
// Even map[string]map[string]T can be resolved.
|
// Even map[string]map[string]T can be resolved.
|
||||||
// This is used for resolving the generic return type of CallExpr white `unwrap_generic` is used to resolve generic usage in FnDecl.
|
// This is used for resolving the generic return type of CallExpr white `unwrap_generic` is used to resolve generic usage in FnDecl.
|
||||||
pub fn (mut t Table) resolve_generic_by_names(generic_type Type, generic_names []string, concrete_types []Type) ?Type {
|
pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_names []string, concrete_types []Type) ?Type {
|
||||||
mut sym := t.get_type_symbol(generic_type)
|
mut sym := t.get_type_symbol(generic_type)
|
||||||
if sym.name in generic_names {
|
if sym.name in generic_names {
|
||||||
index := generic_names.index(sym.name)
|
index := generic_names.index(sym.name)
|
||||||
|
@ -1008,13 +1008,13 @@ pub fn (mut t Table) resolve_generic_by_names(generic_type Type, generic_names [
|
||||||
elem_sym = t.get_type_symbol(elem_type)
|
elem_sym = t.get_type_symbol(elem_type)
|
||||||
dims++
|
dims++
|
||||||
}
|
}
|
||||||
if typ := t.resolve_generic_by_names(elem_type, generic_names, concrete_types) {
|
if typ := t.resolve_generic_to_concrete(elem_type, generic_names, concrete_types) {
|
||||||
idx := t.find_or_register_array_with_dims(typ, dims)
|
idx := t.find_or_register_array_with_dims(typ, dims)
|
||||||
return new_type(idx).derive(generic_type).clear_flag(.generic)
|
return new_type(idx).derive(generic_type).clear_flag(.generic)
|
||||||
}
|
}
|
||||||
} else if sym.kind == .chan {
|
} else if sym.kind == .chan {
|
||||||
info := sym.info as Chan
|
info := sym.info as Chan
|
||||||
if typ := t.resolve_generic_by_names(info.elem_type, generic_names, concrete_types) {
|
if typ := t.resolve_generic_to_concrete(info.elem_type, generic_names, concrete_types) {
|
||||||
idx := t.find_or_register_chan(typ, typ.nr_muls() > 0)
|
idx := t.find_or_register_chan(typ, typ.nr_muls() > 0)
|
||||||
return new_type(idx).derive(generic_type).clear_flag(.generic)
|
return new_type(idx).derive(generic_type).clear_flag(.generic)
|
||||||
}
|
}
|
||||||
|
@ -1022,7 +1022,7 @@ pub fn (mut t Table) resolve_generic_by_names(generic_type Type, generic_names [
|
||||||
mut types := []Type{}
|
mut types := []Type{}
|
||||||
mut type_changed := false
|
mut type_changed := false
|
||||||
for ret_type in sym.info.types {
|
for ret_type in sym.info.types {
|
||||||
if typ := t.resolve_generic_by_names(ret_type, generic_names, concrete_types) {
|
if typ := t.resolve_generic_to_concrete(ret_type, generic_names, concrete_types) {
|
||||||
types << typ
|
types << typ
|
||||||
type_changed = true
|
type_changed = true
|
||||||
} else {
|
} else {
|
||||||
|
@ -1037,76 +1037,11 @@ pub fn (mut t Table) resolve_generic_by_names(generic_type Type, generic_names [
|
||||||
mut type_changed := false
|
mut type_changed := false
|
||||||
mut unwrapped_key_type := sym.info.key_type
|
mut unwrapped_key_type := sym.info.key_type
|
||||||
mut unwrapped_value_type := sym.info.value_type
|
mut unwrapped_value_type := sym.info.value_type
|
||||||
if typ := t.resolve_generic_by_names(sym.info.key_type, generic_names, concrete_types) {
|
if typ := t.resolve_generic_to_concrete(sym.info.key_type, generic_names, concrete_types) {
|
||||||
unwrapped_key_type = typ
|
unwrapped_key_type = typ
|
||||||
type_changed = true
|
type_changed = true
|
||||||
}
|
}
|
||||||
if typ := t.resolve_generic_by_names(sym.info.value_type, generic_names, concrete_types) {
|
if typ := t.resolve_generic_to_concrete(sym.info.value_type, generic_names, concrete_types) {
|
||||||
unwrapped_value_type = typ
|
|
||||||
type_changed = true
|
|
||||||
}
|
|
||||||
if type_changed {
|
|
||||||
idx := t.find_or_register_map(unwrapped_key_type, unwrapped_value_type)
|
|
||||||
return new_type(idx).derive(generic_type).clear_flag(.generic)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return none
|
|
||||||
}
|
|
||||||
|
|
||||||
// resolve_generic_by_types resolves generics to real types T => int.
|
|
||||||
// Even map[string]map[string]T can be resolved.
|
|
||||||
// This is used for resolving the generic return type of CallExpr white `unwrap_generic` is used to resolve generic usage in FnDecl.
|
|
||||||
pub fn (mut t Table) resolve_generic_by_types(generic_type Type, generic_types []Type, concrete_types []Type) ?Type {
|
|
||||||
mut sym := t.get_type_symbol(generic_type)
|
|
||||||
gtype := generic_type.set_nr_muls(0) // resolve &T &&T
|
|
||||||
if gtype in generic_types {
|
|
||||||
index := generic_types.index(gtype)
|
|
||||||
typ := concrete_types[index]
|
|
||||||
return typ.derive(generic_type).clear_flag(.generic)
|
|
||||||
} else if sym.kind == .array {
|
|
||||||
info := sym.info as Array
|
|
||||||
mut elem_type := info.elem_type
|
|
||||||
mut elem_sym := t.get_type_symbol(elem_type)
|
|
||||||
mut dims := 1
|
|
||||||
for mut elem_sym.info is Array {
|
|
||||||
elem_type = elem_sym.info.elem_type
|
|
||||||
elem_sym = t.get_type_symbol(elem_type)
|
|
||||||
dims++
|
|
||||||
}
|
|
||||||
if typ := t.resolve_generic_by_types(elem_type, generic_types, concrete_types) {
|
|
||||||
idx := t.find_or_register_array_with_dims(typ, dims)
|
|
||||||
return new_type(idx).derive(generic_type).clear_flag(.generic)
|
|
||||||
}
|
|
||||||
} else if sym.kind == .chan {
|
|
||||||
info := sym.info as Chan
|
|
||||||
if typ := t.resolve_generic_by_types(info.elem_type, generic_types, concrete_types) {
|
|
||||||
idx := t.find_or_register_chan(typ, typ.nr_muls() > 0)
|
|
||||||
return new_type(idx).derive(generic_type).clear_flag(.generic)
|
|
||||||
}
|
|
||||||
} else if mut sym.info is MultiReturn {
|
|
||||||
mut types := []Type{}
|
|
||||||
mut type_changed := false
|
|
||||||
for ret_type in sym.info.types {
|
|
||||||
if typ := t.resolve_generic_by_types(ret_type, generic_types, concrete_types) {
|
|
||||||
types << typ
|
|
||||||
type_changed = true
|
|
||||||
} else {
|
|
||||||
types << ret_type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if type_changed {
|
|
||||||
idx := t.find_or_register_multi_return(types)
|
|
||||||
return new_type(idx).derive(generic_type).clear_flag(.generic)
|
|
||||||
}
|
|
||||||
} else if mut sym.info is Map {
|
|
||||||
mut type_changed := false
|
|
||||||
mut unwrapped_key_type := sym.info.key_type
|
|
||||||
mut unwrapped_value_type := sym.info.value_type
|
|
||||||
if typ := t.resolve_generic_by_types(sym.info.key_type, generic_types, concrete_types) {
|
|
||||||
unwrapped_key_type = typ
|
|
||||||
type_changed = true
|
|
||||||
}
|
|
||||||
if typ := t.resolve_generic_by_types(sym.info.value_type, generic_types, concrete_types) {
|
|
||||||
unwrapped_value_type = typ
|
unwrapped_value_type = typ
|
||||||
type_changed = true
|
type_changed = true
|
||||||
}
|
}
|
||||||
|
@ -1132,8 +1067,9 @@ pub fn (mut t Table) generic_struct_insts_to_concrete() {
|
||||||
mut parent_info := parent.info as Struct
|
mut parent_info := parent.info as Struct
|
||||||
mut fields := parent_info.fields.clone()
|
mut fields := parent_info.fields.clone()
|
||||||
if parent_info.generic_types.len == info.generic_types.len {
|
if parent_info.generic_types.len == info.generic_types.len {
|
||||||
|
generic_names := parent_info.generic_types.map(t.get_type_symbol(it).name)
|
||||||
for i in 0 .. fields.len {
|
for i in 0 .. fields.len {
|
||||||
if t_typ := t.resolve_generic_by_types(fields[i].typ, parent_info.generic_types,
|
if t_typ := t.resolve_generic_to_concrete(fields[i].typ, generic_names,
|
||||||
info.generic_types)
|
info.generic_types)
|
||||||
{
|
{
|
||||||
fields[i].typ = t_typ
|
fields[i].typ = t_typ
|
||||||
|
|
|
@ -1444,9 +1444,10 @@ fn (mut c Checker) check_return_generics_struct(return_type ast.Type, mut call_e
|
||||||
} else {
|
} else {
|
||||||
mut fields := rts.info.fields.clone()
|
mut fields := rts.info.fields.clone()
|
||||||
if rts.info.generic_types.len == generic_types.len {
|
if rts.info.generic_types.len == generic_types.len {
|
||||||
|
generic_names := rts.info.generic_types.map(c.table.get_type_symbol(it).name)
|
||||||
for i, _ in fields {
|
for i, _ in fields {
|
||||||
if t_typ := c.table.resolve_generic_by_types(fields[i].typ, rts.info.generic_types,
|
if t_typ := c.table.resolve_generic_to_concrete(fields[i].typ,
|
||||||
generic_types)
|
generic_names, generic_types)
|
||||||
{
|
{
|
||||||
fields[i].typ = t_typ
|
fields[i].typ = t_typ
|
||||||
}
|
}
|
||||||
|
@ -1744,7 +1745,7 @@ pub fn (mut c Checker) method_call(mut call_expr ast.CallExpr) ast.Type {
|
||||||
c.infer_fn_generic_types(method, mut call_expr)
|
c.infer_fn_generic_types(method, mut call_expr)
|
||||||
}
|
}
|
||||||
if call_expr.generic_types.len > 0 && method.return_type != 0 {
|
if call_expr.generic_types.len > 0 && method.return_type != 0 {
|
||||||
if typ := c.table.resolve_generic_by_names(method.return_type, method.generic_names,
|
if typ := c.table.resolve_generic_to_concrete(method.return_type, method.generic_names,
|
||||||
call_expr.generic_types)
|
call_expr.generic_types)
|
||||||
{
|
{
|
||||||
call_expr.return_type = typ
|
call_expr.return_type = typ
|
||||||
|
@ -2264,7 +2265,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type {
|
||||||
typ := c.check_expr_opt_call(call_arg.expr, c.expr(call_arg.expr))
|
typ := c.check_expr_opt_call(call_arg.expr, c.expr(call_arg.expr))
|
||||||
|
|
||||||
if param.typ.has_flag(.generic) && func.generic_names.len == call_expr.generic_types.len {
|
if param.typ.has_flag(.generic) && func.generic_names.len == call_expr.generic_types.len {
|
||||||
if unwrap_typ := c.table.resolve_generic_by_names(param.typ, func.generic_names,
|
if unwrap_typ := c.table.resolve_generic_to_concrete(param.typ, func.generic_names,
|
||||||
call_expr.generic_types)
|
call_expr.generic_types)
|
||||||
{
|
{
|
||||||
c.check_expected_call_arg(typ, unwrap_typ, call_expr.language) or {
|
c.check_expected_call_arg(typ, unwrap_typ, call_expr.language) or {
|
||||||
|
@ -2275,7 +2276,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if call_expr.generic_types.len > 0 && func.return_type != 0 {
|
if call_expr.generic_types.len > 0 && func.return_type != 0 {
|
||||||
if typ := c.table.resolve_generic_by_names(func.return_type, func.generic_names,
|
if typ := c.table.resolve_generic_to_concrete(func.return_type, func.generic_names,
|
||||||
call_expr.generic_types)
|
call_expr.generic_types)
|
||||||
{
|
{
|
||||||
call_expr.return_type = typ
|
call_expr.return_type = typ
|
||||||
|
@ -4124,7 +4125,7 @@ fn (mut c Checker) stmts(stmts []ast.Stmt) {
|
||||||
|
|
||||||
pub fn (mut c Checker) unwrap_generic(typ ast.Type) ast.Type {
|
pub fn (mut c Checker) unwrap_generic(typ ast.Type) ast.Type {
|
||||||
if typ.has_flag(.generic) {
|
if typ.has_flag(.generic) {
|
||||||
if t_typ := c.table.resolve_generic_by_names(typ, c.cur_fn.generic_names, c.cur_fn.cur_generic_types) {
|
if t_typ := c.table.resolve_generic_to_concrete(typ, c.cur_fn.generic_names, c.cur_fn.cur_generic_types) {
|
||||||
return t_typ
|
return t_typ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -477,7 +477,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
|
||||||
|
|
||||||
pub fn (mut g Gen) unwrap_generic(typ ast.Type) ast.Type {
|
pub fn (mut g Gen) unwrap_generic(typ ast.Type) ast.Type {
|
||||||
if typ.has_flag(.generic) {
|
if typ.has_flag(.generic) {
|
||||||
if t_typ := g.table.resolve_generic_by_names(typ, g.cur_fn.generic_names, g.cur_generic_types) {
|
if t_typ := g.table.resolve_generic_to_concrete(typ, g.cur_fn.generic_names, g.cur_generic_types) {
|
||||||
return t_typ
|
return t_typ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue