-
Notifications
You must be signed in to change notification settings - Fork 1.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
Add a compile_error!
macro to libstd
#1695
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
- Feature Name: compile\_error\_macro | ||
- Start Date: 2016-08-01 | ||
- RFC PR: (leave this empty) | ||
- Rust Issue: (leave this empty) | ||
|
||
# Summary | ||
[summary]: #summary | ||
|
||
This RFC proposes adding a new macro to `libcore`, `compile_error!` which will | ||
unconditionally cause compilation to fail with the given error message when | ||
encountered. | ||
|
||
# Motivation | ||
[motivation]: #motivation | ||
|
||
Crates which work with macros or annotations such as `cfg` have no tools to | ||
communicate error cases in a meaningful way on stable. For example, given the | ||
following macro: | ||
|
||
```rust | ||
macro_rules! give_me_foo_or_bar { | ||
(foo) => {}; | ||
(bar) => {}; | ||
} | ||
``` | ||
|
||
when invoked with `baz`, the error message will be `error: no rules expected the | ||
token baz`. In a real world scenario, this error may actually occur deep in a | ||
stack of macro calls, with an even more confusing error message. With this RFC, | ||
the macro author could provide the following: | ||
|
||
```rust | ||
macro_rules! give_me_foo_or_bar { | ||
(foo) => {}; | ||
(bar) => {}; | ||
($x:ident) => { | ||
compile_error!("This macro only accepts `foo` or `bar`"); | ||
} | ||
} | ||
``` | ||
|
||
When combined with attributes, this also provides a way for authors to validate | ||
combinations of features. | ||
|
||
```rust | ||
#[cfg(not(any(feature = "postgresql", feature = "sqlite")))] | ||
compile_error!("At least one backend must be used with this crate. \ | ||
Please specify `features = ["postgresql"]` or `features = ["sqlite"]`") | ||
``` | ||
|
||
# Detailed design | ||
[design]: #detailed-design | ||
|
||
The span given for the failure should be the invocation of the `compile_error!` | ||
macro. The macro must take exactly one argument, which is a string literal. The | ||
macro will then call `span_err` with the provided message on the expansion | ||
context, and will not expand to any further code. | ||
|
||
# Drawbacks | ||
[drawbacks]: #drawbacks | ||
|
||
None | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It adds another language-aware macro. When we do have proc macros, there will be overlap between this feature and more sophisticated error handling for proc macros which might be exposed to macro_rules somehow. |
||
|
||
# Alternatives | ||
[alternatives]: #alternatives | ||
|
||
Wait for the stabilization of procedural macros, at which point a crate could | ||
provide this functionality. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems there is some overlap with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIRC Rust did not had |
||
|
||
# Unresolved questions | ||
[unresolved]: #unresolved-questions | ||
|
||
None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be worth accepting a format string rather than a plain string literal? Errors seem like the kind of thing that would be commonly customised?
Is it also worth accepting alternative spans some how? That seems like a useful tool, but I don't have an idea for how it would work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that this entirely at compile time, I'm not sure that there's anything that we could format that wouldn't be equally handled by
concat!
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only way I can think of to accept alternative spans would be to take a file/line number/char number triple, which I think is fine as an option if folks are in favor of it.