Type: remove arbitrary restrictions on param and return types

Opaque and `noreturn` makes sense since they don't represent real
values, but `null` and `undefined` are perfectly normal
comptime-only values.

Closes #16088
This commit is contained in:
Jacob Young 2023-06-20 13:12:15 -04:00 committed by Andrew Kelley
parent e2eabbbc51
commit a257e33fff
4 changed files with 17 additions and 25 deletions

View File

@ -2405,14 +2405,14 @@ pub const Type = struct {
pub fn isValidParamType(self: Type, mod: *const Module) bool { pub fn isValidParamType(self: Type, mod: *const Module) bool {
return switch (self.zigTypeTagOrPoison(mod) catch return true) { return switch (self.zigTypeTagOrPoison(mod) catch return true) {
.Undefined, .Null, .Opaque, .NoReturn => false, .Opaque, .NoReturn => false,
else => true, else => true,
}; };
} }
pub fn isValidReturnType(self: Type, mod: *const Module) bool { pub fn isValidReturnType(self: Type, mod: *const Module) bool {
return switch (self.zigTypeTagOrPoison(mod) catch return true) { return switch (self.zigTypeTagOrPoison(mod) catch return true) {
.Undefined, .Null, .Opaque => false, .Opaque => false,
else => true, else => true,
}; };
} }

View File

@ -580,3 +580,17 @@ test "lazy values passed to anytype parameter" {
const D = struct {}; const D = struct {};
try expect(@sizeOf(D) << 1 == 0); try expect(@sizeOf(D) << 1 == 0);
} }
test "pass and return comptime-only types" {
const S = struct {
fn returnNull(comptime x: @Type(.Null)) @Type(.Null) {
return x;
}
fn returnUndefined(comptime x: @Type(.Undefined)) @Type(.Undefined) {
return x;
}
};
try expectEqual(null, S.returnNull(null));
try expectEqual(@as(u0, 0), S.returnUndefined(undefined));
}

View File

@ -4,11 +4,6 @@ export fn entry1() void {
_ = someFuncPtr; _ = someFuncPtr;
} }
export fn entry2() void {
const someFuncPtr: fn (@TypeOf(null)) void = undefined;
_ = someFuncPtr;
}
fn foo(p: FooType) void { fn foo(p: FooType) void {
_ = p; _ = p;
} }
@ -16,20 +11,11 @@ export fn entry3() void {
_ = foo; _ = foo;
} }
fn bar(p: @TypeOf(null)) void {
_ = p;
}
export fn entry4() void {
_ = bar;
}
// error // error
// backend=stage2 // backend=stage2
// target=native // target=native
// //
// :3:28: error: parameter of opaque type 'tmp.FooType' not allowed // :3:28: error: parameter of opaque type 'tmp.FooType' not allowed
// :1:17: note: opaque declared here // :1:17: note: opaque declared here
// :8:28: error: parameter of type '@TypeOf(null)' not allowed // :7:8: error: parameter of opaque type 'tmp.FooType' not allowed
// :12:8: error: parameter of opaque type 'tmp.FooType' not allowed
// :1:17: note: opaque declared here // :1:17: note: opaque declared here
// :19:8: error: parameter of type '@TypeOf(null)' not allowed

View File

@ -2,12 +2,6 @@ const FooType = opaque {};
export fn bar() FooType { export fn bar() FooType {
return error.InvalidValue; return error.InvalidValue;
} }
export fn bav() @TypeOf(null) {
return error.InvalidValue;
}
export fn baz() @TypeOf(undefined) {
return error.InvalidValue;
}
// error // error
// backend=stage2 // backend=stage2
@ -15,5 +9,3 @@ export fn baz() @TypeOf(undefined) {
// //
// :2:17: error: opaque return type 'tmp.FooType' not allowed // :2:17: error: opaque return type 'tmp.FooType' not allowed
// :1:17: note: opaque declared here // :1:17: note: opaque declared here
// :5:17: error: return type '@TypeOf(null)' not allowed
// :8:17: error: return type '@TypeOf(undefined)' not allowed