-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Prevent @typeInfo and @TypeOf from triggering compile errors #6620
Comments
By the way we already have
|
I ran into a sort of interesting use-case for this. Like many projects, I have a type for a runtime-sized list with a comptime-known maximum length. However, mine is Today I saw #9134, which looks great and would ideally replace my own container type, but it returns a standard struct (that is, non- fn makeLayout(comptime T: type, new_layout: std.builtin.TypeInfo.ContainerLayout) type {
if (@typeInfo(T) != .Struct) {
@compileError("expected struct, got " ++ @tagName(@typeInfo(T)));
}
const struct_info = @typeInfo(T).Struct;
return @Type(.{ .Struct = .{
.layout = new_layout,
.fields = struct_info.fields,
.decls = struct_info.decls,
.is_tuple = struct_info.is_tuple,
} });
} However, I quickly noticed that a couple types I tested this on failed to compile because it triggers the compile errors on deprecated decls. So while this would work initially, if deprecated members were ever added to |
I am interested in seeing at least the In particular, being able to check whether two types can have peer type resolution performed on them would be very useful for being able to construct more complex type check error messages. I have a particular use case, in wanting to modify One way to solve that problem would be to just remove the checks, but then the resulting error message in the case where the types really aren't compatible, become much less useful than they currently are. I have a branch with the basic necessary modifications to Sema for the third option, and I would be happy to go through and update everything else if given the go-ahead. |
Using one other solution to |
Making |
well for that case in the meantime they would have to add |
Another idea that just came to mind would be to make it return a specific type - either a primitive ( |
A minimal fix here might be to add a There might be a good reason why this isn't already the case, but if not, this would allow introspection of container types, without taking a field access on them, and triggering a compile error. Whether a decl |
It sounds like the
It's fundamentally 2 different behaviours wrapped into 1 builtin. Also, notice how one can't tell the difference between "these 2 types don't have a peer" and "the peer type is a compile error" What if a new builtin, Apologies that this is basically reposting #3641, but since this new |
There was a recent discussion, a short one, on Ziggit, which touches on this issue. Mostly I wanted to point out that the issue this is tracking relates to "bottom types", and the ambiguity and differences of approach to it can be clarified by bringing that concept into focus. In sound type systems, Bottom is uninhabited: if type inference derives bottom, then compiling fails. Zig is not interested in building a sound type system, I'm sure, that would make for a very different language. But it's consequential for this discussion, because An answer of Nektro raises a good point about the difference between It doesn't have to have a type-theoretic name like |
An important use case in Zig is the ability to load a module and use reflection to inspect the decarations it exposes. Unfortunately, it's also common to see modules that use
pub const foo = @compileError(..);
for deprecation, specialization, or other purposes like translation errors from translate-c. These two approaches are at odds with each other. This proposal suggests a way to keep the current use of@compileError
and still inspect reflection data without triggering errors.TypeInfo
with tag.CompileError
..CompileError
should be an empty tag, because allowing the metaprogram to inspect the error string could cause difficult to find dependencies on compiler versions.@Type(.CompileError)
which will be used in the decls of the type info of the containing struct.@Type(.CompileError)
is a compile error.@compileError
but also declarations that are invalid for other reasons.@TypeOf
cannot cause a compile error. Instead,@TypeOf(<code that causes compile error>)
returns.CompileError
. This could be useful for a lot of use cases that are currently difficult, likeAll of these use cases are technically solvable with just (1) through (5), but require the use of an intermediate struct whose type info can be inspected. This last point makes that use case a bit cleaner, and unifies the behaviors of "figuring out the type of a declaration for reflection" and "using
@TypeOf
".The text was updated successfully, but these errors were encountered: