authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-09 00:20:43-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-09 05:46:44-04:00
log66084b6c3f78349a7730c02614125185df8b6672
tree3981c3c1d5f1fc036b468e2377be1a1bb14859bc
parentcd7998096b624b326dddcbb2752fe4bcdac8df9f

Sema: remove `validateRunTimeType`

This function does not seem to differ in any interesting way from `!typeRequiresComptime`, other than the `is_extern` param which is only used in one place, and some differences did not seem correct anyway. My reasoning for changing opaque types to be comptime-only is that `explainWhyTypeIsComptime` is quite happy to explain why they are. :D

3 files changed, 22 insertions(+), 73 deletions(-)

src/Sema.zig+11-67
...@@ -5034,7 +5034,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -5034,7 +5034,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
5034 if (val.isUndef(mod)) {5034 if (val.isUndef(mod)) {
5035 return sema.fail(block, src, "cannot dereference undefined value", .{});5035 return sema.fail(block, src, "cannot dereference undefined value", .{});
5036 }5036 }
5037 } else if (!(try sema.validateRunTimeType(elem_ty, false))) {5037 } else if (try sema.typeRequiresComptime(elem_ty)) {
5038 const msg = msg: {5038 const msg = msg: {
5039 const msg = try sema.errMsg(5039 const msg = try sema.errMsg(
5040 block,5040 block,
...@@ -5792,8 +5792,7 @@ fn analyzeBlockBody(...@@ -5792,8 +5792,7 @@ fn analyzeBlockBody(
5792 // TODO add note "missing else causes void value"5792 // TODO add note "missing else causes void value"
57935793
5794 const type_src = src; // TODO: better source location5794 const type_src = src; // TODO: better source location
5795 const valid_rt = try sema.validateRunTimeType(resolved_ty, false);5795 if (try sema.typeRequiresComptime(resolved_ty)) {
5796 if (!valid_rt) {
5797 const msg = msg: {5796 const msg = msg: {
5798 const msg = try sema.errMsg(child_block, type_src, "value with comptime-only type '{}' depends on runtime control flow", .{resolved_ty.fmt(mod)});5797 const msg = try sema.errMsg(child_block, type_src, "value with comptime-only type '{}' depends on runtime control flow", .{resolved_ty.fmt(mod)});
5799 errdefer msg.destroy(sema.gpa);5798 errdefer msg.destroy(sema.gpa);
...@@ -24414,7 +24413,8 @@ fn validateVarType(...@@ -24414,7 +24413,8 @@ fn validateVarType(
24414 return sema.failWithOwnedErrorMsg(msg);24413 return sema.failWithOwnedErrorMsg(msg);
24415 }24414 }
2441624415
24417 if (try sema.validateRunTimeType(var_ty, is_extern)) return;24416 if (is_extern and var_ty.zigTypeTag(mod) == .Opaque) return;
24417 if (!try sema.typeRequiresComptime(var_ty)) return;
2441824418
24419 const msg = msg: {24419 const msg = msg: {
24420 const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(mod)});24420 const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(mod)});
...@@ -24431,61 +24431,6 @@ fn validateVarType(...@@ -24431,61 +24431,6 @@ fn validateVarType(
24431 return sema.failWithOwnedErrorMsg(msg);24431 return sema.failWithOwnedErrorMsg(msg);
24432}24432}
2443324433
24434fn validateRunTimeType(
24435 sema: *Sema,
24436 var_ty: Type,
24437 is_extern: bool,
24438) CompileError!bool {
24439 const mod = sema.mod;
24440 var ty = var_ty;
24441 while (true) switch (ty.zigTypeTag(mod)) {
24442 .Bool,
24443 .Int,
24444 .Float,
24445 .ErrorSet,
24446 .Frame,
24447 .AnyFrame,
24448 .Void,
24449 => return true,
24450
24451 .Enum => return !(try sema.typeRequiresComptime(ty)),
24452
24453 .ComptimeFloat,
24454 .ComptimeInt,
24455 .EnumLiteral,
24456 .NoReturn,
24457 .Type,
24458 .Undefined,
24459 .Null,
24460 .Fn,
24461 => return false,
24462
24463 .Pointer => {
24464 const elem_ty = ty.childType(mod);
24465 switch (elem_ty.zigTypeTag(mod)) {
24466 .Opaque => return true,
24467 .Fn => return elem_ty.isFnOrHasRuntimeBits(mod),
24468 else => ty = elem_ty,
24469 }
24470 },
24471 .Opaque => return is_extern,
24472
24473 .Optional => {
24474 const child_ty = ty.optionalChild(mod);
24475 return sema.validateRunTimeType(child_ty, is_extern);
24476 },
24477 .Array, .Vector => ty = ty.childType(mod),
24478
24479 .ErrorUnion => ty = ty.errorUnionPayload(mod),
24480
24481 .Struct, .Union => {
24482 const resolved_ty = try sema.resolveTypeFields(ty);
24483 const needs_comptime = try sema.typeRequiresComptime(resolved_ty);
24484 return !needs_comptime;
24485 },
24486 };
24487}
24488
24489const TypeSet = std.AutoHashMapUnmanaged(InternPool.Index, void);24434const TypeSet = std.AutoHashMapUnmanaged(InternPool.Index, void);
2449024435
24491fn explainWhyTypeIsComptime(24436fn explainWhyTypeIsComptime(
...@@ -26484,8 +26429,7 @@ fn validateRuntimeElemAccess(...@@ -26484,8 +26429,7 @@ fn validateRuntimeElemAccess(
26484 parent_src: LazySrcLoc,26429 parent_src: LazySrcLoc,
26485) CompileError!void {26430) CompileError!void {
26486 const mod = sema.mod;26431 const mod = sema.mod;
26487 const valid_rt = try sema.validateRunTimeType(elem_ty, false);26432 if (try sema.typeRequiresComptime(elem_ty)) {
26488 if (!valid_rt) {
26489 const msg = msg: {26433 const msg = msg: {
26490 const msg = try sema.errMsg(26434 const msg = try sema.errMsg(
26491 block,26435 block,
...@@ -35965,10 +35909,10 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -35965,10 +35909,10 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
35965 .int_type => return false,35909 .int_type => return false,
35966 .ptr_type => |ptr_type| {35910 .ptr_type => |ptr_type| {
35967 const child_ty = ptr_type.child.toType();35911 const child_ty = ptr_type.child.toType();
35968 if (child_ty.zigTypeTag(mod) == .Fn) {35912 switch (child_ty.zigTypeTag(mod)) {
35969 return mod.typeToFunc(child_ty).?.is_generic;35913 .Fn => return mod.typeToFunc(child_ty).?.is_generic,
35970 } else {35914 .Opaque => return false,
35971 return sema.typeRequiresComptime(child_ty);35915 else => return sema.typeRequiresComptime(child_ty),
35972 }35916 }
35973 },35917 },
35974 .anyframe_type => |child| {35918 .anyframe_type => |child| {
...@@ -36005,7 +35949,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -36005,7 +35949,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
36005 .c_longlong,35949 .c_longlong,
36006 .c_ulonglong,35950 .c_ulonglong,
36007 .c_longdouble,35951 .c_longdouble,
36008 .anyopaque,
36009 .bool,35952 .bool,
36010 .void,35953 .void,
36011 .anyerror,35954 .anyerror,
...@@ -36024,6 +35967,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -36024,6 +35967,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
36024 .adhoc_inferred_error_set,35967 .adhoc_inferred_error_set,
36025 => false,35968 => false,
3602635969
35970 .anyopaque,
36027 .type,35971 .type,
36028 .comptime_int,35972 .comptime_int,
36029 .comptime_float,35973 .comptime_float,
...@@ -36091,7 +36035,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {...@@ -36091,7 +36035,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
36091 }36035 }
36092 },36036 },
3609336037
36094 .opaque_type => false,36038 .opaque_type => true,
36095 .enum_type => |enum_type| try sema.typeRequiresComptime(enum_type.tag_ty.toType()),36039 .enum_type => |enum_type| try sema.typeRequiresComptime(enum_type.tag_ty.toType()),
3609636040
36097 // values, not types36041 // values, not types
src/type.zig+6-6
...@@ -2664,10 +2664,10 @@ pub const Type = struct {...@@ -2664,10 +2664,10 @@ pub const Type = struct {
2664 .int_type => false,2664 .int_type => false,
2665 .ptr_type => |ptr_type| {2665 .ptr_type => |ptr_type| {
2666 const child_ty = ptr_type.child.toType();2666 const child_ty = ptr_type.child.toType();
2667 if (child_ty.zigTypeTag(mod) == .Fn) {2667 switch (child_ty.zigTypeTag(mod)) {
2668 return false;2668 .Fn => return mod.typeToFunc(child_ty).?.is_generic,
2669 } else {2669 .Opaque => return false,
2670 return child_ty.comptimeOnly(mod);2670 else => return child_ty.comptimeOnly(mod),
2671 }2671 }
2672 },2672 },
2673 .anyframe_type => |child| {2673 .anyframe_type => |child| {
...@@ -2704,7 +2704,6 @@ pub const Type = struct {...@@ -2704,7 +2704,6 @@ pub const Type = struct {
2704 .c_longlong,2704 .c_longlong,
2705 .c_ulonglong,2705 .c_ulonglong,
2706 .c_longdouble,2706 .c_longdouble,
2707 .anyopaque,
2708 .bool,2707 .bool,
2709 .void,2708 .void,
2710 .anyerror,2709 .anyerror,
...@@ -2723,6 +2722,7 @@ pub const Type = struct {...@@ -2723,6 +2722,7 @@ pub const Type = struct {
2723 .extern_options,2722 .extern_options,
2724 => false,2723 => false,
27252724
2725 .anyopaque,
2726 .type,2726 .type,
2727 .comptime_int,2727 .comptime_int,
2728 .comptime_float,2728 .comptime_float,
...@@ -2769,7 +2769,7 @@ pub const Type = struct {...@@ -2769,7 +2769,7 @@ pub const Type = struct {
2769 }2769 }
2770 },2770 },
27712771
2772 .opaque_type => false,2772 .opaque_type => true,
27732773
2774 .enum_type => |enum_type| enum_type.tag_ty.toType().comptimeOnly(mod),2774 .enum_type => |enum_type| enum_type.tag_ty.toType().comptimeOnly(mod),
27752775
test/behavior/optional.zig+5
...@@ -498,3 +498,8 @@ test "cast slice to const slice nested in error union and optional" {...@@ -498,3 +498,8 @@ test "cast slice to const slice nested in error union and optional" {
498 };498 };
499 try std.testing.expectError(error.Foo, S.outer());499 try std.testing.expectError(error.Foo, S.outer());
500}500}
501
502test "variable of optional of noreturn" {
503 var null_opv: ?noreturn = null;
504 try std.testing.expectEqual(@as(?noreturn, null), null_opv);
505}