Build Diagnostics
#Error("…") and #Warn("…") are messages from the source to whoever builds it. Written as a directive, #Error stops the build where the compiler reaches it and #Warn prints a warning and lets the build go on. Neither produces any code.
directive = ( "#Error" | "#Warn" ) "(" string-literal ")"
import Core::{ #target, #Error };
func Main() -> int {
when #target.pointerBits < 64 {
#Error("this program needs a 64-bit target");
}
return 0;
}
On a build that reaches it, the error points at the directive itself:
Src/Main.rux:5:9: error: this program needs a 64-bit target
The same names written above a declaration are attributes, which fire at every call of that declaration instead — see #Error and #Warn.
They run after when
Directives are evaluated after conditional compilation has chosen its branches, and a branch that is not taken is never looked at — so a directive in it never fires. That is how they are meant to be used: #Error in the branch a build should never take, #Warn in the branch that deserves a remark. A directive outside any when is always reached, so a bare #Error("…"); in a body stops every build on every target.
Where they may be written
| Position | Form | Import from Core |
|---|---|---|
| a statement in a function body | #Error("…"); | yes |
a bare-expression arm of a when match in a body | .AArch64 => #Warn("…"), | yes |
an arm of a when match between declarations | else => #Error("…") | no |
Between declarations, the match arm is the only place a directive can stand. Inside the braces of a declaration-level when chain, #Error("…") is read as the start of an attribute, and the compiler then wants a declaration after it:
error: expected a declaration after the attributes before '}'
Write the declaration-level check as a match with an else arm:
import Core::{ #target };
when #target.os {
.FreeBSD, .Linux, .macOS => const Separator: char8[..] = "/";
.Windows => const Separator: char8[..] = "\\";
else => #Error("this package does not know the path separator of this system")
}
As a statement, a directive is a call to the intrinsic functions Core declares (pub intrinsic func #Error(message: char8[..]);), so it must be imported; without the import the build fails with error: name '#Warn' is not defined in this scope.
The message
The message must be a string literal written in place — it is printed while compiling, before any constant or variable has a value at run time. A constant is refused:
error: '#Warn' message must be a string literal
rux 0.4.0 does not report a non-literal message in a declaration-level
when arm such as .Windows => #Error(Message); the compiler stops responding instead. Keep the message a literal.Escapes in the literal work as in any string (\n, \", …). Write the message for the person building: say what is unsupported and, where it helps, what to do instead.
See also
- Conditional compilation — choosing the branch a directive sits in
#Errorand#Warn— the attribute forms, reported at each call- Panics —
PanicandAssert, which stop the running program instead - API:
#Error,#Warn· Learn: Compile error