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. So it becomes possible to configure some global crate properties even for fully unconfigured crates.
This commit is contained in:
parent
397641f3bd
commit
46becfdf9c
10 changed files with 63 additions and 31 deletions
|
@ -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…
Add table
Add a link
Reference in a new issue