| ... | @@ -1899,6 +1899,17 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -1899,6 +1899,17 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 1899 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, | 1899 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 1900 | .namespace => break, | 1900 | .namespace => break, |
| 1901 | .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent, | 1901 | .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| | 1902 | .defer_gen => { |
| | 1903 | const defer_gen = scope.cast(Scope.DeferGen).?; |
| | 1904 | |
| | 1905 | return astgen.failNodeNotes(node, "cannot break out of defer expression", .{}, &.{ |
| | 1906 | try astgen.errNoteNode( |
| | 1907 | defer_gen.defer_node, |
| | 1908 | "defer expression here", |
| | 1909 | .{}, |
| | 1910 | ), |
| | 1911 | }); |
| | 1912 | }, |
| 1902 | .top => unreachable, | 1913 | .top => unreachable, |
| 1903 | } | 1914 | } |
| 1904 | } | 1915 | } |
| ... | @@ -1958,6 +1969,17 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) | ... | @@ -1958,6 +1969,17 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 1958 | try unusedResultDeferExpr(parent_gz, defer_scope, defer_scope.parent, expr_node); | 1969 | try unusedResultDeferExpr(parent_gz, defer_scope, defer_scope.parent, expr_node); |
| 1959 | }, | 1970 | }, |
| 1960 | .defer_error => scope = scope.cast(Scope.Defer).?.parent, | 1971 | .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| | 1972 | .defer_gen => { |
| | 1973 | const defer_gen = scope.cast(Scope.DeferGen).?; |
| | 1974 | |
| | 1975 | return astgen.failNodeNotes(node, "cannot continue out of defer expression", .{}, &.{ |
| | 1976 | try astgen.errNoteNode( |
| | 1977 | defer_gen.defer_node, |
| | 1978 | "defer expression here", |
| | 1979 | .{}, |
| | 1980 | ), |
| | 1981 | }); |
| | 1982 | }, |
| 1961 | .namespace => break, | 1983 | .namespace => break, |
| 1962 | .top => unreachable, | 1984 | .top => unreachable, |
| 1963 | } | 1985 | } |
| ... | @@ -2022,6 +2044,7 @@ fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: Ast.Toke | ... | @@ -2022,6 +2044,7 @@ fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: Ast.Toke |
| 2022 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, | 2044 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 2023 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, | 2045 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 2024 | .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent, | 2046 | .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| | 2047 | .defer_gen => scope = scope.cast(Scope.DeferGen).?.parent, |
| 2025 | .namespace => break, | 2048 | .namespace => break, |
| 2026 | .top => unreachable, | 2049 | .top => unreachable, |
| 2027 | } | 2050 | } |
| ... | @@ -2206,7 +2229,13 @@ fn unusedResultDeferExpr(gz: *GenZir, defer_scope: *Scope.Defer, expr_scope: *Sc | ... | @@ -2206,7 +2229,13 @@ fn unusedResultDeferExpr(gz: *GenZir, defer_scope: *Scope.Defer, expr_scope: *Sc |
| 2206 | astgen.source_offset = defer_scope.source_offset; | 2229 | astgen.source_offset = defer_scope.source_offset; |
| 2207 | astgen.source_line = defer_scope.source_line; | 2230 | astgen.source_line = defer_scope.source_line; |
| 2208 | astgen.source_column = defer_scope.source_column; | 2231 | astgen.source_column = defer_scope.source_column; |
| 2209 | _ = try unusedResultExpr(gz, expr_scope, expr_node); | 2232 | |
| | 2233 | var defer_gen: Scope.DeferGen = .{ |
| | 2234 | .parent = expr_scope, |
| | 2235 | .defer_node = defer_scope.defer_node, |
| | 2236 | }; |
| | 2237 | |
| | 2238 | _ = try unusedResultExpr(gz, &defer_gen.base, expr_node); |
| 2210 | } | 2239 | } |
| 2211 | | 2240 | |
| 2212 | /// Returns AST source node of the thing that is noreturn if the statement is | 2241 | /// Returns AST source node of the thing that is noreturn if the statement is |
| ... | @@ -2553,6 +2582,7 @@ fn countDefers(astgen: *AstGen, outer_scope: *Scope, inner_scope: *Scope) struct | ... | @@ -2553,6 +2582,7 @@ fn countDefers(astgen: *AstGen, outer_scope: *Scope, inner_scope: *Scope) struct |
| 2553 | .gen_zir => scope = scope.cast(GenZir).?.parent, | 2582 | .gen_zir => scope = scope.cast(GenZir).?.parent, |
| 2554 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, | 2583 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 2555 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, | 2584 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| | 2585 | .defer_gen => scope = scope.cast(Scope.DeferGen).?.parent, |
| 2556 | .defer_normal => { | 2586 | .defer_normal => { |
| 2557 | const defer_scope = scope.cast(Scope.Defer).?; | 2587 | const defer_scope = scope.cast(Scope.Defer).?; |
| 2558 | scope = defer_scope.parent; | 2588 | scope = defer_scope.parent; |
| ... | @@ -2602,6 +2632,7 @@ fn genDefers( | ... | @@ -2602,6 +2632,7 @@ fn genDefers( |
| 2602 | .gen_zir => scope = scope.cast(GenZir).?.parent, | 2632 | .gen_zir => scope = scope.cast(GenZir).?.parent, |
| 2603 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, | 2633 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 2604 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, | 2634 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| | 2635 | .defer_gen => scope = scope.cast(Scope.DeferGen).?.parent, |
| 2605 | .defer_normal => { | 2636 | .defer_normal => { |
| 2606 | const defer_scope = scope.cast(Scope.Defer).?; | 2637 | const defer_scope = scope.cast(Scope.Defer).?; |
| 2607 | scope = defer_scope.parent; | 2638 | scope = defer_scope.parent; |
| ... | @@ -2681,6 +2712,7 @@ fn checkUsed( | ... | @@ -2681,6 +2712,7 @@ fn checkUsed( |
| 2681 | scope = s.parent; | 2712 | scope = s.parent; |
| 2682 | }, | 2713 | }, |
| 2683 | .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent, | 2714 | .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| | 2715 | .defer_gen => scope = scope.cast(Scope.DeferGen).?.parent, |
| 2684 | .namespace => unreachable, | 2716 | .namespace => unreachable, |
| 2685 | .top => unreachable, | 2717 | .top => unreachable, |
| 2686 | } | 2718 | } |
| ... | @@ -4040,6 +4072,7 @@ fn testDecl( | ... | @@ -4040,6 +4072,7 @@ fn testDecl( |
| 4040 | .local_val, .local_ptr => unreachable, // a test cannot be in a local scope | 4072 | .local_val, .local_ptr => unreachable, // a test cannot be in a local scope |
| 4041 | .gen_zir => s = s.cast(GenZir).?.parent, | 4073 | .gen_zir => s = s.cast(GenZir).?.parent, |
| 4042 | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, | 4074 | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, |
| | 4075 | .defer_gen => s = s.cast(Scope.DeferGen).?.parent, |
| 4043 | .namespace => { | 4076 | .namespace => { |
| 4044 | const ns = s.cast(Scope.Namespace).?; | 4077 | const ns = s.cast(Scope.Namespace).?; |
| 4045 | if (ns.decls.get(name_str_index)) |i| { | 4078 | if (ns.decls.get(name_str_index)) |i| { |
| ... | @@ -6730,6 +6763,7 @@ fn localVarRef( | ... | @@ -6730,6 +6763,7 @@ fn localVarRef( |
| 6730 | }, | 6763 | }, |
| 6731 | .gen_zir => s = s.cast(GenZir).?.parent, | 6764 | .gen_zir => s = s.cast(GenZir).?.parent, |
| 6732 | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, | 6765 | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, |
| | 6766 | .defer_gen => s = s.cast(Scope.DeferGen).?.parent, |
| 6733 | .namespace => { | 6767 | .namespace => { |
| 6734 | const ns = s.cast(Scope.Namespace).?; | 6768 | const ns = s.cast(Scope.Namespace).?; |
| 6735 | if (ns.decls.get(name_str_index)) |i| { | 6769 | if (ns.decls.get(name_str_index)) |i| { |
| ... | @@ -7351,6 +7385,7 @@ fn builtinCall( | ... | @@ -7351,6 +7385,7 @@ fn builtinCall( |
| 7351 | }, | 7385 | }, |
| 7352 | .gen_zir => s = s.cast(GenZir).?.parent, | 7386 | .gen_zir => s = s.cast(GenZir).?.parent, |
| 7353 | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, | 7387 | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, |
| | 7388 | .defer_gen => s = s.cast(Scope.DeferGen).?.parent, |
| 7354 | .namespace => { | 7389 | .namespace => { |
| 7355 | const ns = s.cast(Scope.Namespace).?; | 7390 | const ns = s.cast(Scope.Namespace).?; |
| 7356 | if (ns.decls.get(decl_name)) |i| { | 7391 | if (ns.decls.get(decl_name)) |i| { |
| ... | @@ -9808,6 +9843,7 @@ const Scope = struct { | ... | @@ -9808,6 +9843,7 @@ const Scope = struct { |
| 9808 | local_ptr, | 9843 | local_ptr, |
| 9809 | defer_normal, | 9844 | defer_normal, |
| 9810 | defer_error, | 9845 | defer_error, |
| | 9846 | defer_gen, |
| 9811 | namespace, | 9847 | namespace, |
| 9812 | top, | 9848 | top, |
| 9813 | }; | 9849 | }; |
| ... | @@ -9905,6 +9941,13 @@ const Scope = struct { | ... | @@ -9905,6 +9941,13 @@ const Scope = struct { |
| 9905 | const base_tag: Scope.Tag = .top; | 9941 | const base_tag: Scope.Tag = .top; |
| 9906 | base: Scope = Scope{ .tag = base_tag }, | 9942 | base: Scope = Scope{ .tag = base_tag }, |
| 9907 | }; | 9943 | }; |
| | 9944 | |
| | 9945 | const DeferGen = struct { |
| | 9946 | const base_tag: Scope.Tag = .defer_gen; |
| | 9947 | base: Scope = Scope{ .tag = base_tag }, |
| | 9948 | parent: *Scope, |
| | 9949 | defer_node: Ast.Node.Index, |
| | 9950 | }; |
| 9908 | }; | 9951 | }; |
| 9909 | | 9952 | |
| 9910 | /// This is a temporary structure; references to it are valid only | 9953 | /// This is a temporary structure; references to it are valid only |
| ... | @@ -11415,6 +11458,7 @@ fn detectLocalShadowing( | ... | @@ -11415,6 +11458,7 @@ fn detectLocalShadowing( |
| 11415 | }, | 11458 | }, |
| 11416 | .gen_zir => s = s.cast(GenZir).?.parent, | 11459 | .gen_zir => s = s.cast(GenZir).?.parent, |
| 11417 | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, | 11460 | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, |
| | 11461 | .defer_gen => s = s.cast(Scope.DeferGen).?.parent, |
| 11418 | .top => break, | 11462 | .top => break, |
| 11419 | }; | 11463 | }; |
| 11420 | } | 11464 | } |