checker: cleanup infer_fn_generic_types() (#12515)
parent
24ba660367
commit
d498c365c2
|
@ -573,20 +573,20 @@ pub fn (mut c Checker) int_lit(mut node ast.IntegerLiteral) ast.Type {
|
||||||
return ast.int_literal_type
|
return ast.int_literal_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallExpr) {
|
pub fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr) {
|
||||||
mut inferred_types := []ast.Type{}
|
mut inferred_types := []ast.Type{}
|
||||||
for gi, gt_name in f.generic_names {
|
for gi, gt_name in func.generic_names {
|
||||||
// skip known types
|
// skip known types
|
||||||
if gi < call_expr.concrete_types.len {
|
if gi < node.concrete_types.len {
|
||||||
inferred_types << call_expr.concrete_types[gi]
|
inferred_types << node.concrete_types[gi]
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
mut typ := ast.void_type
|
mut typ := ast.void_type
|
||||||
for i, param in f.params {
|
for i, param in func.params {
|
||||||
mut to_set := ast.void_type
|
mut to_set := ast.void_type
|
||||||
// resolve generic struct receiver
|
// resolve generic struct receiver
|
||||||
if i == 0 && call_expr.is_method && param.typ.has_flag(.generic) {
|
if i == 0 && node.is_method && param.typ.has_flag(.generic) {
|
||||||
sym := c.table.get_type_symbol(call_expr.receiver_type)
|
sym := c.table.get_type_symbol(node.receiver_type)
|
||||||
match sym.info {
|
match sym.info {
|
||||||
ast.Struct, ast.Interface, ast.SumType {
|
ast.Struct, ast.Interface, ast.SumType {
|
||||||
if c.table.cur_fn.generic_names.len > 0 { // in generic fn
|
if c.table.cur_fn.generic_names.len > 0 { // in generic fn
|
||||||
|
@ -607,20 +607,20 @@ pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallEx
|
||||||
else {}
|
else {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
arg_i := if i != 0 && call_expr.is_method { i - 1 } else { i }
|
arg_i := if i != 0 && node.is_method { i - 1 } else { i }
|
||||||
if call_expr.args.len <= arg_i {
|
if node.args.len <= arg_i {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
arg := call_expr.args[arg_i]
|
arg := node.args[arg_i]
|
||||||
param_type_sym := c.table.get_type_symbol(param.typ)
|
param_type_sym := c.table.get_type_symbol(param.typ)
|
||||||
|
|
||||||
if param.typ.has_flag(.generic) && param_type_sym.name == gt_name {
|
if param.typ.has_flag(.generic) && param_type_sym.name == gt_name {
|
||||||
to_set = c.table.mktyp(arg.typ)
|
to_set = c.table.mktyp(arg.typ)
|
||||||
sym := c.table.get_type_symbol(arg.typ)
|
sym := c.table.get_type_symbol(arg.typ)
|
||||||
if sym.info is ast.FnType {
|
if sym.info is ast.FnType {
|
||||||
mut func := sym.info.func
|
mut func_ := sym.info.func
|
||||||
func.name = ''
|
func_.name = ''
|
||||||
idx := c.table.find_or_register_fn_type(c.mod, func, true, false)
|
idx := c.table.find_or_register_fn_type(c.mod, func_, true, false)
|
||||||
to_set = ast.new_type(idx).derive(arg.typ)
|
to_set = ast.new_type(idx).derive(arg.typ)
|
||||||
}
|
}
|
||||||
if arg.expr.is_auto_deref_var() {
|
if arg.expr.is_auto_deref_var() {
|
||||||
|
@ -720,17 +720,19 @@ pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallEx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if typ == ast.void_type {
|
if typ == ast.void_type {
|
||||||
c.error('could not infer generic type `$gt_name` in call to `$f.name`', call_expr.pos)
|
c.error('could not infer generic type `$gt_name` in call to `$func.name`',
|
||||||
|
node.pos)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if c.pref.is_verbose {
|
if c.pref.is_verbose {
|
||||||
s := c.table.type_to_str(typ)
|
s := c.table.type_to_str(typ)
|
||||||
println('inferred `$f.name<$s>`')
|
println('inferred `$func.name<$s>`')
|
||||||
}
|
}
|
||||||
inferred_types << typ
|
inferred_types << typ
|
||||||
call_expr.concrete_types << typ
|
node.concrete_types << typ
|
||||||
}
|
}
|
||||||
if c.table.register_fn_concrete_types(f.name, inferred_types) {
|
|
||||||
|
if c.table.register_fn_concrete_types(func.name, inferred_types) {
|
||||||
c.need_recheck_generic_fns = true
|
c.need_recheck_generic_fns = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue