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

yuyi 2022-06-05 13:44:35 +08:00 committed by Chewing_Bever
parent a0f1c1ffef
commit 799d2dce4d
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
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
}
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,
call_arg) or {
if param.typ.has_flag(.generic) {
@ -1433,6 +1438,10 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
}
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 {
// str method, allow type with str method if fn arg is string
// 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)
}