-
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
RFC: Overhaul the #[cfg(..)]
pattern syntax
#194
Merged
Merged
Changes from 1 commit
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
- Start Date: 2014-08-09 | ||
- RFC PR: | ||
- Rust Issue: | ||
|
||
# Summary | ||
|
||
The `#[cfg(...)]` attribute provides a mechanism for conditional compilation of | ||
items in a Rust crate. This RFC proposes to change the syntax of `#[cfg]` to | ||
make more sense as well as enable expansion of the conditional compilation | ||
system to attributes while maintaining a single syntax. | ||
|
||
# Motivation | ||
|
||
In the current implementation, `#[cfg(...)]` takes a comma separated list of | ||
`key`, `key = "value"`, `not(key)`, or `not(key = "value")`. An individual | ||
`#[cfg(...)]` attribute "matches" if *all* of the contained cfg patterns match | ||
the compilation environment, and an item preserved if it *either* has no | ||
`#[cfg(...)]` attributes or *any* of the `#[cfg(...)]` attributes present | ||
match. | ||
|
||
This is problematic for several reasons: | ||
|
||
* It is excessively verbose in certain situations. For example, implementing | ||
the equivalent of `(a AND (b OR c OR d))` requires three separate | ||
attributes and `a` to be duplicated in each. | ||
* It differs from all other attributes in that all `#[cfg(...)]` attributes on | ||
an item must be processed together instead of in isolation. This change | ||
will move `#[cfg(...)]` closer to implementation as a normal syntax | ||
extension. | ||
|
||
# Detailed design | ||
|
||
The `<p>` inside of `#[cfg(<p>)]` will be called a *cfg pattern* and have a | ||
simple recursive syntax: | ||
|
||
* `key` is a cfg pattern and will match if `key` is present in the | ||
compilation environment. | ||
* `key = "value"` is a cfg pattern and will match if a mapping from `key` | ||
to `value` is present in the compilation environment. At present, key-value | ||
pairs only exist for compiler defined keys such as `target_os` and | ||
`endian`. | ||
* `not(<p>)` is a cfg pattern if `<p>` is and matches if `<p>` does not match. | ||
* `all(<p>, ...)` is a cfg pattern if all of the comma-separated `<p>`s are cfg | ||
patterns and all of them match. | ||
* `any(<p>, ...)` is a cfg pattern if all of the comma-separated `<p>`s are cfg | ||
patterns and any of them match. | ||
|
||
If an item is tagged with `#[cfg(<p>)]`, that item will be stripped from the | ||
AST if the cfg pattern `<p>` does not match. | ||
|
||
One implementation hazard is that the semantics of | ||
```rust | ||
#[cfg(a)] | ||
#[cfg(b)] | ||
fn foo() {} | ||
``` | ||
will change from "include `foo` if *either of* `a` and `b` are present in the | ||
compilation environment" to "include `foo` if *both of* `a` and `b` are present | ||
in the compilation environment". To ease the transition it will be an error to | ||
have multiple `#[cfg(...)]` attributes on a single item for some reasonable | ||
period of time. | ||
|
||
The `cfg!()` syntax extension will be modified to accept cfg patterns as well. | ||
A `#[cfg_attr(<p>, <attr>)]` syntax extension will be added | ||
([PR 16230](https://github.com/rust-lang/rust/pull/16230)) which will expand to | ||
`#[<attr>]` if the cfg pattern `<p>` matches. The test harness's | ||
`#[ignore]` attribute will have its built-in cfg filtering | ||
functionality stripped in favor of `#[cfg_attr(<p>, ignore)]`. | ||
|
||
# Drawbacks | ||
|
||
While the implementation of this change in the compiler will be | ||
straightforward, the effects on downstream code will be significant, especially | ||
in the standard library. | ||
|
||
# Alternatives | ||
|
||
`all` and `any` could be renamed to `and` and `or`, though I feel that the | ||
proposed names read better with the function-like syntax and are consistent | ||
with `Iterator::all` and `Iterator::any`. | ||
|
||
Issue [#2119](https://github.com/rust-lang/rust/issuse/2119) proposed the | ||
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. typo, link should point to rust/issues/2119 (s/issuse/issues) |
||
addition of `||` and `&&` operators and parantheses to the attribute syntax | ||
to result in something like `#[cfg(a || (b && c)]`. I don't favor this proposal | ||
since it would result in a major change to the attribute syntax for relatively | ||
little readability gain. | ||
|
||
# Unresolved questions | ||
|
||
How long should multiple `#[cfg(...)]` attributes on a single item be | ||
forbidden? It should probably be at least until after 0.12 releases. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
I don't think it's entirely crazy for multiple
cfg
s to be an error indefinitely.