Description
Proposal
This proposal is a spawned of work started in this PR. Current documentation for check-cfg can be found in the unstable book.
Old proposal
This proposal wants to adds a new simpler and more explicit syntax for check-cfg. It would consist of two new form [detailed doc]:
--check-cfg exhaustive(...)
enables some exhaustive checking--check-cfg configure(...)
enables checking the values within list-valued conditions.
The exhaustive(...)
form
The exhaustive(...)
form tell the compiler if it should be exhaustive about it's checking.
It currently has two exhaustiveness:
names
: permist the compiler to check every config name by adding it's list of well-known namesvalues
: permist the compiler to check it's well-known cfg values by adding it's list of well-known values
The configure(...)
form
The configure(...)
form enables checking the values within list-valued conditions. It has this form:
rustc --check-cfg `configure(name1, ..., nameN, "value1", "value2", ... "valueN")'
To enable checking of values, but to provide an empty set of valid values, use this form:
rustc --check-cfg `configure(name1, ..., nameN)`
The --check-cfg configure(...)
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.
Why?
The preview forms names(...)
and values(...)
have implicit meaning that are not strait-forward. In particular values(foo)
&values(bar)
and names(foo, bar)
are not equivalent which has created some confusions.
Also the names()
and values()
form are not clear either and again created some confusions where peoples believed that values()
&values(foo)
could be reduced to just values(foo)
.
To fix that the two new forms are made to be explicit and simpler. See the table of correspondence:
names()
->exhaustive(names)
values()
->exhaustive(values)
names(foo)
->exhaustive(names)
&configure(foo)
values(foo)
->configure(foo)
values(feat, "foo", "bar")
->configure(feat, "foo", "bar")
values(foo)
&values(bar)
->configure(foo, bar)
names()
&values()
&values(my_cfg)
->exhaustive(names, values)
&configure(my_cfg)
The two previous forms would be deprecated and will would be removed once cargo and beta rustc have the necessary support.
Open questions
-
Naming of
configure
(comment):--check-cfg configure(...)
also sounds tautological,cfg
already means "configure",values
was a better name for this semantic, IMO.Could be kept as
values(...)
without too much difficulties, having a different name seemed clearer that it was different. -
Naming of
exhaustive
:
Too different fromnames
to re-use the same name.
This proposal is based on the previous proposal above and the summary work done by @wesleywiser in https://hackmd.io/@wesleywiser/rJlumbfep.
This MCP proposes to:
- remove the
names()
andvalues()
form of--check-cfg
(with at least one release of deprecation) - replace those two forms by new unified form one called
cfg()
(to remove most of un-intuitiveness of the previous syntax)
The cfg(...)
form
The cfg(...)
form enables checking the values within list-valued conditions. It has this form:
rustc --check-cfg 'cfg(name1, ..., nameN, values("value1", "value2", ... "valueN"))'
To enable checking of values, but to provide an empty set of expected values, use these forms:
rustc --check-cfg 'cfg(name1, ..., nameN)'
rustc --check-cfg 'cfg(name1, ..., nameN, values())'
To enable checking of name but not values (i.e. unknown expected values), use this form:
rustc --check-cfg 'cfg(name1, ..., nameN, values(any()))'
To disable checking of name, use this form:
rustc --check-cfg 'cfg(any())'
The --check-cfg cfg(...)
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.
Built-in names and values
- Built-in values checking would always be activated as long as a
--check-cfg
argument is present - Built-in names checking would always be activated as long as a
--check-cfg
argument is present unless if anycfg(any())
arg is passed - If one want to enable values and names checking without having any cfg to declare, one can use an empty
cfg()
Why?
The preview forms names(...)
and values(...)
have implicit meaning that are not strait-forward. In particular values(foo)
&values(bar)
and names(foo, bar)
are not equivalent which has created some confusions.
Also the names()
and values()
form are not clear either and again created some confusions where peoples believed that values()
&values(foo)
could be reduced to just values(foo)
.
To fix that the two new forms are made to be explicit and simpler. See the table of correspondence:
names()
-> enable-by-default by any use of--check-cfg
useless givencfg(any())
values()
-> enable-by-default by any use of--check-cfg
names(foo)
->cfg(foo, any())
values(foo)
->cfg(foo)
values(feat, "foo", "bar")
->cfg(feat, values("foo", "bar"))
values(foo)
&values(bar)
->cfg(foo, bar)
names()
&values()
&values(my_cfg)
->cfg(my_cfg)
The two previous forms would be deprecated and will would be removed once cargo and beta rustc have the necessary support.
Open questions
-
Naming of
cfg
form (comment):--check=cfg(...)
. I had this thought as well but was struggling to think of other things it could be extended to. It also seemed like users might thinkrustc --check ...
is equivalent tocargo check
. Need to think about this more...rustdoc
already has a--check
argument making--check=cfg(...)
impossible
Mentors or Reviewers
@petrochenkov for reviewing and my-self for the implementation work
Process
The main points of the Major Change Process are as follows:
- File an issue describing the proposal.
- A compiler team member or contributor who is knowledgeable in the area can second by writing
@rustbot second
.- Finding a "second" suffices for internal changes. If however, you are proposing a new public-facing feature, such as a
-C flag
, then full team check-off is required. - Compiler team members can initiate a check-off via
@rfcbot fcp merge
on either the MCP or the PR.
- Finding a "second" suffices for internal changes. If however, you are proposing a new public-facing feature, such as a
- Once an MCP is seconded, the Final Comment Period begins. If no objections are raised after 10 days, the MCP is considered approved.
You can read more about Major Change Proposals on forge.
Comments
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.