Skip to content

Commit 2aa0e82

Browse files
committed
cfg boolean literals
1 parent ffb2c46 commit 2aa0e82

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

text/0000-cfg_boolean_literal.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
- Feature Name: `cfg_boolean_literal`
2+
- Start Date: 2024-09-16
3+
- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)
4+
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
Allow `true` and `false` boolean literals as `cfg` predicates, i.e. `cfg(true)`/`cfg(false)`.
10+
11+
# Motivation
12+
[motivation]: #motivation
13+
14+
Often, we may want to temporarily disable a block of code while working on a project; this can be useful, for example, to disable functions which have errors while refactoring a codebase.
15+
16+
Currently, the easiest ways for programmers to do this are to comment out the code block (which means syntax highlighting no longer works), or to use `cfg(any())` (which is not explicit in meaning).
17+
18+
By allowing `#[cfg(false)]`, we can provide programmers with an explicit and more intuitive way to disable code, while retaining IDE functionality.
19+
20+
Allowing `cfg(true)` would also make temporarily enabling `cfg`'ed out code easier; a `true` may be added to the end of a `cfg(any(..))` list.
21+
22+
# Guide-level explanation
23+
[guide-level-explanation]: #guide-level-explanation
24+
25+
Boolean literals (i.e. `true` and `false`) may be used as `cfg` predicates, to evaluate as always true/false respectively.
26+
27+
# Reference-level explanation
28+
[reference-level-explanation]: #reference-level-explanation
29+
30+
The syntax for configuration predicates should be extended to include boolean literals:
31+
32+
> **<sup>Syntax</sup>**\
33+
> _ConfigurationPredicate_ :\
34+
> &nbsp;&nbsp; &nbsp;&nbsp; _ConfigurationOption_\
35+
> &nbsp;&nbsp; | _ConfigurationAll_\
36+
> &nbsp;&nbsp; | _ConfigurationAny_\
37+
> &nbsp;&nbsp; | _ConfigurationNot_ \
38+
> &nbsp;&nbsp; | `true` | `false`
39+
40+
And the line
41+
> - `true` or `false` literals, which are always `true`/`false` respectively
42+
43+
should be added to the explanation of the predicates.
44+
45+
# Drawbacks
46+
[drawbacks]: #drawbacks
47+
48+
By making it more convenient, this may encourage unconditionally disabled blocks of code being committed, which is undesirable.
49+
50+
# Rationale and alternatives
51+
[rationale-and-alternatives]: #rationale-and-alternatives
52+
53+
- This could instead be spelled as `cfg(disabled|enabled)`, or `cfg(none)` for disabling code only
54+
- Giving special meaning to a valid identifier can change the meaning of existing code (although `check-cfg` warnings should reduce the impact of this)
55+
- As the existing predicates evaluate to booleans, using boolean literals is the most intuitive way to spell this
56+
57+
# Prior art
58+
[prior-art]: #prior-art
59+
60+
Many languages with conditional compilation constructs have a way to disable a blog entirely.
61+
62+
- C: `#if 0`
63+
- C#: `#if false`
64+
- Dlang: `version(none)`
65+
- Haskell: `#if 0`
66+
67+
Searching for `cfg(false)` on [GitHub](https://github.com/search?q=%23%5Bcfg%28false%29%5D+language%3ARust&type=code) reveals many examples of projects (including Rust itself) using `cfg(FALSE)` as a way to get this behavior - although this raises a `check-cfg` warning.
68+
69+
# Future possibilities
70+
[future-possibilities]: #future-possibilities
71+
72+
A future lint could suggest replacing constructs such as `cfg(any())` with `cfg(false)`.
73+
74+
The `check-cfg` lint could be with a special case for identifiers such as `FALSE` and suggest `cfg(false)` instead.

0 commit comments

Comments
 (0)