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 https://github.com/rust-lang/rust/issues/104633 Part of https://github.com/rust-lang/rust/issues/110082
This commit is contained in:
commit
2baebad063
@ -197,9 +197,11 @@ pub fn pre_configure_attrs(sess: &Session, attrs: &[Attribute]) -> ast::AttrVec
|
|||||||
config_tokens: false,
|
config_tokens: false,
|
||||||
lint_node_id: ast::CRATE_NODE_ID,
|
lint_node_id: ast::CRATE_NODE_ID,
|
||||||
};
|
};
|
||||||
let attrs: ast::AttrVec =
|
attrs
|
||||||
attrs.iter().flat_map(|attr| strip_unconfigured.process_cfg_attr(attr)).collect();
|
.iter()
|
||||||
if strip_unconfigured.in_cfg(&attrs) { attrs } else { ast::AttrVec::new() }
|
.flat_map(|attr| strip_unconfigured.process_cfg_attr(attr))
|
||||||
|
.take_while(|attr| !is_cfg(attr) || strip_unconfigured.cfg_true(attr).0)
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
@ -1039,7 +1039,12 @@ trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
|
|||||||
) -> Result<Self::OutputTy, Self> {
|
) -> Result<Self::OutputTy, Self> {
|
||||||
Ok(noop_flat_map(node, collector))
|
Ok(noop_flat_map(node, collector))
|
||||||
}
|
}
|
||||||
fn expand_cfg_false(&mut self, collector: &mut InvocationCollector<'_, '_>, span: Span) {
|
fn expand_cfg_false(
|
||||||
|
&mut self,
|
||||||
|
collector: &mut InvocationCollector<'_, '_>,
|
||||||
|
_pos: usize,
|
||||||
|
span: Span,
|
||||||
|
) {
|
||||||
collector.cx.emit_err(RemoveNodeNotSupported { span, descr: Self::descr() });
|
collector.cx.emit_err(RemoveNodeNotSupported { span, descr: Self::descr() });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1409,8 +1414,15 @@ impl InvocationCollectorNode for ast::Crate {
|
|||||||
fn noop_visit<V: MutVisitor>(&mut self, visitor: &mut V) {
|
fn noop_visit<V: MutVisitor>(&mut self, visitor: &mut V) {
|
||||||
noop_visit_crate(self, visitor)
|
noop_visit_crate(self, visitor)
|
||||||
}
|
}
|
||||||
fn expand_cfg_false(&mut self, collector: &mut InvocationCollector<'_, '_>, _span: Span) {
|
fn expand_cfg_false(
|
||||||
self.attrs.clear();
|
&mut self,
|
||||||
|
collector: &mut InvocationCollector<'_, '_>,
|
||||||
|
pos: usize,
|
||||||
|
_span: Span,
|
||||||
|
) {
|
||||||
|
// Attributes above `cfg(FALSE)` are left in place, because we may want to configure
|
||||||
|
// some global crate properties even on fully unconfigured crates.
|
||||||
|
self.attrs.truncate(pos);
|
||||||
// Standard prelude imports are left in the crate for backward compatibility.
|
// Standard prelude imports are left in the crate for backward compatibility.
|
||||||
self.items.truncate(collector.cx.num_standard_library_imports);
|
self.items.truncate(collector.cx.num_standard_library_imports);
|
||||||
}
|
}
|
||||||
@ -1804,7 +1816,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
node.expand_cfg_false(self, span);
|
node.expand_cfg_false(self, pos, span);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
sym::cfg_attr => {
|
sym::cfg_attr => {
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
// It is unclear whether a fully unconfigured crate should link to standard library,
|
// `#![no_std]` on a fully unconfigured crate is respected if it's placed before `cfg(FALSE)`.
|
||||||
// or what its `no_std`/`no_core`/`compiler_builtins` status, more precisely.
|
// This crate has no such attribute, therefore this crate does link to libstd.
|
||||||
// Currently the usual standard library prelude is added to such crates,
|
|
||||||
// and therefore they link to libstd.
|
|
||||||
|
|
||||||
#![cfg(FALSE)]
|
#![cfg(FALSE)]
|
||||||
|
5
tests/ui/cfg/auxiliary/cfg_false_lib_no_std_after.rs
Normal file
5
tests/ui/cfg/auxiliary/cfg_false_lib_no_std_after.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// `#![no_std]` on a fully unconfigured crate is respected if it's placed before `cfg(FALSE)`.
|
||||||
|
// Therefore this crate does link to libstd.
|
||||||
|
|
||||||
|
#![cfg(FALSE)]
|
||||||
|
#![no_std]
|
8
tests/ui/cfg/auxiliary/cfg_false_lib_no_std_before.rs
Normal file
8
tests/ui/cfg/auxiliary/cfg_false_lib_no_std_before.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// `#![no_std]` on a fully unconfigured crate is respected if it's placed before `cfg(FALSE)`.
|
||||||
|
// Therefore this crate doesn't link to libstd.
|
||||||
|
|
||||||
|
// no-prefer-dynamic
|
||||||
|
|
||||||
|
#![no_std]
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
#![cfg(FALSE)]
|
@ -1,5 +1,4 @@
|
|||||||
// It is unclear which features should be in effect in a fully unconfigured crate (issue #104633).
|
// Features above `cfg(FALSE)` are in effect in a fully unconfigured crate (issue #104633).
|
||||||
// Currently none on the features are in effect, so we get the feature gates reported.
|
|
||||||
|
|
||||||
// check-pass
|
// check-pass
|
||||||
// compile-flags: --crate-type lib
|
// compile-flags: --crate-type lib
|
||||||
@ -8,8 +7,7 @@
|
|||||||
#![cfg(FALSE)]
|
#![cfg(FALSE)]
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
|
|
||||||
macro mac() {} //~ WARN `macro` is experimental
|
macro mac() {} // OK
|
||||||
//~| WARN unstable syntax can change at any point in the future
|
|
||||||
|
|
||||||
trait A = Clone; //~ WARN trait aliases are experimental
|
trait A = Clone; //~ WARN trait aliases are experimental
|
||||||
//~| WARN unstable syntax can change at any point in the future
|
//~| WARN unstable syntax can change at any point in the future
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
warning: trait aliases are experimental
|
warning: trait aliases are experimental
|
||||||
--> $DIR/cfg-false-feature.rs:14:1
|
--> $DIR/cfg-false-feature.rs:12:1
|
||||||
|
|
|
|
||||||
LL | trait A = Clone;
|
LL | trait A = Clone;
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
@ -9,19 +9,8 @@ LL | trait A = Clone;
|
|||||||
= warning: unstable syntax can change at any point in the future, causing a hard error!
|
= warning: unstable syntax can change at any point in the future, causing a hard error!
|
||||||
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
|
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
|
||||||
|
|
||||||
warning: `macro` is experimental
|
|
||||||
--> $DIR/cfg-false-feature.rs:11:1
|
|
||||||
|
|
|
||||||
LL | macro mac() {}
|
|
||||||
| ^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #39412 <https://github.com/rust-lang/rust/issues/39412> for more information
|
|
||||||
= help: add `#![feature(decl_macro)]` to the crate attributes to enable
|
|
||||||
= warning: unstable syntax can change at any point in the future, causing a hard error!
|
|
||||||
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
|
|
||||||
|
|
||||||
warning: box pattern syntax is experimental
|
warning: box pattern syntax is experimental
|
||||||
--> $DIR/cfg-false-feature.rs:18:9
|
--> $DIR/cfg-false-feature.rs:16:9
|
||||||
|
|
|
|
||||||
LL | let box _ = Box::new(0);
|
LL | let box _ = Box::new(0);
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
@ -31,5 +20,5 @@ LL | let box _ = Box::new(0);
|
|||||||
= warning: unstable syntax can change at any point in the future, causing a hard error!
|
= warning: unstable syntax can change at any point in the future, causing a hard error!
|
||||||
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
|
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
|
||||||
|
|
||||||
warning: 3 warnings emitted
|
warning: 2 warnings emitted
|
||||||
|
|
||||||
|
10
tests/ui/cfg/cfg_false_no_std-1.rs
Normal file
10
tests/ui/cfg/cfg_false_no_std-1.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// No error, panic handler is supplied by libstd linked though the empty library.
|
||||||
|
|
||||||
|
// check-pass
|
||||||
|
// aux-build: cfg_false_lib_no_std_after.rs
|
||||||
|
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
extern crate cfg_false_lib_no_std_after as _;
|
||||||
|
|
||||||
|
fn main() {}
|
11
tests/ui/cfg/cfg_false_no_std-2.rs
Normal file
11
tests/ui/cfg/cfg_false_no_std-2.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Error, the linked empty library is `no_std` and doesn't provide a panic handler.
|
||||||
|
|
||||||
|
// dont-check-compiler-stderr
|
||||||
|
// error-pattern: `#[panic_handler]` function required, but not found
|
||||||
|
// aux-build: cfg_false_lib_no_std_before.rs
|
||||||
|
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
extern crate cfg_false_lib_no_std_before as _;
|
||||||
|
|
||||||
|
fn main() {}
|
@ -1,5 +1,4 @@
|
|||||||
// Currently no error because the panic handler is supplied by libstd linked though the empty
|
// No error, panic handler is supplied by libstd linked though the empty library.
|
||||||
// library, but the desirable behavior is unclear (see comments in cfg_false_lib.rs).
|
|
||||||
|
|
||||||
// check-pass
|
// check-pass
|
||||||
// aux-build: cfg_false_lib.rs
|
// aux-build: cfg_false_lib.rs
|
||||||
|
Loading…
x
Reference in New Issue
Block a user