| ... | ... | @@ -1683,7 +1683,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 1683 | 1683 | const defer_scope = scope.cast(Scope.Defer).?; |
| 1684 | 1684 | scope = defer_scope.parent; |
| 1685 | 1685 | const expr_node = node_datas[defer_scope.defer_node].rhs; |
| 1686 | | _ = try unusedResultExpr(parent_gz, defer_scope.parent, expr_node); |
| 1686 | try unusedResultDeferExpr(parent_gz, defer_scope, defer_scope.parent, expr_node); |
| 1687 | 1687 | }, |
| 1688 | 1688 | .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| 1689 | 1689 | .top => unreachable, |
| ... | ... | @@ -1736,7 +1736,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 1736 | 1736 | const defer_scope = scope.cast(Scope.Defer).?; |
| 1737 | 1737 | scope = defer_scope.parent; |
| 1738 | 1738 | const expr_node = node_datas[defer_scope.defer_node].rhs; |
| 1739 | | _ = try unusedResultExpr(parent_gz, defer_scope.parent, expr_node); |
| 1739 | try unusedResultDeferExpr(parent_gz, defer_scope, defer_scope.parent, expr_node); |
| 1740 | 1740 | }, |
| 1741 | 1741 | .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| 1742 | 1742 | .namespace => break, |
| ... | ... | @@ -1922,8 +1922,8 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 1922 | 1922 | .simple_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.simpleVarDecl(statement)), |
| 1923 | 1923 | .aligned_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.alignedVarDecl(statement)), |
| 1924 | 1924 | |
| 1925 | | .@"defer" => scope = try makeDeferScope(scope, statement, &block_arena.allocator, .defer_normal), |
| 1926 | | .@"errdefer" => scope = try makeDeferScope(scope, statement, &block_arena.allocator, .defer_error), |
| 1925 | .@"defer" => scope = try makeDeferScope(gz.astgen, scope, statement, &block_arena.allocator, .defer_normal), |
| 1926 | .@"errdefer" => scope = try makeDeferScope(gz.astgen, scope, statement, &block_arena.allocator, .defer_error), |
| 1927 | 1927 | |
| 1928 | 1928 | .assign => try assign(gz, scope, statement), |
| 1929 | 1929 | |
| ... | ... | @@ -1951,6 +1951,22 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 1951 | 1951 | try checkUsed(gz, parent_scope, scope); |
| 1952 | 1952 | } |
| 1953 | 1953 | |
| 1954 | fn unusedResultDeferExpr(gz: *GenZir, defer_scope: *Scope.Defer, expr_scope: *Scope, expr_node: Ast.Node.Index) InnerError!void { |
| 1955 | const astgen = gz.astgen; |
| 1956 | const prev_offset = astgen.source_offset; |
| 1957 | const prev_line = astgen.source_line; |
| 1958 | const prev_column = astgen.source_column; |
| 1959 | defer { |
| 1960 | astgen.source_offset = prev_offset; |
| 1961 | astgen.source_line = prev_line; |
| 1962 | astgen.source_column = prev_column; |
| 1963 | } |
| 1964 | astgen.source_offset = defer_scope.source_offset; |
| 1965 | astgen.source_line = defer_scope.source_line; |
| 1966 | astgen.source_column = defer_scope.source_column; |
| 1967 | _ = try unusedResultExpr(gz, expr_scope, expr_node); |
| 1968 | } |
| 1969 | |
| 1954 | 1970 | /// Returns AST source node of the thing that is noreturn if the statement is definitely `noreturn`. |
| 1955 | 1971 | /// Otherwise returns 0. |
| 1956 | 1972 | fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) InnerError!Ast.Node.Index { |
| ... | ... | @@ -2333,7 +2349,7 @@ fn genDefers( |
| 2333 | 2349 | const prev_in_defer = gz.in_defer; |
| 2334 | 2350 | gz.in_defer = true; |
| 2335 | 2351 | defer gz.in_defer = prev_in_defer; |
| 2336 | | _ = try unusedResultExpr(gz, defer_scope.parent, expr_node); |
| 2352 | try unusedResultDeferExpr(gz, defer_scope, defer_scope.parent, expr_node); |
| 2337 | 2353 | }, |
| 2338 | 2354 | .defer_error => { |
| 2339 | 2355 | const defer_scope = scope.cast(Scope.Defer).?; |
| ... | ... | @@ -2344,7 +2360,7 @@ fn genDefers( |
| 2344 | 2360 | const prev_in_defer = gz.in_defer; |
| 2345 | 2361 | gz.in_defer = true; |
| 2346 | 2362 | defer gz.in_defer = prev_in_defer; |
| 2347 | | _ = try unusedResultExpr(gz, defer_scope.parent, expr_node); |
| 2363 | try unusedResultDeferExpr(gz, defer_scope, defer_scope.parent, expr_node); |
| 2348 | 2364 | }, |
| 2349 | 2365 | .both => |err_code| { |
| 2350 | 2366 | const expr_node = node_datas[defer_scope.defer_node].rhs; |
| ... | ... | @@ -2365,7 +2381,7 @@ fn genDefers( |
| 2365 | 2381 | }; |
| 2366 | 2382 | break :blk &local_val_scope.base; |
| 2367 | 2383 | }; |
| 2368 | | _ = try unusedResultExpr(gz, sub_scope, expr_node); |
| 2384 | try unusedResultDeferExpr(gz, defer_scope, sub_scope, expr_node); |
| 2369 | 2385 | }, |
| 2370 | 2386 | .normal_only => continue, |
| 2371 | 2387 | } |
| ... | ... | @@ -2409,16 +2425,27 @@ fn checkUsed( |
| 2409 | 2425 | } |
| 2410 | 2426 | |
| 2411 | 2427 | fn makeDeferScope( |
| 2428 | astgen: *AstGen, |
| 2412 | 2429 | scope: *Scope, |
| 2413 | 2430 | node: Ast.Node.Index, |
| 2414 | 2431 | block_arena: *Allocator, |
| 2415 | 2432 | scope_tag: Scope.Tag, |
| 2416 | 2433 | ) InnerError!*Scope { |
| 2434 | const tree = astgen.tree; |
| 2435 | const node_datas = tree.nodes.items(.data); |
| 2436 | const expr_node = node_datas[node].rhs; |
| 2437 | const token_starts = tree.tokens.items(.start); |
| 2438 | const node_start = token_starts[tree.firstToken(expr_node)]; |
| 2417 | 2439 | const defer_scope = try block_arena.create(Scope.Defer); |
| 2440 | astgen.advanceSourceCursor(tree.source, node_start); |
| 2441 | |
| 2418 | 2442 | defer_scope.* = .{ |
| 2419 | 2443 | .base = .{ .tag = scope_tag }, |
| 2420 | 2444 | .parent = scope, |
| 2421 | 2445 | .defer_node = node, |
| 2446 | .source_offset = astgen.source_offset, |
| 2447 | .source_line = astgen.source_line, |
| 2448 | .source_column = astgen.source_column, |
| 2422 | 2449 | }; |
| 2423 | 2450 | return &defer_scope.base; |
| 2424 | 2451 | } |
| ... | ... | @@ -9245,6 +9272,9 @@ const Scope = struct { |
| 9245 | 9272 | /// Parents can be: `LocalVal`, `LocalPtr`, `GenZir`, `Defer`, `Namespace`. |
| 9246 | 9273 | parent: *Scope, |
| 9247 | 9274 | defer_node: Ast.Node.Index, |
| 9275 | source_offset: u32, |
| 9276 | source_line: u32, |
| 9277 | source_column: u32, |
| 9248 | 9278 | }; |
| 9249 | 9279 | |
| 9250 | 9280 | /// Represents a global scope that has any number of declarations in it. |