all: allow functions to return `shared` object (#8606)

pull/8614/head
Uwe Krüger 2021-02-06 19:41:52 +01:00 committed by GitHub
parent fe9d062b41
commit 5343f1374b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 3 deletions

View File

@ -2548,7 +2548,7 @@ fn (mut g Gen) expr(node ast.Expr) {
node.return_type.clear_flag(.optional) node.return_type.clear_flag(.optional)
} }
mut shared_styp := '' mut shared_styp := ''
if g.is_shared { if g.is_shared && !ret_type.has_flag(.shared_f) {
ret_sym := g.table.get_type_symbol(ret_type) ret_sym := g.table.get_type_symbol(ret_type)
shared_typ := ret_type.set_flag(.shared_f) shared_typ := ret_type.set_flag(.shared_f)
shared_styp = g.typ(shared_typ) shared_styp = g.typ(shared_typ)
@ -2576,7 +2576,7 @@ fn (mut g Gen) expr(node ast.Expr) {
g.strs_to_free0 = [] g.strs_to_free0 = []
// println('pos=$node.pos.pos') // println('pos=$node.pos.pos')
} }
if g.is_shared { if g.is_shared && !ret_type.has_flag(.shared_f) {
g.writeln('}, sizeof($shared_styp))') g.writeln('}, sizeof($shared_styp))')
} }
// if g.autofree && node.autofree_pregen != '' { // g.strs_to_free0.len != 0 { // if g.autofree && node.autofree_pregen != '' { // g.strs_to_free0.len != 0 {

View File

@ -207,6 +207,9 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
p.warn_with_pos('use `(mut f Foo)` instead of `(f mut Foo)`', lpar_pos.extend(p.peek_tok2.position())) p.warn_with_pos('use `(mut f Foo)` instead of `(f mut Foo)`', lpar_pos.extend(p.peek_tok2.position()))
} }
} }
if p.tok.kind == .key_shared {
p.error_with_pos('use `(shared f Foo)` instead of `(f shared Foo)`', lpar_pos.extend(p.peek_tok2.position()))
}
receiver_pos = rec_start_pos.extend(p.tok.position()) receiver_pos = rec_start_pos.extend(p.tok.position())
is_amp := p.tok.kind == .amp is_amp := p.tok.kind == .amp
if p.tok.kind == .name && p.tok.lit == 'JS' { if p.tok.kind == .name && p.tok.lit == 'JS' {
@ -685,6 +688,9 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
} }
is_mut = true is_mut = true
} }
if p.tok.kind == .key_shared {
p.error_with_pos('use `shared f Foo` instead of `f shared Foo`', p.tok.position())
}
if p.tok.kind == .ellipsis { if p.tok.kind == .ellipsis {
p.next() p.next()
is_variadic = true is_variadic = true

View File

@ -0,0 +1,54 @@
struct St {
mut:
x f64
}
fn f() shared St {
shared x := St{ x: 3.25 }
return x
}
fn g(good bool) ?shared St {
if !good {
return error('no shared St created')
}
shared x := St{ x: 12.75 }
return x
}
fn test_shared_fn_return() {
shared x := f()
val := rlock x { x.x }
assert val == 3.25
}
fn shared_opt_propagate(good bool) ?f64 {
shared x := g(good) ?
ret := rlock x { x.x }
return ret
}
fn test_shared_opt_propagate() {
x := shared_opt_propagate(true) or { 1.25 }
y := shared_opt_propagate(false) or { 2.125 }
assert x == 12.75
assert y == 2.125
}
fn test_shared_opt_good() {
shared yy := g(true) or {
shared my_default := St{ x: 37.5 }
my_default
}
val := rlock yy { yy.x }
assert val == 12.75
}
fn test_shared_opt_bad() {
shared yy := g(false) or {
shared my_default := St{ x: 37.5 }
my_default
}
val := rlock yy { yy.x }
assert val == 37.5
}

View File

@ -427,7 +427,7 @@ pub fn (tok Kind) is_relational() bool {
} }
pub fn (k Kind) is_start_of_type() bool { pub fn (k Kind) is_start_of_type() bool {
return k in [.name, .lpar, .amp, .lsbr, .question] return k in [.name, .lpar, .amp, .lsbr, .question, .key_shared]
} }
pub fn (kind Kind) is_prefix() bool { pub fn (kind Kind) is_prefix() bool {