about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-06-10 11:20:09 +0200
committerGitHub <noreply@github.com>2023-06-10 11:20:09 +0200
commit2baebad0635c061b5820ab560ccccc8f57958408 (patch)
treead8db2066f03b6183e8122f5f2679452309dbec4
parentd0ee1908ed791d3e91d2ad74ba502eaa203cff6d (diff)
parent46becfdf9c807e0108a78bb4df9b8330b10422c8 (diff)
downloadrust-2baebad0635c061b5820ab560ccccc8f57958408.tar.gz
rust-2baebad0635c061b5820ab560ccccc8f57958408.zip
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
-rw-r--r--compiler/rustc_expand/src/config.rs8
-rw-r--r--compiler/rustc_expand/src/expand.rs20
-rw-r--r--tests/ui/cfg/auxiliary/cfg_false_lib.rs6
-rw-r--r--tests/ui/cfg/auxiliary/cfg_false_lib_no_std_after.rs5
-rw-r--r--tests/ui/cfg/auxiliary/cfg_false_lib_no_std_before.rs8
-rw-r--r--tests/ui/cfg/cfg-false-feature.rs6
-rw-r--r--tests/ui/cfg/cfg-false-feature.stderr17
-rw-r--r--tests/ui/cfg/cfg_false_no_std-1.rs10
-rw-r--r--tests/ui/cfg/cfg_false_no_std-2.rs11
-rw-r--r--tests/ui/cfg/cfg_false_no_std.rs3
10 files changed, 63 insertions, 31 deletions
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index 690f80f6876..bcfa5313bde 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -197,9 +197,11 @@ pub fn pre_configure_attrs(sess: &Session, attrs: &[Attribute]) -> ast::AttrVec
         config_tokens: false,
         lint_node_id: ast::CRATE_NODE_ID,
     };
-    let attrs: ast::AttrVec =
-        attrs.iter().flat_map(|attr| strip_unconfigured.process_cfg_attr(attr)).collect();
-    if strip_unconfigured.in_cfg(&attrs) { attrs } else { ast::AttrVec::new() }
+    attrs
+        .iter()
+        .flat_map(|attr| strip_unconfigured.process_cfg_attr(attr))
+        .take_while(|attr| !is_cfg(attr) || strip_unconfigured.cfg_true(attr).0)
+        .collect()
 }
 
 #[macro_export]
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index dd8863df195..9850723a857 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -1039,7 +1039,12 @@ trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
     ) -> Result<Self::OutputTy, Self> {
         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() });
     }
 
@@ -1409,8 +1414,15 @@ impl InvocationCollectorNode for ast::Crate {
     fn noop_visit<V: MutVisitor>(&mut self, visitor: &mut V) {
         noop_visit_crate(self, visitor)
     }
-    fn expand_cfg_false(&mut self, collector: &mut InvocationCollector<'_, '_>, _span: Span) {
-        self.attrs.clear();
+    fn expand_cfg_false(
+        &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.
         self.items.truncate(collector.cx.num_standard_library_imports);
     }
@@ -1804,7 +1816,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                             continue;
                         }
 
-                        node.expand_cfg_false(self, span);
+                        node.expand_cfg_false(self, pos, span);
                         continue;
                     }
                     sym::cfg_attr => {
diff --git a/tests/ui/cfg/auxiliary/cfg_false_lib.rs b/tests/ui/cfg/auxiliary/cfg_false_lib.rs
index 3c011d72b02..6c2dbb44d2a 100644
--- a/tests/ui/cfg/auxiliary/cfg_false_lib.rs
+++ b/tests/ui/cfg/auxiliary/cfg_false_lib.rs
@@ -1,6 +1,4 @@
-// It is unclear whether a fully unconfigured crate should link to standard library,
-// or what its `no_std`/`no_core`/`compiler_builtins` status, more precisely.
-// Currently the usual standard library prelude is added to such crates,
-// and therefore they link to libstd.
+// `#![no_std]` on a fully unconfigured crate is respected if it's placed before `cfg(FALSE)`.
+// This crate has no such attribute, therefore this crate does link to libstd.
 
 #![cfg(FALSE)]
diff --git a/tests/ui/cfg/auxiliary/cfg_false_lib_no_std_after.rs b/tests/ui/cfg/auxiliary/cfg_false_lib_no_std_after.rs
new file mode 100644
index 00000000000..3cfa6c510d0
--- /dev/null
+++ b/tests/ui/cfg/auxiliary/cfg_false_lib_no_std_after.rs
@@ -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]
diff --git a/tests/ui/cfg/auxiliary/cfg_false_lib_no_std_before.rs b/tests/ui/cfg/auxiliary/cfg_false_lib_no_std_before.rs
new file mode 100644
index 00000000000..8e89545b8f4
--- /dev/null
+++ b/tests/ui/cfg/auxiliary/cfg_false_lib_no_std_before.rs
@@ -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)]
diff --git a/tests/ui/cfg/cfg-false-feature.rs b/tests/ui/cfg/cfg-false-feature.rs
index 21ea3ec79b4..84c231562f1 100644
--- a/tests/ui/cfg/cfg-false-feature.rs
+++ b/tests/ui/cfg/cfg-false-feature.rs
@@ -1,5 +1,4 @@
-// It is unclear which features should be in effect in a fully unconfigured crate (issue #104633).
-// Currently none on the features are in effect, so we get the feature gates reported.
+// Features above `cfg(FALSE)` are in effect in a fully unconfigured crate (issue #104633).
 
 // check-pass
 // compile-flags: --crate-type lib
@@ -8,8 +7,7 @@
 #![cfg(FALSE)]
 #![feature(box_syntax)]
 
-macro mac() {} //~ WARN `macro` is experimental
-               //~| WARN unstable syntax can change at any point in the future
+macro mac() {} // OK
 
 trait A = Clone; //~ WARN trait aliases are experimental
                  //~| WARN unstable syntax can change at any point in the future
diff --git a/tests/ui/cfg/cfg-false-feature.stderr b/tests/ui/cfg/cfg-false-feature.stderr
index 14673fbdb14..34093036205 100644
--- a/tests/ui/cfg/cfg-false-feature.stderr
+++ b/tests/ui/cfg/cfg-false-feature.stderr
@@ -1,5 +1,5 @@
 warning: trait aliases are experimental
-  --> $DIR/cfg-false-feature.rs:14:1
+  --> $DIR/cfg-false-feature.rs:12:1
    |
 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!
    = 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
-  --> $DIR/cfg-false-feature.rs:18:9
+  --> $DIR/cfg-false-feature.rs:16:9
    |
 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!
    = note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
 
-warning: 3 warnings emitted
+warning: 2 warnings emitted
 
diff --git a/tests/ui/cfg/cfg_false_no_std-1.rs b/tests/ui/cfg/cfg_false_no_std-1.rs
new file mode 100644
index 00000000000..bcb49e51353
--- /dev/null
+++ b/tests/ui/cfg/cfg_false_no_std-1.rs
@@ -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() {}
diff --git a/tests/ui/cfg/cfg_false_no_std-2.rs b/tests/ui/cfg/cfg_false_no_std-2.rs
new file mode 100644
index 00000000000..0a2bfd5f68b
--- /dev/null
+++ b/tests/ui/cfg/cfg_false_no_std-2.rs
@@ -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() {}
diff --git a/tests/ui/cfg/cfg_false_no_std.rs b/tests/ui/cfg/cfg_false_no_std.rs
index 319ea078187..4fa831715ed 100644
--- a/tests/ui/cfg/cfg_false_no_std.rs
+++ b/tests/ui/cfg/cfg_false_no_std.rs
@@ -1,5 +1,4 @@
-// Currently no error because the panic handler is supplied by libstd linked though the empty
-// library, but the desirable behavior is unclear (see comments in cfg_false_lib.rs).
+// No error, panic handler is supplied by libstd linked though the empty library.
 
 // check-pass
 // aux-build: cfg_false_lib.rs