Resolves #32119
The @compileError builtin function now takes a variable number of args, each of which can be either a comptime-known string or a type. The emitted compile error will be a concatenation of all args with pretty-printed type names (削除) and spaces in between (削除ここまで). It will also include a 'declared here' note for each type it's passed, which wasn't possible to do with ++ string concatenation and @typeName:
constS=struct{};exportfnfoo()void{@compileError("wrong type: ",S);}myfile.zig:3:5: error: wrong type: myfile.S
@compileError("wrong type: ", S);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
myfile.zig:1:11: note: struct declared here
const S = struct {};
^~~~~~~~~
Passing zero arguments to @compileError is a compile error itself, the programmer should use comptime unreachable instead. @compileError("") is still possible if an empty error message is desired.
(削除) Quick justification for putting spaces between args: literally every single time I've used some_str ++ @typeName(...) I've surrounded the type name with spaces anyway and probably half the time I've forgotten to do so only to realize it some time later when I'm hit with an ugly compile error, so even though this is more restrictive and arguably less explicit than letting the user put the spaces there instead I think it's just more convenient (ofc open to reverting that, it's a single LOC). (削除ここまで)
EDIT: reverted, see comments and commit message
The error message generation in zirCompileError for invalid args is also kind of... quirky? This is the only case I'm aware of where a coercion to two different types is supposed to succeed, so since there's not really an established code path for that I've decided to first check whether an arg is a type since only undefined can coerce to type and bare undefined should always a compile error here IMO since it's ambiguous (typed @as(type, undefined) is still possible this way as I think it's reasonable to allow that). Then I try to coerce it to []const u8. The issue here is that the error message will only say that []const u8 is expected, and say nothing about type also being a possibility. But there's also potentially valuable information in the error notes added by coerce. So I've ended up doing the full coercion to []const u8 and then catching the error message emitted by that and replacing it with a custom error message that also mentions type. I've found that to be much clearer than just attaching a note about type at the bottom of the error or reparenting the coercion error to something that also mentions type.