1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

mutable args: don't allow primitives

This commit is contained in:
Alexander Medvednikov 2019-07-24 15:24:32 +02:00
parent 7ea688aa43
commit 6b2063a2ea
3 changed files with 39 additions and 6 deletions

View File

@ -626,17 +626,21 @@ fn (p mut Parser) fn_args(f mut Fn) {
if is_mut { if is_mut {
p.next() p.next()
} }
mut typ2 := p.get_type() mut typ := p.get_type()
if is_mut && is_primitive_type(typ) {
p.error('mutable arguments are only allowed for arrays, maps, and structs.' +
'\nreturn values instead: `foo(n mut int)` => `foo(n int) int`')
}
for name in names { for name in names {
if !p.first_run() && !p.table.known_type(typ2) { if !p.first_run() && !p.table.known_type(typ) {
p.error('fn_args: unknown type $typ2') p.error('fn_args: unknown type $typ')
} }
if is_mut { if is_mut {
typ2 += '*' typ += '*'
} }
v := Var { v := Var {
name: name name: name
typ: typ2 typ: typ
is_arg: true is_arg: true
is_mut: is_mut is_mut: is_mut
ptr: is_mut ptr: is_mut

View File

@ -113,6 +113,10 @@ fn is_float_type(typ string) bool {
return FLOAT_TYPES.contains(typ) return FLOAT_TYPES.contains(typ)
} }
fn is_primitive_type(typ string) bool {
return is_number_type(typ) || typ == 'string'
}
fn new_table(obfuscate bool) *Table { fn new_table(obfuscate bool) *Table {
mut t := &Table { mut t := &Table {
obf_ids: map[string]int{} obf_ids: map[string]int{}

View File

@ -71,7 +71,7 @@ fn modify_array(a mut []int) {
a << 888 a << 888
} }
fn test_mut() { fn test_mut_array() {
mut nums := [1, 2, 3] mut nums := [1, 2, 3]
modify_array(mut nums) modify_array(mut nums)
assert nums.len == 4 assert nums.len == 4
@ -81,6 +81,31 @@ fn test_mut() {
assert nums[3] == 888 assert nums[3] == 888
} }
fn mod_struct(user mut User) {
user.age++
}
struct User {
mut:
age int
}
fn test_mut_struct() {
mut user := User{18}
mod_struct(mut user)
assert user.age == 19
}
fn mod_ptr(buf mut byteptr) {
buf[0] = 77
}
fn test_mut_ptr() {
buf := malloc(10)
mod_ptr(mut buf)
assert buf[0] == 77
}
fn test_fns() { fn test_fns() {
// no asserts for now, just test function declarations above // no asserts for now, just test function declarations above
} }