checker: check using literal argument as reference parameter (#14674)
parent
f6ebbc99cd
commit
4cf6abd99d
|
@ -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
|
||||||
|
|
|
@ -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 | }
|
|
@ -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)
|
||||||
|
}
|
Loading…
Reference in New Issue