| ... | ... | @@ -2161,10 +2161,9 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 2161 | 2161 | const opt_break_label, const opt_rhs = tree.nodeData(node).opt_token_and_opt_node; |
| 2162 | 2162 | |
| 2163 | 2163 | // Look for the label in the scope. |
| 2164 | | var scope = parent_scope; |
| 2165 | | find_scope: switch (scope.tag) { |
| 2166 | | .gen_zir => { |
| 2167 | | const gen_zir = scope.cast(GenZir).?; |
| 2164 | find_scope: switch (parent_scope.unwrap()) { |
| 2165 | .gen_zir => |gen_zir| { |
| 2166 | const scope = &gen_zir.base; |
| 2168 | 2167 | |
| 2169 | 2168 | if (gen_zir.cur_defer_node.unwrap()) |cur_defer_node| { |
| 2170 | 2169 | // We are breaking out of a `defer` block. |
| ... | ... | @@ -2185,13 +2184,11 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 2185 | 2184 | } |
| 2186 | 2185 | } |
| 2187 | 2186 | // gz without or with different label, continue to parent scopes. |
| 2188 | | scope = gen_zir.parent; |
| 2189 | | continue :find_scope scope.tag; |
| 2187 | continue :find_scope gen_zir.parent.unwrap(); |
| 2190 | 2188 | } else if (!gen_zir.allow_unlabeled_control_flow) { |
| 2191 | 2189 | // This `break` is unlabeled and the gz we've found doesn't allow |
| 2192 | 2190 | // unlabeled control flow. Continue to parent scopes. |
| 2193 | | scope = gen_zir.parent; |
| 2194 | | continue :find_scope scope.tag; |
| 2191 | continue :find_scope gen_zir.parent.unwrap(); |
| 2195 | 2192 | } |
| 2196 | 2193 | |
| 2197 | 2194 | const break_tag: Zir.Inst.Tag = if (gen_zir.is_inline) |
| ... | ... | @@ -2236,18 +2233,9 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 2236 | 2233 | return .unreachable_value; |
| 2237 | 2234 | } |
| 2238 | 2235 | }, |
| 2239 | | .local_val => { |
| 2240 | | scope = scope.cast(Scope.LocalVal).?.parent; |
| 2241 | | continue :find_scope scope.tag; |
| 2242 | | }, |
| 2243 | | .local_ptr => { |
| 2244 | | scope = scope.cast(Scope.LocalPtr).?.parent; |
| 2245 | | continue :find_scope scope.tag; |
| 2246 | | }, |
| 2247 | | .defer_normal, .defer_error => { |
| 2248 | | scope = scope.cast(Scope.Defer).?.parent; |
| 2249 | | continue :find_scope scope.tag; |
| 2250 | | }, |
| 2236 | .local_val => |local_val| continue :find_scope local_val.parent.unwrap(), |
| 2237 | .local_ptr => |local_ptr| continue :find_scope local_ptr.parent.unwrap(), |
| 2238 | .defer_normal, .defer_error => |defer_scope| continue :find_scope defer_scope.parent.unwrap(), |
| 2251 | 2239 | .namespace => { |
| 2252 | 2240 | if (opt_break_label.unwrap()) |break_label| { |
| 2253 | 2241 | const label_name = try astgen.identifierTokenString(break_label); |
| ... | ... | @@ -2270,10 +2258,9 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 2270 | 2258 | } |
| 2271 | 2259 | |
| 2272 | 2260 | // Look for the label in the scope. |
| 2273 | | var scope = parent_scope; |
| 2274 | | find_scope: switch (scope.tag) { |
| 2275 | | .gen_zir => { |
| 2276 | | const gen_zir = scope.cast(GenZir).?; |
| 2261 | find_scope: switch (parent_scope.unwrap()) { |
| 2262 | .gen_zir => |gen_zir| { |
| 2263 | const scope = &gen_zir.base; |
| 2277 | 2264 | |
| 2278 | 2265 | if (gen_zir.cur_defer_node.unwrap()) |cur_defer_node| { |
| 2279 | 2266 | return astgen.failNodeNotes(node, "cannot continue out of defer expression", .{}, &.{ |
| ... | ... | @@ -2305,24 +2292,21 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 2305 | 2292 | } |
| 2306 | 2293 | } |
| 2307 | 2294 | // gz without or with different label, continue to parent scopes. |
| 2308 | | scope = gen_zir.parent; |
| 2309 | | continue :find_scope scope.tag; |
| 2295 | continue :find_scope gen_zir.parent.unwrap(); |
| 2310 | 2296 | } else if (gen_zir.allow_unlabeled_control_flow) { |
| 2311 | 2297 | // This `continue` is unlabeled. If the gz we've found doesn't |
| 2312 | 2298 | // provide a `continue` target or corresponds to a labeled |
| 2313 | 2299 | // `switch`, ignore it and continue to parent scopes. |
| 2314 | 2300 | switch (gen_zir.continue_target) { |
| 2315 | 2301 | .none, .switch_continue => { |
| 2316 | | scope = gen_zir.parent; |
| 2317 | | continue :find_scope scope.tag; |
| 2302 | continue :find_scope gen_zir.parent.unwrap(); |
| 2318 | 2303 | }, |
| 2319 | 2304 | .@"break" => {}, |
| 2320 | 2305 | } |
| 2321 | 2306 | } else { |
| 2322 | 2307 | // We don't have a break label and the gz we found doesn't allow |
| 2323 | 2308 | // unlabeled control flow, so we continue to its parent scopes. |
| 2324 | | scope = gen_zir.parent; |
| 2325 | | continue :find_scope scope.tag; |
| 2309 | continue :find_scope gen_zir.parent.unwrap(); |
| 2326 | 2310 | } |
| 2327 | 2311 | |
| 2328 | 2312 | switch (gen_zir.continue_target) { |
| ... | ... | @@ -2360,18 +2344,9 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 2360 | 2344 | }, |
| 2361 | 2345 | } |
| 2362 | 2346 | }, |
| 2363 | | .local_val => { |
| 2364 | | scope = scope.cast(Scope.LocalVal).?.parent; |
| 2365 | | continue :find_scope scope.tag; |
| 2366 | | }, |
| 2367 | | .local_ptr => { |
| 2368 | | scope = scope.cast(Scope.LocalPtr).?.parent; |
| 2369 | | continue :find_scope scope.tag; |
| 2370 | | }, |
| 2371 | | .defer_normal, .defer_error => { |
| 2372 | | scope = scope.cast(Scope.Defer).?.parent; |
| 2373 | | continue :find_scope scope.tag; |
| 2374 | | }, |
| 2347 | .local_val => |local_val| continue :find_scope local_val.parent.unwrap(), |
| 2348 | .local_ptr => |local_ptr| continue :find_scope local_ptr.parent.unwrap(), |
| 2349 | .defer_normal, .defer_error => |defer_scope| continue :find_scope defer_scope.parent.unwrap(), |
| 2375 | 2350 | .namespace => { |
| 2376 | 2351 | if (opt_break_label.unwrap()) |break_label| { |
| 2377 | 2352 | const label_name = try astgen.identifierTokenString(break_label); |
| ... | ... | @@ -2466,33 +2441,29 @@ fn blockExpr( |
| 2466 | 2441 | |
| 2467 | 2442 | fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: Ast.TokenIndex) !void { |
| 2468 | 2443 | // Look for the label in the scope. |
| 2469 | | var scope = parent_scope; |
| 2470 | | while (true) { |
| 2471 | | switch (scope.tag) { |
| 2472 | | .gen_zir => { |
| 2473 | | const gen_zir = scope.cast(GenZir).?; |
| 2474 | | if (gen_zir.label) |prev_label| { |
| 2475 | | if (try astgen.tokenIdentEql(label, prev_label.token)) { |
| 2476 | | const label_name = try astgen.identifierTokenString(label); |
| 2477 | | return astgen.failTokNotes(label, "redefinition of label '{s}'", .{ |
| 2478 | | label_name, |
| 2479 | | }, &[_]u32{ |
| 2480 | | try astgen.errNoteTok( |
| 2481 | | prev_label.token, |
| 2482 | | "previous definition here", |
| 2483 | | .{}, |
| 2484 | | ), |
| 2485 | | }); |
| 2486 | | } |
| 2444 | find_scope: switch (parent_scope.unwrap()) { |
| 2445 | .gen_zir => |gen_zir| { |
| 2446 | if (gen_zir.label) |prev_label| { |
| 2447 | if (try astgen.tokenIdentEql(label, prev_label.token)) { |
| 2448 | const label_name = try astgen.identifierTokenString(label); |
| 2449 | return astgen.failTokNotes(label, "redefinition of label '{s}'", .{ |
| 2450 | label_name, |
| 2451 | }, &[_]u32{ |
| 2452 | try astgen.errNoteTok( |
| 2453 | prev_label.token, |
| 2454 | "previous definition here", |
| 2455 | .{}, |
| 2456 | ), |
| 2457 | }); |
| 2487 | 2458 | } |
| 2488 | | scope = gen_zir.parent; |
| 2489 | | }, |
| 2490 | | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 2491 | | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 2492 | | .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| 2493 | | .namespace => break, |
| 2494 | | .top => unreachable, |
| 2495 | | } |
| 2459 | } |
| 2460 | continue :find_scope gen_zir.parent.unwrap(); |
| 2461 | }, |
| 2462 | .local_val => |local_val| continue :find_scope local_val.parent.unwrap(), |
| 2463 | .local_ptr => |local_ptr| continue :find_scope local_ptr.parent.unwrap(), |
| 2464 | .defer_normal, .defer_error => |defer_scope| continue :find_scope defer_scope.parent.unwrap(), |
| 2465 | .namespace => break :find_scope, |
| 2466 | .top => unreachable, |
| 2496 | 2467 | } |
| 2497 | 2468 | } |
| 2498 | 2469 | |
| ... | ... | @@ -3007,18 +2978,16 @@ fn countDefers(outer_scope: *Scope, inner_scope: *Scope) struct { |
| 3007 | 2978 | var need_err_code = false; |
| 3008 | 2979 | var scope = inner_scope; |
| 3009 | 2980 | while (scope != outer_scope) { |
| 3010 | | switch (scope.tag) { |
| 3011 | | .gen_zir => scope = scope.cast(GenZir).?.parent, |
| 3012 | | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 3013 | | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 3014 | | .defer_normal => { |
| 3015 | | const defer_scope = scope.cast(Scope.Defer).?; |
| 2981 | switch (scope.unwrap()) { |
| 2982 | .gen_zir => |gen_zir| scope = gen_zir.parent, |
| 2983 | .local_val => |local_val| scope = local_val.parent, |
| 2984 | .local_ptr => |local_ptr| scope = local_ptr.parent, |
| 2985 | .defer_normal => |defer_scope| { |
| 3016 | 2986 | scope = defer_scope.parent; |
| 3017 | 2987 | |
| 3018 | 2988 | have_normal = true; |
| 3019 | 2989 | }, |
| 3020 | | .defer_error => { |
| 3021 | | const defer_scope = scope.cast(Scope.Defer).?; |
| 2990 | .defer_error => |defer_scope| { |
| 3022 | 2991 | scope = defer_scope.parent; |
| 3023 | 2992 | |
| 3024 | 2993 | have_err = true; |
| ... | ... | @@ -3054,17 +3023,15 @@ fn genDefers( |
| 3054 | 3023 | |
| 3055 | 3024 | var scope = inner_scope; |
| 3056 | 3025 | while (scope != outer_scope) { |
| 3057 | | switch (scope.tag) { |
| 3058 | | .gen_zir => scope = scope.cast(GenZir).?.parent, |
| 3059 | | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 3060 | | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 3061 | | .defer_normal => { |
| 3062 | | const defer_scope = scope.cast(Scope.Defer).?; |
| 3026 | switch (scope.unwrap()) { |
| 3027 | .gen_zir => |gen_zir| scope = gen_zir.parent, |
| 3028 | .local_val => |local_val| scope = local_val.parent, |
| 3029 | .local_ptr => |local_ptr| scope = local_ptr.parent, |
| 3030 | .defer_normal => |defer_scope| { |
| 3063 | 3031 | scope = defer_scope.parent; |
| 3064 | 3032 | try gz.addDefer(defer_scope.index, defer_scope.len); |
| 3065 | 3033 | }, |
| 3066 | | .defer_error => { |
| 3067 | | const defer_scope = scope.cast(Scope.Defer).?; |
| 3034 | .defer_error => |defer_scope| { |
| 3068 | 3035 | scope = defer_scope.parent; |
| 3069 | 3036 | switch (which_ones) { |
| 3070 | 3037 | .both_sans_err => { |
| ... | ... | @@ -3107,10 +3074,9 @@ fn checkUsed(gz: *GenZir, outer_scope: *Scope, inner_scope: *Scope) InnerError!v |
| 3107 | 3074 | |
| 3108 | 3075 | var scope = inner_scope; |
| 3109 | 3076 | while (scope != outer_scope) { |
| 3110 | | switch (scope.tag) { |
| 3111 | | .gen_zir => scope = scope.cast(GenZir).?.parent, |
| 3112 | | .local_val => { |
| 3113 | | const s = scope.cast(Scope.LocalVal).?; |
| 3077 | switch (scope.unwrap()) { |
| 3078 | .gen_zir => |gen_zir| scope = gen_zir.parent, |
| 3079 | .local_val => |s| { |
| 3114 | 3080 | if (s.used == .none and s.discarded == .none) { |
| 3115 | 3081 | try astgen.appendErrorTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)}); |
| 3116 | 3082 | } else if (s.used != .none and s.discarded != .none) { |
| ... | ... | @@ -3120,8 +3086,7 @@ fn checkUsed(gz: *GenZir, outer_scope: *Scope, inner_scope: *Scope) InnerError!v |
| 3120 | 3086 | } |
| 3121 | 3087 | scope = s.parent; |
| 3122 | 3088 | }, |
| 3123 | | .local_ptr => { |
| 3124 | | const s = scope.cast(Scope.LocalPtr).?; |
| 3089 | .local_ptr => |s| { |
| 3125 | 3090 | if (s.used == .none and s.discarded == .none) { |
| 3126 | 3091 | try astgen.appendErrorTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)}); |
| 3127 | 3092 | } else { |
| ... | ... | @@ -3136,10 +3101,9 @@ fn checkUsed(gz: *GenZir, outer_scope: *Scope, inner_scope: *Scope) InnerError!v |
| 3136 | 3101 | }); |
| 3137 | 3102 | } |
| 3138 | 3103 | } |
| 3139 | | |
| 3140 | 3104 | scope = s.parent; |
| 3141 | 3105 | }, |
| 3142 | | .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| 3106 | .defer_normal, .defer_error => |defer_scope| scope = defer_scope.parent, |
| 3143 | 3107 | .namespace => unreachable, |
| 3144 | 3108 | .top => unreachable, |
| 3145 | 3109 | } |
| ... | ... | @@ -4805,13 +4769,11 @@ fn testDecl( |
| 4805 | 4769 | |
| 4806 | 4770 | // Local variables, including function parameters. |
| 4807 | 4771 | const name_str_index = try astgen.identAsString(test_name_token); |
| 4808 | | var s = scope; |
| 4809 | 4772 | var found_already: ?Ast.Node.Index = null; // we have found a decl with the same name already |
| 4810 | 4773 | var num_namespaces_out: u32 = 0; |
| 4811 | 4774 | var capturing_namespace: ?*Scope.Namespace = null; |
| 4812 | | while (true) switch (s.tag) { |
| 4813 | | .local_val => { |
| 4814 | | const local_val = s.cast(Scope.LocalVal).?; |
| 4775 | find_scope: switch (scope.unwrap()) { |
| 4776 | .local_val => |local_val| { |
| 4815 | 4777 | if (local_val.name == name_str_index) { |
| 4816 | 4778 | local_val.used = .fromToken(test_name_token); |
| 4817 | 4779 | return astgen.failTokNotes(test_name_token, "cannot test a {s}", .{ |
| ... | ... | @@ -4822,10 +4784,9 @@ fn testDecl( |
| 4822 | 4784 | }), |
| 4823 | 4785 | }); |
| 4824 | 4786 | } |
| 4825 | | s = local_val.parent; |
| 4787 | continue :find_scope local_val.parent.unwrap(); |
| 4826 | 4788 | }, |
| 4827 | | .local_ptr => { |
| 4828 | | const local_ptr = s.cast(Scope.LocalPtr).?; |
| 4789 | .local_ptr => |local_ptr| { |
| 4829 | 4790 | if (local_ptr.name == name_str_index) { |
| 4830 | 4791 | local_ptr.used = .fromToken(test_name_token); |
| 4831 | 4792 | return astgen.failTokNotes(test_name_token, "cannot test a {s}", .{ |
| ... | ... | @@ -4836,12 +4797,11 @@ fn testDecl( |
| 4836 | 4797 | }), |
| 4837 | 4798 | }); |
| 4838 | 4799 | } |
| 4839 | | s = local_ptr.parent; |
| 4800 | continue :find_scope local_ptr.parent.unwrap(); |
| 4840 | 4801 | }, |
| 4841 | | .gen_zir => s = s.cast(GenZir).?.parent, |
| 4842 | | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, |
| 4843 | | .namespace => { |
| 4844 | | const ns = s.cast(Scope.Namespace).?; |
| 4802 | .gen_zir => |gen_zir| continue :find_scope gen_zir.parent.unwrap(), |
| 4803 | .defer_normal, .defer_error => |defer_scope| continue :find_scope defer_scope.parent.unwrap(), |
| 4804 | .namespace => |ns| { |
| 4845 | 4805 | if (ns.decls.get(name_str_index)) |i| { |
| 4846 | 4806 | if (found_already) |f| { |
| 4847 | 4807 | return astgen.failTokNotes(test_name_token, "ambiguous reference", .{}, &.{ |
| ... | ... | @@ -4854,10 +4814,10 @@ fn testDecl( |
| 4854 | 4814 | } |
| 4855 | 4815 | num_namespaces_out += 1; |
| 4856 | 4816 | capturing_namespace = ns; |
| 4857 | | s = ns.parent; |
| 4817 | continue :find_scope ns.parent.unwrap(); |
| 4858 | 4818 | }, |
| 4859 | | .top => break, |
| 4860 | | }; |
| 4819 | .top => break :find_scope, |
| 4820 | } |
| 4861 | 4821 | if (found_already == null) { |
| 4862 | 4822 | const ident_name = try astgen.identifierTokenString(test_name_token); |
| 4863 | 4823 | return astgen.failTok(test_name_token, "use of undeclared identifier '{s}'", .{ident_name}); |
| ... | ... | @@ -8409,7 +8369,6 @@ fn localVarRef( |
| 8409 | 8369 | ) InnerError!Zir.Inst.Ref { |
| 8410 | 8370 | const astgen = gz.astgen; |
| 8411 | 8371 | const name_str_index = try astgen.identAsString(ident_token); |
| 8412 | | var s = scope; |
| 8413 | 8372 | var found_already: ?Ast.Node.Index = null; // we have found a decl with the same name already |
| 8414 | 8373 | var found_needs_tunnel: bool = undefined; // defined when `found_already != null` |
| 8415 | 8374 | var found_namespaces_out: u32 = undefined; // defined when `found_already != null` |
| ... | ... | @@ -8419,10 +8378,8 @@ fn localVarRef( |
| 8419 | 8378 | // defined by `num_namespaces_out != 0` |
| 8420 | 8379 | var capturing_namespace: *Scope.Namespace = undefined; |
| 8421 | 8380 | |
| 8422 | | while (true) switch (s.tag) { |
| 8423 | | .local_val => { |
| 8424 | | const local_val = s.cast(Scope.LocalVal).?; |
| 8425 | | |
| 8381 | find_scope: switch (scope.unwrap()) { |
| 8382 | .local_val => |local_val| { |
| 8426 | 8383 | if (local_val.name == name_str_index) { |
| 8427 | 8384 | // Locals cannot shadow anything, so we do not need to look for ambiguous |
| 8428 | 8385 | // references in this case. |
| ... | ... | @@ -8445,10 +8402,9 @@ fn localVarRef( |
| 8445 | 8402 | |
| 8446 | 8403 | return rvalueNoCoercePreRef(gz, ri, value_inst, ident); |
| 8447 | 8404 | } |
| 8448 | | s = local_val.parent; |
| 8405 | continue :find_scope local_val.parent.unwrap(); |
| 8449 | 8406 | }, |
| 8450 | | .local_ptr => { |
| 8451 | | const local_ptr = s.cast(Scope.LocalPtr).?; |
| 8407 | .local_ptr => |local_ptr| { |
| 8452 | 8408 | if (local_ptr.name == name_str_index) { |
| 8453 | 8409 | if (ri.rl == .discard and ri.ctx == .assignment) { |
| 8454 | 8410 | local_ptr.discarded = .fromToken(ident_token); |
| ... | ... | @@ -8497,12 +8453,11 @@ fn localVarRef( |
| 8497 | 8453 | }, |
| 8498 | 8454 | } |
| 8499 | 8455 | } |
| 8500 | | s = local_ptr.parent; |
| 8456 | continue :find_scope local_ptr.parent.unwrap(); |
| 8501 | 8457 | }, |
| 8502 | | .gen_zir => s = s.cast(GenZir).?.parent, |
| 8503 | | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, |
| 8504 | | .namespace => { |
| 8505 | | const ns = s.cast(Scope.Namespace).?; |
| 8458 | .gen_zir => |gen_zir| continue :find_scope gen_zir.parent.unwrap(), |
| 8459 | .defer_normal, .defer_error => |defer_scope| continue :find_scope defer_scope.parent.unwrap(), |
| 8460 | .namespace => |ns| { |
| 8506 | 8461 | if (ns.decls.get(name_str_index)) |i| { |
| 8507 | 8462 | if (found_already) |f| { |
| 8508 | 8463 | return astgen.failNodeNotes(ident, "ambiguous reference", .{}, &.{ |
| ... | ... | @@ -8517,10 +8472,10 @@ fn localVarRef( |
| 8517 | 8472 | } |
| 8518 | 8473 | num_namespaces_out += 1; |
| 8519 | 8474 | capturing_namespace = ns; |
| 8520 | | s = ns.parent; |
| 8475 | continue :find_scope ns.parent.unwrap(); |
| 8521 | 8476 | }, |
| 8522 | | .top => break, |
| 8523 | | }; |
| 8477 | .top => break :find_scope, |
| 8478 | } |
| 8524 | 8479 | if (found_already == null) { |
| 8525 | 8480 | const ident_name = try astgen.identifierTokenString(ident_token); |
| 8526 | 8481 | return astgen.failNode(ident, "use of undeclared identifier '{s}'", .{ident_name}); |
| ... | ... | @@ -11812,6 +11767,26 @@ const Scope = struct { |
| 11812 | 11767 | }; |
| 11813 | 11768 | } |
| 11814 | 11769 | |
| 11770 | fn unwrap(base: *Scope) Unwrapped { |
| 11771 | return switch (base.tag) { |
| 11772 | inline else => |tag| @unionInit( |
| 11773 | Unwrapped, |
| 11774 | @tagName(tag), |
| 11775 | @alignCast(@fieldParentPtr("base", base)), |
| 11776 | ), |
| 11777 | }; |
| 11778 | } |
| 11779 | |
| 11780 | const Unwrapped = union(Tag) { |
| 11781 | gen_zir: *GenZir, |
| 11782 | local_val: *LocalVal, |
| 11783 | local_ptr: *LocalPtr, |
| 11784 | defer_normal: *Defer, |
| 11785 | defer_error: *Defer, |
| 11786 | namespace: *Namespace, |
| 11787 | top: *Top, |
| 11788 | }; |
| 11789 | |
| 11815 | 11790 | const Tag = enum { |
| 11816 | 11791 | gen_zir, |
| 11817 | 11792 | local_val, |
| ... | ... | @@ -13408,11 +13383,9 @@ fn detectLocalShadowing( |
| 13408 | 13383 | }); |
| 13409 | 13384 | } |
| 13410 | 13385 | |
| 13411 | | var s = scope; |
| 13412 | 13386 | var outer_scope = false; |
| 13413 | | while (true) switch (s.tag) { |
| 13414 | | .local_val => { |
| 13415 | | const local_val = s.cast(Scope.LocalVal).?; |
| 13387 | find_scope: switch (scope.unwrap()) { |
| 13388 | .local_val => |local_val| { |
| 13416 | 13389 | if (local_val.name == ident_name) { |
| 13417 | 13390 | const name_slice = mem.span(astgen.nullTerminatedString(ident_name)); |
| 13418 | 13391 | const name = try gpa.dupe(u8, name_slice); |
| ... | ... | @@ -13438,10 +13411,9 @@ fn detectLocalShadowing( |
| 13438 | 13411 | ), |
| 13439 | 13412 | }); |
| 13440 | 13413 | } |
| 13441 | | s = local_val.parent; |
| 13414 | continue :find_scope local_val.parent.unwrap(); |
| 13442 | 13415 | }, |
| 13443 | | .local_ptr => { |
| 13444 | | const local_ptr = s.cast(Scope.LocalPtr).?; |
| 13416 | .local_ptr => |local_ptr| { |
| 13445 | 13417 | if (local_ptr.name == ident_name) { |
| 13446 | 13418 | const name_slice = mem.span(astgen.nullTerminatedString(ident_name)); |
| 13447 | 13419 | const name = try gpa.dupe(u8, name_slice); |
| ... | ... | @@ -13467,14 +13439,12 @@ fn detectLocalShadowing( |
| 13467 | 13439 | ), |
| 13468 | 13440 | }); |
| 13469 | 13441 | } |
| 13470 | | s = local_ptr.parent; |
| 13442 | continue :find_scope local_ptr.parent.unwrap(); |
| 13471 | 13443 | }, |
| 13472 | | .namespace => { |
| 13444 | .namespace => |ns| { |
| 13473 | 13445 | outer_scope = true; |
| 13474 | | const ns = s.cast(Scope.Namespace).?; |
| 13475 | 13446 | const decl_node = ns.decls.get(ident_name) orelse { |
| 13476 | | s = ns.parent; |
| 13477 | | continue; |
| 13447 | continue :find_scope ns.parent.unwrap(); |
| 13478 | 13448 | }; |
| 13479 | 13449 | const name_slice = mem.span(astgen.nullTerminatedString(ident_name)); |
| 13480 | 13450 | const name = try gpa.dupe(u8, name_slice); |
| ... | ... | @@ -13485,13 +13455,13 @@ fn detectLocalShadowing( |
| 13485 | 13455 | try astgen.errNoteNode(decl_node, "declared here", .{}), |
| 13486 | 13456 | }); |
| 13487 | 13457 | }, |
| 13488 | | .gen_zir => { |
| 13489 | | s = s.cast(GenZir).?.parent; |
| 13458 | .gen_zir => |gen_zir| { |
| 13490 | 13459 | outer_scope = true; |
| 13460 | continue :find_scope gen_zir.parent.unwrap(); |
| 13491 | 13461 | }, |
| 13492 | | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, |
| 13493 | | .top => break, |
| 13494 | | }; |
| 13462 | .defer_normal, .defer_error => |defer_scope| continue :find_scope defer_scope.parent.unwrap(), |
| 13463 | .top => break :find_scope, |
| 13464 | } |
| 13495 | 13465 | } |
| 13496 | 13466 | |
| 13497 | 13467 | const LineColumn = struct { u32, u32 }; |
| ... | ... | @@ -13728,10 +13698,8 @@ fn scanContainer( |
| 13728 | 13698 | continue; |
| 13729 | 13699 | } |
| 13730 | 13700 | |
| 13731 | | var s = namespace.parent; |
| 13732 | | while (true) switch (s.tag) { |
| 13733 | | .local_val => { |
| 13734 | | const local_val = s.cast(Scope.LocalVal).?; |
| 13701 | find_scope: switch (namespace.parent.unwrap()) { |
| 13702 | .local_val => |local_val| { |
| 13735 | 13703 | if (local_val.name == name_str_index) { |
| 13736 | 13704 | try astgen.appendErrorTokNotes(name_token, "declaration '{s}' shadows {s} from outer scope", .{ |
| 13737 | 13705 | token_bytes, @tagName(local_val.id_cat), |
| ... | ... | @@ -13743,12 +13711,11 @@ fn scanContainer( |
| 13743 | 13711 | ), |
| 13744 | 13712 | }); |
| 13745 | 13713 | any_invalid_declarations = true; |
| 13746 | | break; |
| 13714 | break :find_scope; |
| 13747 | 13715 | } |
| 13748 | | s = local_val.parent; |
| 13716 | continue :find_scope local_val.parent.unwrap(); |
| 13749 | 13717 | }, |
| 13750 | | .local_ptr => { |
| 13751 | | const local_ptr = s.cast(Scope.LocalPtr).?; |
| 13718 | .local_ptr => |local_ptr| { |
| 13752 | 13719 | if (local_ptr.name == name_str_index) { |
| 13753 | 13720 | try astgen.appendErrorTokNotes(name_token, "declaration '{s}' shadows {s} from outer scope", .{ |
| 13754 | 13721 | token_bytes, @tagName(local_ptr.id_cat), |
| ... | ... | @@ -13760,15 +13727,15 @@ fn scanContainer( |
| 13760 | 13727 | ), |
| 13761 | 13728 | }); |
| 13762 | 13729 | any_invalid_declarations = true; |
| 13763 | | break; |
| 13730 | break :find_scope; |
| 13764 | 13731 | } |
| 13765 | | s = local_ptr.parent; |
| 13732 | continue :find_scope local_ptr.parent.unwrap(); |
| 13766 | 13733 | }, |
| 13767 | | .namespace => s = s.cast(Scope.Namespace).?.parent, |
| 13768 | | .gen_zir => s = s.cast(GenZir).?.parent, |
| 13769 | | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, |
| 13770 | | .top => break, |
| 13771 | | }; |
| 13734 | .namespace => |ns| continue :find_scope ns.parent.unwrap(), |
| 13735 | .gen_zir => |gen_zir| continue :find_scope gen_zir.parent.unwrap(), |
| 13736 | .defer_normal, .defer_error => |defer_scope| continue :find_scope defer_scope.parent.unwrap(), |
| 13737 | .top => break :find_scope, |
| 13738 | } |
| 13772 | 13739 | } |
| 13773 | 13740 | |
| 13774 | 13741 | if (!any_duplicates) { |