parser: allow passing `mut a AliasOfPointerType`
parent
52a14e8422
commit
87494fad1d
|
@ -824,13 +824,21 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
|
||||||
|
|
||||||
fn (mut p Parser) check_fn_mutable_arguments(typ table.Type, pos token.Position) {
|
fn (mut p Parser) check_fn_mutable_arguments(typ table.Type, pos token.Position) {
|
||||||
sym := p.table.get_type_symbol(typ)
|
sym := p.table.get_type_symbol(typ)
|
||||||
if sym.kind !in [.array, .array_fixed, .interface_, .map, .placeholder, .struct_, .sum_type]
|
if sym.kind in [.array, .array_fixed, .interface_, .map, .placeholder, .struct_, .sum_type] {
|
||||||
&& !typ.is_ptr() && !typ.is_pointer() {
|
return
|
||||||
p.error_with_pos(
|
|
||||||
'mutable arguments are only allowed for arrays, interfaces, maps, pointers and structs\n' +
|
|
||||||
'return values instead: `fn foo(mut n $sym.name) {` => `fn foo(n $sym.name) $sym.name {`',
|
|
||||||
pos)
|
|
||||||
}
|
}
|
||||||
|
if typ.is_ptr() || typ.is_pointer() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if sym.kind == .alias {
|
||||||
|
atyp := (sym.info as table.Alias).parent_type
|
||||||
|
p.check_fn_mutable_arguments(atyp, pos)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.error_with_pos(
|
||||||
|
'mutable arguments are only allowed for arrays, interfaces, maps, pointers, structs or their aliases\n' +
|
||||||
|
'return values instead: `fn foo(mut n $sym.name) {` => `fn foo(n $sym.name) $sym.name {`',
|
||||||
|
pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut p Parser) check_fn_shared_arguments(typ table.Type, pos token.Position) {
|
fn (mut p Parser) check_fn_shared_arguments(typ table.Type, pos token.Position) {
|
||||||
|
|
|
@ -37,3 +37,38 @@ fn test_alias_of_pointer_types() {
|
||||||
assert sizeof(PPZZInt) == sizeof(voidptr)
|
assert sizeof(PPZZInt) == sizeof(voidptr)
|
||||||
assert sizeof(PPZZMyStructInt) == sizeof(voidptr)
|
assert sizeof(PPZZMyStructInt) == sizeof(voidptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_calling_a_function_expecting_a_mut_alias() {
|
||||||
|
eprintln('------------------------')
|
||||||
|
mut s := &MyStructInt{456}
|
||||||
|
mut ps := PZZMyStructInt(s)
|
||||||
|
dump(voidptr(s))
|
||||||
|
dump(voidptr(ps))
|
||||||
|
eprintln('------------------------')
|
||||||
|
dump(&MyStructInt(ps))
|
||||||
|
res := mut_alias(mut ps)
|
||||||
|
dump(&MyStructInt(ps))
|
||||||
|
// the alias `ps` is now changed and points to another object
|
||||||
|
assert res == 123
|
||||||
|
assert s.x == 456 // should remain the same
|
||||||
|
assert (&MyStructInt(ps)).x == 789
|
||||||
|
assert u64(voidptr(s)) != u64(voidptr(ps))
|
||||||
|
dump(voidptr(s))
|
||||||
|
dump(voidptr(ps))
|
||||||
|
eprintln('------------------------')
|
||||||
|
}
|
||||||
|
|
||||||
|
// do not delete this, its generated code eases comparisons with mut_alias
|
||||||
|
fn mut_struct(mut p ZZMyStructInt) int {
|
||||||
|
dump(ptr_str(voidptr(p)))
|
||||||
|
return 999
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_alias(mut ps PZZMyStructInt) int {
|
||||||
|
// dump(ptr_str(voidptr(ps)))
|
||||||
|
another := &MyStructInt{789}
|
||||||
|
// dump(ptr_str(voidptr(another)))
|
||||||
|
ps = PZZMyStructInt(another)
|
||||||
|
// dump(ptr_str(voidptr(ps)))
|
||||||
|
return 123
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue