Skip to content
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

Rollup of 9 pull requests #94331

Closed
wants to merge 25 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c00f635
Remove in-band lifetimes
compiler-errors Feb 10, 2022
43dbd83
Remove LifetimeDefOrigin
compiler-errors Feb 20, 2022
8ca47d7
Stop manually SIMDing in swap_nonoverlapping
scottmcm Feb 21, 2022
da896d3
Improve CheckCfg internal representation
Urgau Feb 19, 2022
fbe1c15
Add test for well known names defined by rustc
Urgau Feb 19, 2022
3d23477
Improve diagnostic of the unexpected_cfgs lint
Urgau Feb 19, 2022
8d3de56
Continue improvements on the --check-cfg implementation
Urgau Feb 20, 2022
a556a2a
Add compiler flag `--check-cfg` to the unstable book
Urgau Feb 21, 2022
c73a2f8
properly handle fat pointers to uninhabitable types
compiler-errors Feb 23, 2022
f047af2
Normalize main return type during mono item collection & codegen
tmiasko Feb 23, 2022
37d9ea7
Improve `scan_escape`.
nnethercote Feb 24, 2022
44308dc
Inline a hot closure in `from_lit_token`.
nnethercote Feb 24, 2022
70018c1
update auto trait lint
lcnr Feb 24, 2022
34319ff
Avoid emitting full macro body into JSON
Mark-Simulacrum Feb 24, 2022
8ba7436
better ObligationCause for normalization errors in can_type_implement…
compiler-errors Feb 6, 2022
ee98dc8
restore spans for issue-50480
compiler-errors Feb 6, 2022
44de8c0
Rollup merge of #93714 - compiler-errors:can-type-impl-copy-error-spa…
Dylan-DPC Feb 24, 2022
b33098f
Rollup merge of #93845 - compiler-errors:in-band-lifetimes, r=cjgillot
Dylan-DPC Feb 24, 2022
92b5d1d
Rollup merge of #94175 - Urgau:check-cfg-improvements, r=petrochenkov
Dylan-DPC Feb 24, 2022
87f826d
Rollup merge of #94212 - scottmcm:swapper, r=dtolnay
Dylan-DPC Feb 24, 2022
2da2737
Rollup merge of #94242 - compiler-errors:fat-uninhabitable-pointer, r…
Dylan-DPC Feb 24, 2022
c20ed90
Rollup merge of #94308 - tmiasko:normalize-main-ret-ty, r=oli-obk
Dylan-DPC Feb 24, 2022
d4db2be
Rollup merge of #94315 - lcnr:auto-trait-lint-update, r=oli-obk
Dylan-DPC Feb 24, 2022
25cc094
Rollup merge of #94316 - nnethercote:improve-string-literal-unescapin…
Dylan-DPC Feb 24, 2022
39d8195
Rollup merge of #94327 - Mark-Simulacrum:avoid-macro-sp, r=petrochenkov
Dylan-DPC Feb 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add compiler flag --check-cfg to the unstable book
  • Loading branch information
Urgau committed Feb 23, 2022
commit a556a2a8e60501203f310407b27cf739618c0000
221 changes: 221 additions & 0 deletions src/doc/unstable-book/src/compiler-flags/check-cfg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
# `check-cfg`

The tracking issue for this feature is: [#82450](https://github.com/rust-lang/rust/issues/82450).

------------------------

This feature allows you to enable complete or partial checking of configuration.

`rustc` accepts the `--check-cfg` option, which specifies whether to check conditions and how to
check them. The `--check-cfg` option takes a value, called the _check cfg specification_. The
check cfg specification is parsed using the Rust metadata syntax, just as the `--cfg` option is.

`--check-cfg` option can take one of two forms:

1. `--check-cfg names(...)` enables checking condition names.
2. `--check-cfg values(...)` enables checking the values within list-valued conditions.

These two options are independent. `names` checks only the namespace of condition names
while `values` checks only the namespace of the values of list-valued conditions.

## The `names(...)` form

The `names(...)` form enables checking the names. This form uses a named list:

```bash
rustc --check-cfg 'names(name1, name2, ... nameN)'
```

where each `name` is a bare identifier (has no quotes). The order of the names is not significant.

If `--check-cfg names(...)` is specified at least once, then `rustc` will check all references to
condition names. `rustc` will check every `#[cfg]` attribute, `#[cfg_attr]` attribute, `cfg` clause
inside `#[link]` attribute and `cfg!(...)` call against the provided list of expected condition
names. If a name is not present in this list, then `rustc` will report an `unexpected_cfgs` lint
diagnostic. The default diagnostic level for this lint is `Warn`.

If `--check-cfg names(...)` is not specified, then `rustc` will not check references to condition
names.

`--check-cfg names(...)` may be specified more than once. The result is that the list of valid
condition names is merged across all options. It is legal for a condition name to be specified
more than once; redundantly specifying a condition name has no effect.

To enable checking condition names with an empty set of valid condition names, use the following
form. The parentheses are required.

```bash
rustc --check-cfg 'names()'
```

Note that `--check-cfg 'names()'` is _not_ equivalent to omitting the option entirely.
The first form enables checking condition names, while specifying that there are no valid
condition names (outside of the set of well-known names defined by `rustc`). Omitting the
`--check-cfg 'names(...)'` option does not enable checking condition names.

Conditions that are enabled are implicitly valid; it is unnecessary (but legal) to specify a
condition name as both enabled and valid. For example, the following invocations are equivalent:

```bash
# condition names will be checked, and 'has_time_travel' is valid
rustc --cfg 'has_time_travel' --check-cfg 'names()'

# condition names will be checked, and 'has_time_travel' is valid
rustc --cfg 'has_time_travel' --check-cfg 'names(has_time_travel)'
```

In contrast, the following two invocations are _not_ equivalent:

```bash
# condition names will not be checked (because there is no --check-cfg names(...))
rustc --cfg 'has_time_travel'

# condition names will be checked, and 'has_time_travel' is both valid and enabled.
rustc --cfg 'has_time_travel' --check-cfg 'names(has_time_travel)'
```

## The `values(...)` form

The `values(...)` form enables checking the values within list-valued conditions. It has this
form:

```bash
rustc --check-cfg `values(name, "value1", "value2", ... "valueN")'
```

where `name` is a bare identifier (has no quotes) and each `"value"` term is a quoted literal
string. `name` specifies the name of the condition, such as `feature` or `target_os`.

When the `values(...)` option is specified, `rustc` will check every `#[cfg(name = "value")]`
attribute, `#[cfg_attr(name = "value")]` attribute, `#[link(name = "a", cfg(name = "value"))]`
and `cfg!(name = "value")` call. It will check that the `"value"` specified is present in the
list of expected values. If `"value"` is not in it, then `rustc` will report an `unexpected_cfgs`
lint diagnostic. The default diagnostic level for this lint is `Warn`.

The form `values()` is an error, because it does not specify a condition name.

To enable checking of values, but to provide an empty set of valid values, use this form:

```bash
rustc --check-cfg `values(name)`
```

The `--check-cfg values(...)` option can be repeated, both for the same condition name and for
different names. If it is repeated for the same condition name, then the sets of values for that
condition are merged together.

## Examples

Consider this command line:

```bash
rustc --check-cfg 'names(feature)' \
--check-cfg 'values(feature,"lion","zebra")' \
--cfg 'feature="lion"' -Z unstable-options \
example.rs
```

This command line indicates that this crate has two features: `lion` and `zebra`. The `lion`
feature is enabled, while the `zebra` feature is disabled. Consider compiling this code:

```rust
// This is expected, and tame_lion() will be compiled
#[cfg(feature = "lion")]
fn tame_lion(lion: Lion) {}

// This is expected, and ride_zebra() will NOT be compiled.
#[cfg(feature = "zebra")]
fn ride_zebra(zebra: Zebra) {}

// This is UNEXPECTED, and will cause a compiler warning (by default).
#[cfg(feature = "platypus")]
fn poke_platypus() {}

// This is UNEXPECTED, because 'feechure' is not a known condition name,
// and will cause a compiler warning (by default).
#[cfg(feechure = "lion")]
fn tame_lion() {}
```

> Note: The `--check-cfg names(feature)` option is necessary only to enable checking the condition
> name, as in the last example. `feature` is a well-known (always-expected) condition name, and so
> it is not necessary to specify it in a `--check-cfg 'names(...)'` option. That option can be
> shortened to > `--check-cfg names()` in order to enable checking well-known condition names.

### Example: Checking condition names, but not values

```bash
# This turns on checking for condition names, but not values, such as 'feature' values.
rustc --check-cfg 'names(is_embedded, has_feathers)' \
--cfg has_feathers --cfg 'feature = "zapping"' -Z unstable-options
```

```rust
#[cfg(is_embedded)] // This is expected as "is_embedded" was provided in names()
fn do_embedded() {}

#[cfg(has_feathers)] // This is expected as "has_feathers" was provided in names()
fn do_features() {}

#[cfg(has_mumble_frotz)] // This is UNEXPECTED because names checking is enable and
// "has_mumble_frotz" was not provided in names()
fn do_mumble_frotz() {}

#[cfg(feature = "lasers")] // This doesn't raise a warning, because values checking for "feature"
// was never used
fn shoot_lasers() {}
```

### Example: Checking feature values, but not condition names

```bash
# This turns on checking for feature values, but not for condition names.
rustc --check-cfg 'values(feature, "zapping", "lasers")' \
--cfg 'feature="zapping"' -Z unstable-options
```

```rust
#[cfg(is_embedded)] // This is doesn't raise a warning, because names checking was not
// enable (ie not names())
fn do_embedded() {}

#[cfg(has_feathers)] // Same as above, --check-cfg names(...) was never used so no name
// checking is performed
fn do_features() {}


#[cfg(feature = "lasers")] // This is expected, "lasers" is in the values(feature) list
fn shoot_lasers() {}

#[cfg(feature = "monkeys")] // This is UNEXPECTED, because "monkeys" is not in the
// --check-cfg values(feature) list
fn write_shakespeare() {}
```

### Example: Checking both condition names and feature values

```bash
# This turns on checking for feature values and for condition names.
rustc --check-cfg 'names(is_embedded, has_feathers)' \
--check-cfg 'values(feature, "zapping", "lasers")' \
--cfg has_feathers --cfg 'feature="zapping"' -Z unstable-options
```

```rust
#[cfg(is_embedded)] // This is expected because "is_embedded" was provided in names()
fn do_embedded() {}

#[cfg(has_feathers)] // This is expected because "has_feathers" was provided in names()
fn do_features() {}

#[cfg(has_mumble_frotz)] // This is UNEXPECTED, because has_mumble_frotz is not in the
// --check-cfg names(...) list
fn do_mumble_frotz() {}

#[cfg(feature = "lasers")] // This is expected, "lasers" is in the values(feature) list
fn shoot_lasers() {}

#[cfg(feature = "monkeys")] // This is UNEXPECTED, because "monkeys" is not in
// the values(feature) list
fn write_shakespear() {}
```