checker: cleanup in fn_decl() (#14802)

master
yuyi 2022-06-20 22:56:02 +08:00 committed by GitHub
parent 1fc9e1a716
commit 8703e336e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 15 additions and 20 deletions

View File

@ -134,13 +134,11 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
return return
} }
// make sure interface does not implement its own interface methods // make sure interface does not implement its own interface methods
if sym.kind == .interface_ && sym.has_method(node.name) { if mut sym.info is ast.Interface && sym.has_method(node.name) {
if mut sym.info is ast.Interface { // if the method is in info.methods then it is an interface method
// if the method is in info.methods then it is an interface method if sym.info.has_method(node.name) {
if sym.info.has_method(node.name) { c.error('interface `$sym.name` cannot implement its own interface method `$node.name`',
c.error('interface `$sym.name` cannot implement its own interface method `$node.name`', node.pos)
node.pos)
}
} }
} }
if mut sym.info is ast.Struct { if mut sym.info is ast.Struct {
@ -186,28 +184,25 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
} }
if !param.typ.is_ptr() { // value parameter, i.e. on stack - check for `[heap]` if !param.typ.is_ptr() { // value parameter, i.e. on stack - check for `[heap]`
arg_typ_sym := c.table.sym(param.typ) arg_typ_sym := c.table.sym(param.typ)
if arg_typ_sym.kind == .struct_ { if arg_typ_sym.info is ast.Struct {
info := arg_typ_sym.info as ast.Struct if arg_typ_sym.info.is_heap { // set auto_heap to promote value parameter
if info.is_heap { // set auto_heap to promote value parameter
mut v := node.scope.find_var(param.name) or { continue } mut v := node.scope.find_var(param.name) or { continue }
v.is_auto_heap = true v.is_auto_heap = true
} }
if info.generic_types.len > 0 && !param.typ.has_flag(.generic) if arg_typ_sym.info.generic_types.len > 0 && !param.typ.has_flag(.generic)
&& info.concrete_types.len == 0 { && arg_typ_sym.info.concrete_types.len == 0 {
c.error('generic struct in fn declaration must specify the generic type names, e.g. Foo<T>', c.error('generic struct in fn declaration must specify the generic type names, e.g. Foo<T>',
param.type_pos) param.type_pos)
} }
} else if arg_typ_sym.kind == .interface_ { } else if arg_typ_sym.info is ast.Interface {
info := arg_typ_sym.info as ast.Interface if arg_typ_sym.info.generic_types.len > 0 && !param.typ.has_flag(.generic)
if info.generic_types.len > 0 && !param.typ.has_flag(.generic) && arg_typ_sym.info.concrete_types.len == 0 {
&& info.concrete_types.len == 0 {
c.error('generic interface in fn declaration must specify the generic type names, e.g. Foo<T>', c.error('generic interface in fn declaration must specify the generic type names, e.g. Foo<T>',
param.type_pos) param.type_pos)
} }
} else if arg_typ_sym.kind == .sum_type { } else if arg_typ_sym.info is ast.SumType {
info := arg_typ_sym.info as ast.SumType if arg_typ_sym.info.generic_types.len > 0 && !param.typ.has_flag(.generic)
if info.generic_types.len > 0 && !param.typ.has_flag(.generic) && arg_typ_sym.info.concrete_types.len == 0 {
&& info.concrete_types.len == 0 {
c.error('generic sumtype in fn declaration must specify the generic type names, e.g. Foo<T>', c.error('generic sumtype in fn declaration must specify the generic type names, e.g. Foo<T>',
param.type_pos) param.type_pos)
} }