authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-02 17:37:27-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-01-02 17:37:27-05:00
logdf5fcf5432bc25faf8e981c3ce74820b5f1ea3c7
tree0ca9f031a799dfc43363fa87a6e1b5cf3140f690
parent0b99c83c21f9899cb7e8fb876caf0b005b5121c7
parentb048fa4f1377c84327f74fd4ecd5b03141e68e36
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #14159 from Vexu/err-fix

Sema: prevent spurious "depends on itself" errors

2 files changed, 59 insertions(+), 5 deletions(-)

src/Sema.zig+48-5
......@@ -2536,6 +2536,9 @@ fn coerceResultPtr(
25362536 .wrap_errunion_payload => {
25372537 new_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, new_ptr, false, true);
25382538 },
2539 .array_to_slice => {
2540 return sema.fail(block, src, "TODO coerce_result_ptr array_to_slice", .{});
2541 },
25392542 else => {
25402543 if (std.debug.runtime_safety) {
25412544 std.debug.panic("unexpected AIR tag for coerce_result_ptr: {}", .{
......@@ -7839,7 +7842,23 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
78397842
78407843 if (try sema.resolveMaybeUndefVal(operand)) |int_val| {
78417844 if (dest_ty.isNonexhaustiveEnum()) {
7842 return sema.addConstant(dest_ty, int_val);
7845 var buffer: Type.Payload.Bits = undefined;
7846 const int_tag_ty = dest_ty.intTagType(&buffer);
7847 if (try sema.intFitsInType(int_val, int_tag_ty, null)) {
7848 return sema.addConstant(dest_ty, int_val);
7849 }
7850 const msg = msg: {
7851 const msg = try sema.errMsg(
7852 block,
7853 src,
7854 "int value '{}' out of range of non-exhaustive enum '{}'",
7855 .{ int_val.fmtValue(sema.typeOf(operand), sema.mod), dest_ty.fmt(sema.mod) },
7856 );
7857 errdefer msg.destroy(sema.gpa);
7858 try sema.addDeclaredHereNote(msg, dest_ty);
7859 break :msg msg;
7860 };
7861 return sema.failWithOwnedErrorMsg(msg);
78437862 }
78447863 if (int_val.isUndef()) {
78457864 return sema.failWithUseOfUndef(block, operand_src);
......@@ -30318,6 +30337,18 @@ fn resolveTypeFieldsStruct(
3031830337 ty: Type,
3031930338 struct_obj: *Module.Struct,
3032030339) CompileError!void {
30340 switch (sema.mod.declPtr(struct_obj.owner_decl).analysis) {
30341 .file_failure,
30342 .dependency_failure,
30343 .sema_failure,
30344 .sema_failure_retryable,
30345 => {
30346 sema.owner_decl.analysis = .dependency_failure;
30347 sema.owner_decl.generation = sema.mod.generation;
30348 return error.AnalysisFail;
30349 },
30350 else => {},
30351 }
3032130352 switch (struct_obj.status) {
3032230353 .none => {},
3032330354 .field_types_wip => {
......@@ -30338,10 +30369,23 @@ fn resolveTypeFieldsStruct(
3033830369 }
3033930370
3034030371 struct_obj.status = .field_types_wip;
30372 errdefer struct_obj.status = .none;
3034130373 try semaStructFields(sema.mod, struct_obj);
3034230374}
3034330375
3034430376fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_obj: *Module.Union) CompileError!void {
30377 switch (sema.mod.declPtr(union_obj.owner_decl).analysis) {
30378 .file_failure,
30379 .dependency_failure,
30380 .sema_failure,
30381 .sema_failure_retryable,
30382 => {
30383 sema.owner_decl.analysis = .dependency_failure;
30384 sema.owner_decl.generation = sema.mod.generation;
30385 return error.AnalysisFail;
30386 },
30387 else => {},
30388 }
3034530389 switch (union_obj.status) {
3034630390 .none => {},
3034730391 .field_types_wip => {
......@@ -30362,6 +30406,7 @@ fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_obj: *Module.Union) Compi
3036230406 }
3036330407
3036430408 union_obj.status = .field_types_wip;
30409 errdefer union_obj.status = .none;
3036530410 try semaUnionFields(sema.mod, union_obj);
3036630411 union_obj.status = .have_field_types;
3036730412}
......@@ -30426,9 +30471,7 @@ fn resolveInferredErrorSetTy(
3042630471fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void {
3042730472 const gpa = mod.gpa;
3042830473 const decl_index = struct_obj.owner_decl;
30429 const file_scope = struct_obj.namespace.file_scope;
30430 if (file_scope.status != .success_zir) return error.AnalysisFail;
30431 const zir = file_scope.zir;
30474 const zir = struct_obj.namespace.file_scope.zir;
3043230475 const extended = zir.instructions.items(.data)[struct_obj.zir_index].extended;
3043330476 assert(extended.opcode == .struct_decl);
3043430477 const small = @bitCast(Zir.Inst.StructDecl.Small, extended.small);
......@@ -32886,7 +32929,7 @@ fn enumHasInt(
3288632929 int: Value,
3288732930) CompileError!bool {
3288832931 switch (ty.tag()) {
32889 .enum_nonexhaustive => return sema.intFitsInType(int, ty, null),
32932 .enum_nonexhaustive => unreachable,
3289032933 .enum_full => {
3289132934 const enum_full = ty.castTag(.enum_full).?.data;
3289232935 const tag_ty = enum_full.tag_ty;
test/cases/compile_errors/intToEnum_on_non-exhaustive_enums_checks_int_in_range.zig created+11
......@@ -0,0 +1,11 @@
1pub export fn entry() void {
2 const E = enum(u3) { a, b, c, _ };
3 @compileLog(@intToEnum(E, 100));
4}
5
6// error
7// target=native
8// backend=stage2
9//
10// :3:17: error: int value '100' out of range of non-exhaustive enum 'tmp.entry.E'
11// :2:15: note: enum declared here