checker: fix missing concrete type checking on a generic type specifier (#21614)

This commit is contained in:
Felipe Pena 2024-06-01 20:10:48 -03:00 committed by GitHub
parent 7cff1f7972
commit 2e567ff9e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 26 additions and 0 deletions

View File

@ -0,0 +1,7 @@
vlib/v/checker/tests/missing_concrete_type_err.vv:4:6: error: missing concrete type on generic type
2 |
3 | fn main() {
4 | bar[Foo]()
| ~~~
5 | }
6 |

View File

@ -0,0 +1,9 @@
struct Foo[T] {}
fn main() {
bar[Foo]()
}
fn bar[T]() {
}

View File

@ -542,6 +542,11 @@ fn (mut p Parser) parse_type() ast.Type {
return 0 return 0
} }
sym := p.table.sym(typ) sym := p.table.sym(typ)
if p.inside_fn_concrete_type && sym.info is ast.Struct {
if !typ.has_flag(.generic) && sym.info.generic_types.len > 0 {
p.error_with_pos('missing concrete type on generic type', option_pos.extend(p.prev_tok.pos()))
}
}
if is_option && sym.info is ast.SumType && sym.info.is_anon { if is_option && sym.info is ast.SumType && sym.info.is_anon {
p.error_with_pos('an inline sum type cannot be an Option', option_pos.extend(p.prev_tok.pos())) p.error_with_pos('an inline sum type cannot be an Option', option_pos.extend(p.prev_tok.pos()))
} }

View File

@ -47,6 +47,7 @@ mut:
inside_for_expr bool inside_for_expr bool
inside_fn bool // true even with implicit main inside_fn bool // true even with implicit main
inside_fn_return bool inside_fn_return bool
inside_fn_concrete_type bool // parsing fn_name[concrete_type]() call expr
inside_call_args bool // true inside f( .... ) inside_call_args bool // true inside f( .... )
inside_unsafe_fn bool inside_unsafe_fn bool
inside_str_interp bool inside_str_interp bool
@ -3369,6 +3370,10 @@ fn (mut p Parser) parse_concrete_types() []ast.Type {
if p.tok.kind !in [.lt, .lsbr] { if p.tok.kind !in [.lt, .lsbr] {
return types return types
} }
p.inside_fn_concrete_type = true
defer {
p.inside_fn_concrete_type = false
}
end_kind := if p.tok.kind == .lt { token.Kind.gt } else { token.Kind.rsbr } end_kind := if p.tok.kind == .lt { token.Kind.gt } else { token.Kind.rsbr }
p.next() // `<` p.next() // `<`
mut first_done := false mut first_done := false