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
 | 
			
		||||
						share = iv.share
 | 
			
		||||
						if iv.is_static {
 | 
			
		||||
							if !p.pref.translated && !p.pref.is_fmt {
 | 
			
		||||
								p.error_with_pos('static variables are supported only in -translated mode',
 | 
			
		||||
							if !p.pref.translated && !p.pref.is_fmt && !p.inside_unsafe_fn {
 | 
			
		||||
								p.error_with_pos('static variables are supported only in -translated mode or in [unsafe] fn',
 | 
			
		||||
									lx.pos)
 | 
			
		||||
								return ast.Stmt{}
 | 
			
		||||
							}
 | 
			
		||||
| 
						 | 
				
			
			@ -154,7 +154,7 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
 | 
			
		|||
						name: lx.name
 | 
			
		||||
						expr: if left.len == right.len { right[i] } else { ast.Expr{} }
 | 
			
		||||
						share: share
 | 
			
		||||
						is_mut: lx.is_mut || p.inside_for
 | 
			
		||||
						is_mut: lx.is_mut || p.inside_for || is_static
 | 
			
		||||
						pos: lx.pos
 | 
			
		||||
					}
 | 
			
		||||
					if p.pref.autofree {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -361,7 +361,9 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
 | 
			
		|||
	body_start_pos := p.peek_tok.position()
 | 
			
		||||
	if p.tok.kind == .lcbr {
 | 
			
		||||
		p.inside_fn = true
 | 
			
		||||
		p.inside_unsafe_fn = is_unsafe
 | 
			
		||||
		stmts = p.parse_block_no_scope(true)
 | 
			
		||||
		p.inside_unsafe_fn = false
 | 
			
		||||
		p.inside_fn = false
 | 
			
		||||
	}
 | 
			
		||||
	if !no_body && are_args_type_only {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,7 @@ mut:
 | 
			
		|||
	inside_or_expr    bool
 | 
			
		||||
	inside_for        bool
 | 
			
		||||
	inside_fn         bool // true even with implicit main
 | 
			
		||||
	inside_unsafe_fn  bool // true when in fn, marked with `[unsafe]`
 | 
			
		||||
	inside_str_interp bool
 | 
			
		||||
	or_is_handled     bool         // ignore `or` in this expression
 | 
			
		||||
	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