authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-17 19:11:11-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-17 19:11:11-07:00
log1d808d0dd20326dbdb0478f2a2f43f0b9ebb557a
treeebb6072e5533949e8c7273d4f57d69b861ddf1fd
parent67f5a28257b50e72750f51a03d6ce9ee27ad1439

stage2: fix crash in switch compile error

when the AST for the switch has never been loaded

3 files changed, 15 insertions(+), 10 deletions(-)

BRANCH_TODO deleted-3
...@@ -1,3 +0,0 @@
1 * in SwitchProng resolve, make sure AST tree gets loaded.
2 It will be unloaded if using cached ZIR.
3
src/Module.zig+8-1
...@@ -4419,13 +4419,20 @@ pub const SwitchProngSrc = union(enum) {...@@ -4419,13 +4419,20 @@ pub const SwitchProngSrc = union(enum) {
4419 /// the LazySrcLoc in order to emit a compile error.4419 /// the LazySrcLoc in order to emit a compile error.
4420 pub fn resolve(4420 pub fn resolve(
4421 prong_src: SwitchProngSrc,4421 prong_src: SwitchProngSrc,
4422 gpa: *Allocator,
4422 decl: *Decl,4423 decl: *Decl,
4423 switch_node_offset: i32,4424 switch_node_offset: i32,
4424 range_expand: RangeExpand,4425 range_expand: RangeExpand,
4425 ) LazySrcLoc {4426 ) LazySrcLoc {
4426 @setCold(true);4427 @setCold(true);
4428 const tree = decl.namespace.file_scope.getTree(gpa) catch |err| {
4429 // In this case we emit a warning + a less precise source location.
4430 log.warn("unable to load {s}: {s}", .{
4431 decl.namespace.file_scope.sub_file_path, @errorName(err),
4432 });
4433 return LazySrcLoc{ .node_offset = 0};
4434 };
4427 const switch_node = decl.relativeToNodeIndex(switch_node_offset);4435 const switch_node = decl.relativeToNodeIndex(switch_node_offset);
4428 const tree = decl.namespace.file_scope.tree;
4429 const main_tokens = tree.nodes.items(.main_token);4436 const main_tokens = tree.nodes.items(.main_token);
4430 const node_datas = tree.nodes.items(.data);4437 const node_datas = tree.nodes.items(.data);
4431 const node_tags = tree.nodes.items(.tag);4438 const node_tags = tree.nodes.items(.tag);
src/Sema.zig+7-6
...@@ -4229,18 +4229,19 @@ fn resolveSwitchItemVal(...@@ -4229,18 +4229,19 @@ fn resolveSwitchItemVal(
4229 switch_prong_src: Module.SwitchProngSrc,4229 switch_prong_src: Module.SwitchProngSrc,
4230 range_expand: Module.SwitchProngSrc.RangeExpand,4230 range_expand: Module.SwitchProngSrc.RangeExpand,
4231) InnerError!TypedValue {4231) InnerError!TypedValue {
4232 const mod = sema.mod;
4232 const item = try sema.resolveInst(item_ref);4233 const item = try sema.resolveInst(item_ref);
4233 // We have to avoid the other helper functions here because we cannot construct a LazySrcLoc4234 // We have to avoid the other helper functions here because we cannot construct a LazySrcLoc
4234 // because we only have the switch AST node. Only if we know for sure we need to report4235 // because we only have the switch AST node. Only if we know for sure we need to report
4235 // a compile error do we resolve the full source locations.4236 // a compile error do we resolve the full source locations.
4236 if (item.value()) |val| {4237 if (item.value()) |val| {
4237 if (val.isUndef()) {4238 if (val.isUndef()) {
4238 const src = switch_prong_src.resolve(block.src_decl, switch_node_offset, range_expand);4239 const src = switch_prong_src.resolve(mod, block.src_decl, switch_node_offset, range_expand);
4239 return sema.failWithUseOfUndef(block, src);4240 return sema.failWithUseOfUndef(block, src);
4240 }4241 }
4241 return TypedValue{ .ty = item.ty, .val = val };4242 return TypedValue{ .ty = item.ty, .val = val };
4242 }4243 }
4243 const src = switch_prong_src.resolve(block.src_decl, switch_node_offset, range_expand);4244 const src = switch_prong_src.resolve(mod, block.src_decl, switch_node_offset, range_expand);
4244 return sema.failWithNeededComptime(block, src);4245 return sema.failWithNeededComptime(block, src);
4245}4246}
42464247
...@@ -4284,7 +4285,7 @@ fn validateSwitchItemEnum(...@@ -4284,7 +4285,7 @@ fn validateSwitchItemEnum(
4284 const item_tv = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none);4285 const item_tv = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none);
4285 const field_index = item_tv.ty.enumTagFieldIndex(item_tv.val) orelse {4286 const field_index = item_tv.ty.enumTagFieldIndex(item_tv.val) orelse {
4286 const msg = msg: {4287 const msg = msg: {
4287 const src = switch_prong_src.resolve(block.src_decl, src_node_offset, .none);4288 const src = switch_prong_src.resolve(mod, block.src_decl, src_node_offset, .none);
4288 const msg = try mod.errMsg(4289 const msg = try mod.errMsg(
4289 &block.base,4290 &block.base,
4290 src,4291 src,
...@@ -4316,8 +4317,8 @@ fn validateSwitchDupe(...@@ -4316,8 +4317,8 @@ fn validateSwitchDupe(
4316) InnerError!void {4317) InnerError!void {
4317 const prev_prong_src = maybe_prev_src orelse return;4318 const prev_prong_src = maybe_prev_src orelse return;
4318 const mod = sema.mod;4319 const mod = sema.mod;
4319 const src = switch_prong_src.resolve(block.src_decl, src_node_offset, .none);4320 const src = switch_prong_src.resolve(mod, block.src_decl, src_node_offset, .none);
4320 const prev_src = prev_prong_src.resolve(block.src_decl, src_node_offset, .none);4321 const prev_src = prev_prong_src.resolve(mod, block.src_decl, src_node_offset, .none);
4321 const msg = msg: {4322 const msg = msg: {
4322 const msg = try mod.errMsg(4323 const msg = try mod.errMsg(
4323 &block.base,4324 &block.base,
...@@ -4354,7 +4355,7 @@ fn validateSwitchItemBool(...@@ -4354,7 +4355,7 @@ fn validateSwitchItemBool(
4354 false_count.* += 1;4355 false_count.* += 1;
4355 }4356 }
4356 if (true_count.* + false_count.* > 2) {4357 if (true_count.* + false_count.* > 2) {
4357 const src = switch_prong_src.resolve(block.src_decl, src_node_offset, .none);4358 const src = switch_prong_src.resolve(mod, block.src_decl, src_node_offset, .none);
4358 return sema.mod.fail(&block.base, src, "duplicate switch value", .{});4359 return sema.mod.fail(&block.base, src, "duplicate switch value", .{});
4359 }4360 }
4360}4361}