checker: check using literal argument as reference parameter (#14674)

master
yuyi 2022-06-05 13:44:35 +08:00 committed by GitHub
parent f6ebbc99cd
commit 4cf6abd99d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 0 deletions

View File

@ -897,6 +897,11 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
} }
continue continue
} }
if param.typ.is_ptr() && !param.is_mut && !call_arg.typ.is_real_pointer()
&& call_arg.expr.is_literal() && func.language == .v {
c.error('literal argument cannot be passed as reference parameter `${c.table.type_to_str(param.typ)}`',
call_arg.pos)
}
c.check_expected_call_arg(arg_typ, c.unwrap_generic(param.typ), node.language, c.check_expected_call_arg(arg_typ, c.unwrap_generic(param.typ), node.language,
call_arg) or { call_arg) or {
if param.typ.has_flag(.generic) { if param.typ.has_flag(.generic) {
@ -1433,6 +1438,10 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
} }
continue continue
} }
if param.typ.is_ptr() && !arg.typ.is_real_pointer() && arg.expr.is_literal() {
c.error('literal argument cannot be passed as reference parameter `${c.table.type_to_str(param.typ)}`',
arg.pos)
}
c.check_expected_call_arg(got_arg_typ, exp_arg_typ, node.language, arg) or { c.check_expected_call_arg(got_arg_typ, exp_arg_typ, node.language, arg) or {
// str method, allow type with str method if fn arg is string // str method, allow type with str method if fn arg is string
// Passing an int or a string array produces a c error here // Passing an int or a string array produces a c error here

View File

@ -0,0 +1,13 @@
vlib/v/checker/tests/fn_ref_arg_mismatch_err.vv:15:10: error: literal argument cannot be passed as reference parameter `&T`
13 | fn main() {
14 | foo := Foo<int>{}
15 | foo.foo(12)
| ~~
16 |
17 | bar<int>(12)
vlib/v/checker/tests/fn_ref_arg_mismatch_err.vv:17:11: error: literal argument cannot be passed as reference parameter `&T`
15 | foo.foo(12)
16 |
17 | bar<int>(12)
| ~~
18 | }

View File

@ -0,0 +1,18 @@
module main
struct Foo<T> { }
fn (f &Foo<T>) foo(a &T) {
println(a)
}
fn bar<T>(a &T) {
println(a)
}
fn main() {
foo := Foo<int>{}
foo.foo(12)
bar<int>(12)
}