checker: cleanup infer_fn_generic_types() (#12515)

pull/12518/head
yuyi 2021-11-19 16:24:03 +08:00 committed by GitHub
parent 24ba660367
commit d498c365c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 19 additions and 17 deletions

View File

@ -573,20 +573,20 @@ pub fn (mut c Checker) int_lit(mut node ast.IntegerLiteral) ast.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{}
for gi, gt_name in f.generic_names {
for gi, gt_name in func.generic_names {
// skip known types
if gi < call_expr.concrete_types.len {
inferred_types << call_expr.concrete_types[gi]
if gi < node.concrete_types.len {
inferred_types << node.concrete_types[gi]
continue
}
mut typ := ast.void_type
for i, param in f.params {
for i, param in func.params {
mut to_set := ast.void_type
// resolve generic struct receiver
if i == 0 && call_expr.is_method && param.typ.has_flag(.generic) {
sym := c.table.get_type_symbol(call_expr.receiver_type)
if i == 0 && node.is_method && param.typ.has_flag(.generic) {
sym := c.table.get_type_symbol(node.receiver_type)
match sym.info {
ast.Struct, ast.Interface, ast.SumType {
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 {}
}
}
arg_i := if i != 0 && call_expr.is_method { i - 1 } else { i }
if call_expr.args.len <= arg_i {
arg_i := if i != 0 && node.is_method { i - 1 } else { i }
if node.args.len <= arg_i {
break
}
arg := call_expr.args[arg_i]
arg := node.args[arg_i]
param_type_sym := c.table.get_type_symbol(param.typ)
if param.typ.has_flag(.generic) && param_type_sym.name == gt_name {
to_set = c.table.mktyp(arg.typ)
sym := c.table.get_type_symbol(arg.typ)
if sym.info is ast.FnType {
mut func := sym.info.func
func.name = ''
idx := c.table.find_or_register_fn_type(c.mod, func, true, false)
mut func_ := sym.info.func
func_.name = ''
idx := c.table.find_or_register_fn_type(c.mod, func_, true, false)
to_set = ast.new_type(idx).derive(arg.typ)
}
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 {
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
}
if c.pref.is_verbose {
s := c.table.type_to_str(typ)
println('inferred `$f.name<$s>`')
println('inferred `$func.name<$s>`')
}
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
}
}