parser: support `static x := 42` in [unsafe] functions too
parent
276c08e7f7
commit
bdce35fd9c
|
@ -141,8 +141,8 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
|
||||||
iv := lx.info as ast.IdentVar
|
iv := lx.info as ast.IdentVar
|
||||||
share = iv.share
|
share = iv.share
|
||||||
if iv.is_static {
|
if iv.is_static {
|
||||||
if !p.pref.translated && !p.pref.is_fmt {
|
if !p.pref.translated && !p.pref.is_fmt && !p.inside_unsafe_fn {
|
||||||
p.error_with_pos('static variables are supported only in -translated mode',
|
p.error_with_pos('static variables are supported only in -translated mode or in [unsafe] fn',
|
||||||
lx.pos)
|
lx.pos)
|
||||||
return ast.Stmt{}
|
return ast.Stmt{}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
|
||||||
name: lx.name
|
name: lx.name
|
||||||
expr: if left.len == right.len { right[i] } else { ast.Expr{} }
|
expr: if left.len == right.len { right[i] } else { ast.Expr{} }
|
||||||
share: share
|
share: share
|
||||||
is_mut: lx.is_mut || p.inside_for
|
is_mut: lx.is_mut || p.inside_for || is_static
|
||||||
pos: lx.pos
|
pos: lx.pos
|
||||||
}
|
}
|
||||||
if p.pref.autofree {
|
if p.pref.autofree {
|
||||||
|
|
|
@ -361,7 +361,9 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||||
body_start_pos := p.peek_tok.position()
|
body_start_pos := p.peek_tok.position()
|
||||||
if p.tok.kind == .lcbr {
|
if p.tok.kind == .lcbr {
|
||||||
p.inside_fn = true
|
p.inside_fn = true
|
||||||
|
p.inside_unsafe_fn = is_unsafe
|
||||||
stmts = p.parse_block_no_scope(true)
|
stmts = p.parse_block_no_scope(true)
|
||||||
|
p.inside_unsafe_fn = false
|
||||||
p.inside_fn = false
|
p.inside_fn = false
|
||||||
}
|
}
|
||||||
if !no_body && are_args_type_only {
|
if !no_body && are_args_type_only {
|
||||||
|
|
|
@ -38,6 +38,7 @@ mut:
|
||||||
inside_or_expr bool
|
inside_or_expr bool
|
||||||
inside_for bool
|
inside_for bool
|
||||||
inside_fn bool // true even with implicit main
|
inside_fn bool // true even with implicit main
|
||||||
|
inside_unsafe_fn bool // true when in fn, marked with `[unsafe]`
|
||||||
inside_str_interp bool
|
inside_str_interp bool
|
||||||
or_is_handled bool // ignore `or` in this expression
|
or_is_handled bool // ignore `or` in this expression
|
||||||
builtin_mod bool // are we in the `builtin` module?
|
builtin_mod bool // are we in the `builtin` module?
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
[unsafe]
|
||||||
|
fn foo() int {
|
||||||
|
static x := 42
|
||||||
|
x++
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
fn xfoo() int {
|
||||||
|
return unsafe { foo() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_static_vars_work() {
|
||||||
|
assert xfoo() == 43
|
||||||
|
assert xfoo() == 44
|
||||||
|
assert xfoo() == 45
|
||||||
|
}
|
Loading…
Reference in New Issue