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(...@@ -2536,6 +2536,9 @@ fn coerceResultPtr(
2536 .wrap_errunion_payload => {2536 .wrap_errunion_payload => {
2537 new_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, new_ptr, false, true);2537 new_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, new_ptr, false, true);
2538 },2538 },
2539 .array_to_slice => {
2540 return sema.fail(block, src, "TODO coerce_result_ptr array_to_slice", .{});
2541 },
2539 else => {2542 else => {
2540 if (std.debug.runtime_safety) {2543 if (std.debug.runtime_safety) {
2541 std.debug.panic("unexpected AIR tag for coerce_result_ptr: {}", .{2544 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...@@ -7839,7 +7842,23 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
78397842
7840 if (try sema.resolveMaybeUndefVal(operand)) |int_val| {7843 if (try sema.resolveMaybeUndefVal(operand)) |int_val| {
7841 if (dest_ty.isNonexhaustiveEnum()) {7844 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);
7843 }7862 }
7844 if (int_val.isUndef()) {7863 if (int_val.isUndef()) {
7845 return sema.failWithUseOfUndef(block, operand_src);7864 return sema.failWithUseOfUndef(block, operand_src);
...@@ -30318,6 +30337,18 @@ fn resolveTypeFieldsStruct(...@@ -30318,6 +30337,18 @@ fn resolveTypeFieldsStruct(
30318 ty: Type,30337 ty: Type,
30319 struct_obj: *Module.Struct,30338 struct_obj: *Module.Struct,
30320) CompileError!void {30339) 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 }
30321 switch (struct_obj.status) {30352 switch (struct_obj.status) {
30322 .none => {},30353 .none => {},
30323 .field_types_wip => {30354 .field_types_wip => {
...@@ -30338,10 +30369,23 @@ fn resolveTypeFieldsStruct(...@@ -30338,10 +30369,23 @@ fn resolveTypeFieldsStruct(
30338 }30369 }
3033930370
30340 struct_obj.status = .field_types_wip;30371 struct_obj.status = .field_types_wip;
30372 errdefer struct_obj.status = .none;
30341 try semaStructFields(sema.mod, struct_obj);30373 try semaStructFields(sema.mod, struct_obj);
30342}30374}
3034330375
30344fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_obj: *Module.Union) CompileError!void {30376fn 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 }
30345 switch (union_obj.status) {30389 switch (union_obj.status) {
30346 .none => {},30390 .none => {},
30347 .field_types_wip => {30391 .field_types_wip => {
...@@ -30362,6 +30406,7 @@ fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_obj: *Module.Union) Compi...@@ -30362,6 +30406,7 @@ fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_obj: *Module.Union) Compi
30362 }30406 }
3036330407
30364 union_obj.status = .field_types_wip;30408 union_obj.status = .field_types_wip;
30409 errdefer union_obj.status = .none;
30365 try semaUnionFields(sema.mod, union_obj);30410 try semaUnionFields(sema.mod, union_obj);
30366 union_obj.status = .have_field_types;30411 union_obj.status = .have_field_types;
30367}30412}
...@@ -30426,9 +30471,7 @@ fn resolveInferredErrorSetTy(...@@ -30426,9 +30471,7 @@ fn resolveInferredErrorSetTy(
30426fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void {30471fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void {
30427 const gpa = mod.gpa;30472 const gpa = mod.gpa;
30428 const decl_index = struct_obj.owner_decl;30473 const decl_index = struct_obj.owner_decl;
30429 const file_scope = struct_obj.namespace.file_scope;30474 const zir = struct_obj.namespace.file_scope.zir;
30430 if (file_scope.status != .success_zir) return error.AnalysisFail;
30431 const zir = file_scope.zir;
30432 const extended = zir.instructions.items(.data)[struct_obj.zir_index].extended;30475 const extended = zir.instructions.items(.data)[struct_obj.zir_index].extended;
30433 assert(extended.opcode == .struct_decl);30476 assert(extended.opcode == .struct_decl);
30434 const small = @bitCast(Zir.Inst.StructDecl.Small, extended.small);30477 const small = @bitCast(Zir.Inst.StructDecl.Small, extended.small);
...@@ -32886,7 +32929,7 @@ fn enumHasInt(...@@ -32886,7 +32929,7 @@ fn enumHasInt(
32886 int: Value,32929 int: Value,
32887) CompileError!bool {32930) CompileError!bool {
32888 switch (ty.tag()) {32931 switch (ty.tag()) {
32889 .enum_nonexhaustive => return sema.intFitsInType(int, ty, null),32932 .enum_nonexhaustive => unreachable,
32890 .enum_full => {32933 .enum_full => {
32891 const enum_full = ty.castTag(.enum_full).?.data;32934 const enum_full = ty.castTag(.enum_full).?.data;
32892 const tag_ty = enum_full.tag_ty;32935 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