File tree Expand file tree Collapse file tree 4 files changed +35
-21
lines changed Expand file tree Collapse file tree 4 files changed +35
-21
lines changed Original file line number Diff line number Diff line change @@ -2433,24 +2433,24 @@ fn (mut c Checker) defer_stmt(mut node ast.DeferStmt) {
24332433 if c.locked_names.len != 0 || c.rlocked_names.len != 0 {
24342434 c.error ('`defer(fn)`s are not allowed in lock statements' , node.pos)
24352435 }
2436- }
2437- for i, ident in node.defer_vars {
2438- mut id := ident
2439- if mut id.info is ast.IdentVar {
2440- if id.comptime
2441- && (id.tok_kind == .question || id.name in ast.valid_comptime_not_user_defined) {
2442- node.defer_vars[i] = ast.Ident{
2443- scope: unsafe { nil }
2444- name: ''
2436+ for i, ident in node.defer_vars {
2437+ mut id := ident
2438+ if mut id.info is ast.IdentVar {
2439+ if id.comptime
2440+ && (id.tok_kind == .question || id.name in ast.valid_comptime_not_user_defined) {
2441+ node.defer_vars[i] = ast.Ident{
2442+ scope: unsafe { nil }
2443+ name: ''
2444+ }
2445+ continue
24452446 }
2446- continue
2447- }
2448- typ := c.ident (mut id)
2449- if typ == ast.error_type_idx {
2450- continue
2447+ typ := c.ident (mut id)
2448+ if typ == ast.error_type_idx {
2449+ continue
2450+ }
2451+ id.info.typ = typ
2452+ node.defer_vars[i] = id
24512453 }
2452- id.info.typ = typ
2453- node.defer_vars[i] = id
24542454 }
24552455 }
24562456 c.stmts (mut node.stmts)
Original file line number Diff line number Diff line change @@ -7,11 +7,11 @@ import v.ast
77
88fn (mut p Parser) assign_stmt () ast.Stmt {
99 mut defer_vars := p.defer_vars.clone ()
10- p.defer_vars = []ast.Ident{}
10+ p.defer_vars = []
1111
1212 exprs := p.expr_list (true )
1313
14- if ! (p.inside_defer && p.tok.kind == .decl_assign) {
14+ if ! (p.inside_defer && p.defer_mode == .function && p. tok.kind == .decl_assign) {
1515 defer_vars << p.defer_vars
1616 }
1717 p.defer_vars = defer_vars
Original file line number Diff line number Diff line change 6363 inside_asm_template bool
6464 inside_asm bool
6565 inside_defer bool
66+ defer_mode ast.DeferMode
6667 inside_generic_params bool // indicates if parsing between `<` and `>` of a method/function
6768 inside_receiver_param bool // indicates if parsing the receiver parameter inside the first `(` and `)` of a method
6869 inside_struct_field_decl bool
@@ -1147,6 +1148,7 @@ fn (mut p Parser) stmt(is_top_level bool) ast.Stmt {
11471148 p.check (.rpar)
11481149 }
11491150 p.inside_defer = true
1151+ p.defer_mode = defer_mode
11501152 p.defer_vars = []ast.Ident{}
11511153 stmts := p.parse_block ()
11521154 p.inside_defer = false
@@ -1253,10 +1255,9 @@ fn (mut p Parser) parse_multi_expr(is_top_level bool) ast.Stmt {
12531255
12541256 left := p.expr_list (p.inside_assign_rhs)
12551257
1256- if ! (p.inside_defer && p.tok.kind == .decl_assign) {
1258+ if ! (p.inside_defer && p.defer_mode == .function && p. tok.kind == .decl_assign) {
12571259 defer_vars << p.defer_vars
12581260 }
1259-
12601261 p.defer_vars = defer_vars
12611262
12621263 left0 := left[0 ]
@@ -3237,7 +3238,7 @@ fn (mut p Parser) show(params ParserShowParams) {
32373238}
32383239
32393240fn (mut p Parser) add_defer_var (ident ast.Ident) {
3240- if p.inside_defer {
3241+ if p.inside_defer && p. defer_mode == .function {
32413242 if ! p.defer_vars.any (it .name == ident.name && it .mod == ident.mod)
32423243 && ident.name ! in ['err' , 'it' ] {
32433244 p.defer_vars << ident
Original file line number Diff line number Diff line change @@ -117,3 +117,16 @@ fn test_defer_with_comptime_for() {
117117 }
118118 assert c == 3
119119}
120+
121+ fn test_defer_fn_with_inner_var () {
122+ mut x := 0
123+ defer {
124+ assert x == 1
125+ }
126+ {
127+ a := 1
128+ defer (fn ) {
129+ x = a
130+ }
131+ }
132+ }
You can’t perform that action at this time.
0 commit comments