checker: ban any_int/any_float outside buitlin (#7675)
parent
3e44393152
commit
a9ab79d301
|
@ -292,17 +292,17 @@ pub:
|
|||
is_variadic bool
|
||||
is_anon bool
|
||||
receiver Field
|
||||
receiver_pos token.Position
|
||||
receiver_pos token.Position // `(u User)` in `fn (u User) name()` position
|
||||
is_method bool
|
||||
method_type_pos token.Position
|
||||
method_type_pos token.Position // `User` in ` fn (u User)` position
|
||||
method_idx int
|
||||
rec_mut bool // is receiver mutable
|
||||
rec_share table.ShareType
|
||||
language table.Language
|
||||
no_body bool // just a definition `fn C.malloc()`
|
||||
is_builtin bool // this function is defined in builtin/strconv
|
||||
pos token.Position
|
||||
body_pos token.Position
|
||||
pos token.Position // function declaration position
|
||||
body_pos token.Position // function bodys position
|
||||
file string
|
||||
is_generic bool
|
||||
is_direct_arr bool // direct array access
|
||||
|
|
|
@ -316,7 +316,7 @@ pub fn (mut c Checker) type_decl(node ast.TypeDecl) {
|
|||
c.check_valid_pascal_case(node.name, 'type alias', node.pos)
|
||||
}
|
||||
typ_sym := c.table.get_type_symbol(node.parent_type)
|
||||
if typ_sym.kind == .placeholder {
|
||||
if typ_sym.kind in [.placeholder, .any_int, .any_float] {
|
||||
c.error("type `$typ_sym.name` doesn't exist", node.pos)
|
||||
} else if typ_sym.kind == .alias {
|
||||
orig_sym := c.table.get_type_symbol((typ_sym.info as table.Alias).parent_type)
|
||||
|
@ -353,10 +353,10 @@ pub fn (mut c Checker) type_decl(node ast.TypeDecl) {
|
|||
if sym.name in names_used {
|
||||
c.error('sum type $node.name cannot hold the type `$sym.name` more than once',
|
||||
variant.pos)
|
||||
} else if sym.kind == .placeholder {
|
||||
c.error("type `$sym.name` doesn't exist", node.pos)
|
||||
} else if sym.kind in [.placeholder, .any_int, .any_float] {
|
||||
c.error("type `$sym.name` doesn't exist", variant.pos)
|
||||
} else if sym.kind == .interface_ {
|
||||
c.error('sum type cannot hold an interface', node.pos)
|
||||
c.error('sum type cannot hold an interface', variant.pos)
|
||||
}
|
||||
names_used << sym.name
|
||||
}
|
||||
|
@ -397,6 +397,16 @@ pub fn (mut c Checker) struct_decl(decl ast.StructDecl) {
|
|||
c.error(util.new_suggestion(sym.name, c.table.known_type_names()).say('unknown type `$sym.name`'),
|
||||
field.type_pos)
|
||||
}
|
||||
// Separate error condition for `any_int` and `any_float` because `util.suggestion` may give different
|
||||
// suggestions due to f32 comparision issue.
|
||||
if sym.kind in [.any_int, .any_float] {
|
||||
msg := if sym.kind == .any_int {
|
||||
'unknown type `$sym.name`.\nDid you mean `int`?'
|
||||
} else {
|
||||
'unknown type `$sym.name`.\nDid you mean `f64`?'
|
||||
}
|
||||
c.error(msg, field.type_pos)
|
||||
}
|
||||
if sym.kind == .array {
|
||||
array_info := sym.array_info()
|
||||
elem_sym := c.table.get_type_symbol(array_info.elem_type)
|
||||
|
@ -4861,11 +4871,17 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
|||
// Make sure all types are valid
|
||||
for arg in node.params {
|
||||
sym := c.table.get_type_symbol(arg.typ)
|
||||
if sym.kind == .placeholder {
|
||||
c.error('unknown type `$sym.name`', node.method_type_pos)
|
||||
if sym.kind == .placeholder ||
|
||||
(sym.kind in [table.Kind.any_int, .any_float] && !c.is_builtin_mod) {
|
||||
c.error('unknown type `$sym.name`', node.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
return_sym := c.table.get_type_symbol(node.return_type)
|
||||
if node.language == .v &&
|
||||
return_sym.kind in [.placeholder, .any_int, .any_float] && return_sym.language == .v {
|
||||
c.error('unknown type `$return_sym.name`', node.pos)
|
||||
}
|
||||
if node.language == .v && node.is_method && node.name == 'str' {
|
||||
if node.return_type != table.string_type {
|
||||
c.error('.str() methods should return `string`', node.pos)
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
vlib/v/checker/tests/any_int_float_ban_err.vv:1:12: error: type `any_int` doesn't exist
|
||||
1 | type Foo = any_int | any_float
|
||||
| ~~~~~~~
|
||||
2 | type Fo2 = any_int
|
||||
3 |
|
||||
vlib/v/checker/tests/any_int_float_ban_err.vv:2:1: error: type `any_int` doesn't exist
|
||||
1 | type Foo = any_int | any_float
|
||||
2 | type Fo2 = any_int
|
||||
| ~~~~~~~~
|
||||
3 |
|
||||
4 | struct Int {
|
||||
vlib/v/checker/tests/any_int_float_ban_err.vv:5:7: error: unknown type `any_int`.
|
||||
Did you mean `int`?
|
||||
3 |
|
||||
4 | struct Int {
|
||||
5 | i any_int
|
||||
| ~~~~~~~
|
||||
6 | f any_float
|
||||
7 | }
|
||||
vlib/v/checker/tests/any_int_float_ban_err.vv:6:7: error: unknown type `any_float`.
|
||||
Did you mean `f64`?
|
||||
4 | struct Int {
|
||||
5 | i any_int
|
||||
6 | f any_float
|
||||
| ~~~~~~~~~
|
||||
7 | }
|
||||
8 |
|
||||
vlib/v/checker/tests/any_int_float_ban_err.vv:9:1: error: unknown type `any_int`
|
||||
7 | }
|
||||
8 |
|
||||
9 | fn foo(i any_int) any_int {
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
10 | return i
|
||||
11 | }
|
||||
vlib/v/checker/tests/any_int_float_ban_err.vv:13:1: error: unknown type `any_int`
|
||||
11 | }
|
||||
12 |
|
||||
13 | fn foo2() any_int {
|
||||
| ~~~~~~~~~~~~~~~~~
|
||||
14 | return 1
|
||||
15 | }
|
|
@ -0,0 +1,15 @@
|
|||
type Foo = any_int | any_float
|
||||
type Fo2 = any_int
|
||||
|
||||
struct Int {
|
||||
i any_int
|
||||
f any_float
|
||||
}
|
||||
|
||||
fn foo(i any_int) any_int {
|
||||
return i
|
||||
}
|
||||
|
||||
fn foo2() any_int {
|
||||
return 1
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
vlib/v/checker/tests/sum_type_exists.vv:1:1: error: type `Nope` doesn't exist
|
||||
vlib/v/checker/tests/sum_type_exists.vv:1:22: error: type `Nope` doesn't exist
|
||||
1 | type Miscellaneous = Nope | Inexistant | int
|
||||
| ~~~~~~~~~~~~~~~~~~
|
||||
2 |
|
||||
| ~~~~
|
||||
2 |
|
||||
3 | fn main() {
|
||||
|
|
|
@ -732,7 +732,8 @@ pub fn (table &Table) sumtype_has_variant(parent Type, variant Type) bool {
|
|||
pub fn (table &Table) known_type_names() []string {
|
||||
mut res := []string{}
|
||||
for _, idx in table.type_idxs {
|
||||
if idx == 0 {
|
||||
// Skip `any_int_type_idx` and `any_flt_type_idx` because they shouldn't be visible to the User.
|
||||
if idx in [0, any_int_type_idx, any_flt_type_idx] {
|
||||
continue
|
||||
}
|
||||
res << table.type_to_str(idx)
|
||||
|
|
|
@ -11,7 +11,7 @@ import v.util
|
|||
import v.pref
|
||||
|
||||
// `Any` is a sum type that lists the possible types to be decoded and used.
|
||||
pub type Any = string | int | i64 | f32 | f64 | any_int | any_float | bool | Null | []Any | map[string]Any
|
||||
pub type Any = string | int | i64 | f32 | f64 | bool | Null | []Any | map[string]Any
|
||||
|
||||
// `Null` struct is a simple representation of the `null` value in JSON.
|
||||
pub struct Null {
|
||||
|
|
|
@ -79,12 +79,6 @@ pub fn (f Any) str() string {
|
|||
str_f64
|
||||
}
|
||||
}
|
||||
any_int {
|
||||
return f.str()
|
||||
}
|
||||
any_float {
|
||||
return f.str()
|
||||
}
|
||||
bool {
|
||||
return f.str()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue