Skip to content

Commit 2baebad

Browse files
authored
Rollup merge of #110141 - petrochenkov:cratecfg2, r=WaffleLapkin
expand: Change how `#![cfg(FALSE)]` behaves on crate root Previously it removed all other attributes from the crate root. Now it removes only attributes below itself (during both regular expansion and pre-configuration). So it becomes possible to configure some global crate properties even for fully unconfigured crates. Fixes #104633 Part of #110082
2 parents d0ee190 + 46becfd commit 2baebad

10 files changed

+63
-31
lines changed

compiler/rustc_expand/src/config.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,11 @@ pub fn pre_configure_attrs(sess: &Session, attrs: &[Attribute]) -> ast::AttrVec
197197
config_tokens: false,
198198
lint_node_id: ast::CRATE_NODE_ID,
199199
};
200-
let attrs: ast::AttrVec =
201-
attrs.iter().flat_map(|attr| strip_unconfigured.process_cfg_attr(attr)).collect();
202-
if strip_unconfigured.in_cfg(&attrs) { attrs } else { ast::AttrVec::new() }
200+
attrs
201+
.iter()
202+
.flat_map(|attr| strip_unconfigured.process_cfg_attr(attr))
203+
.take_while(|attr| !is_cfg(attr) || strip_unconfigured.cfg_true(attr).0)
204+
.collect()
203205
}
204206

205207
#[macro_export]

compiler/rustc_expand/src/expand.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -1039,7 +1039,12 @@ trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
10391039
) -> Result<Self::OutputTy, Self> {
10401040
Ok(noop_flat_map(node, collector))
10411041
}
1042-
fn expand_cfg_false(&mut self, collector: &mut InvocationCollector<'_, '_>, span: Span) {
1042+
fn expand_cfg_false(
1043+
&mut self,
1044+
collector: &mut InvocationCollector<'_, '_>,
1045+
_pos: usize,
1046+
span: Span,
1047+
) {
10431048
collector.cx.emit_err(RemoveNodeNotSupported { span, descr: Self::descr() });
10441049
}
10451050

@@ -1409,8 +1414,15 @@ impl InvocationCollectorNode for ast::Crate {
14091414
fn noop_visit<V: MutVisitor>(&mut self, visitor: &mut V) {
14101415
noop_visit_crate(self, visitor)
14111416
}
1412-
fn expand_cfg_false(&mut self, collector: &mut InvocationCollector<'_, '_>, _span: Span) {
1413-
self.attrs.clear();
1417+
fn expand_cfg_false(
1418+
&mut self,
1419+
collector: &mut InvocationCollector<'_, '_>,
1420+
pos: usize,
1421+
_span: Span,
1422+
) {
1423+
// Attributes above `cfg(FALSE)` are left in place, because we may want to configure
1424+
// some global crate properties even on fully unconfigured crates.
1425+
self.attrs.truncate(pos);
14141426
// Standard prelude imports are left in the crate for backward compatibility.
14151427
self.items.truncate(collector.cx.num_standard_library_imports);
14161428
}
@@ -1804,7 +1816,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
18041816
continue;
18051817
}
18061818

1807-
node.expand_cfg_false(self, span);
1819+
node.expand_cfg_false(self, pos, span);
18081820
continue;
18091821
}
18101822
sym::cfg_attr => {
+2-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
// It is unclear whether a fully unconfigured crate should link to standard library,
2-
// or what its `no_std`/`no_core`/`compiler_builtins` status, more precisely.
3-
// Currently the usual standard library prelude is added to such crates,
4-
// and therefore they link to libstd.
1+
// `#![no_std]` on a fully unconfigured crate is respected if it's placed before `cfg(FALSE)`.
2+
// This crate has no such attribute, therefore this crate does link to libstd.
53

64
#![cfg(FALSE)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// `#![no_std]` on a fully unconfigured crate is respected if it's placed before `cfg(FALSE)`.
2+
// Therefore this crate does link to libstd.
3+
4+
#![cfg(FALSE)]
5+
#![no_std]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// `#![no_std]` on a fully unconfigured crate is respected if it's placed before `cfg(FALSE)`.
2+
// Therefore this crate doesn't link to libstd.
3+
4+
// no-prefer-dynamic
5+
6+
#![no_std]
7+
#![crate_type = "lib"]
8+
#![cfg(FALSE)]

tests/ui/cfg/cfg-false-feature.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
// It is unclear which features should be in effect in a fully unconfigured crate (issue #104633).
2-
// Currently none on the features are in effect, so we get the feature gates reported.
1+
// Features above `cfg(FALSE)` are in effect in a fully unconfigured crate (issue #104633).
32

43
// check-pass
54
// compile-flags: --crate-type lib
@@ -8,8 +7,7 @@
87
#![cfg(FALSE)]
98
#![feature(box_syntax)]
109

11-
macro mac() {} //~ WARN `macro` is experimental
12-
//~| WARN unstable syntax can change at any point in the future
10+
macro mac() {} // OK
1311

1412
trait A = Clone; //~ WARN trait aliases are experimental
1513
//~| WARN unstable syntax can change at any point in the future

tests/ui/cfg/cfg-false-feature.stderr

+3-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
warning: trait aliases are experimental
2-
--> $DIR/cfg-false-feature.rs:14:1
2+
--> $DIR/cfg-false-feature.rs:12:1
33
|
44
LL | trait A = Clone;
55
| ^^^^^^^^^^^^^^^^
@@ -9,19 +9,8 @@ LL | trait A = Clone;
99
= warning: unstable syntax can change at any point in the future, causing a hard error!
1010
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
1111

12-
warning: `macro` is experimental
13-
--> $DIR/cfg-false-feature.rs:11:1
14-
|
15-
LL | macro mac() {}
16-
| ^^^^^^^^^^^^^^
17-
|
18-
= note: see issue #39412 <https://github.com/rust-lang/rust/issues/39412> for more information
19-
= help: add `#![feature(decl_macro)]` to the crate attributes to enable
20-
= warning: unstable syntax can change at any point in the future, causing a hard error!
21-
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
22-
2312
warning: box pattern syntax is experimental
24-
--> $DIR/cfg-false-feature.rs:18:9
13+
--> $DIR/cfg-false-feature.rs:16:9
2514
|
2615
LL | let box _ = Box::new(0);
2716
| ^^^^^
@@ -31,5 +20,5 @@ LL | let box _ = Box::new(0);
3120
= warning: unstable syntax can change at any point in the future, causing a hard error!
3221
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
3322

34-
warning: 3 warnings emitted
23+
warning: 2 warnings emitted
3524

tests/ui/cfg/cfg_false_no_std-1.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// No error, panic handler is supplied by libstd linked though the empty library.
2+
3+
// check-pass
4+
// aux-build: cfg_false_lib_no_std_after.rs
5+
6+
#![no_std]
7+
8+
extern crate cfg_false_lib_no_std_after as _;
9+
10+
fn main() {}

tests/ui/cfg/cfg_false_no_std-2.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Error, the linked empty library is `no_std` and doesn't provide a panic handler.
2+
3+
// dont-check-compiler-stderr
4+
// error-pattern: `#[panic_handler]` function required, but not found
5+
// aux-build: cfg_false_lib_no_std_before.rs
6+
7+
#![no_std]
8+
9+
extern crate cfg_false_lib_no_std_before as _;
10+
11+
fn main() {}

tests/ui/cfg/cfg_false_no_std.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
// Currently no error because the panic handler is supplied by libstd linked though the empty
2-
// library, but the desirable behavior is unclear (see comments in cfg_false_lib.rs).
1+
// No error, panic handler is supplied by libstd linked though the empty library.
32

43
// check-pass
54
// aux-build: cfg_false_lib.rs

0 commit comments

Comments
 (0)