about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-11-07 04:03:52 +0000
committerbors <bors@rust-lang.org>2023-11-07 04:03:52 +0000
commitefc300e5460fd1ed057b882e9e29adfdd217eeef (patch)
tree24a985826adbb561066d301f0901eba29cb15adc
parent489647f984b2b3a5ee6b2a0d46a527c8d926ceae (diff)
parentefb81ca657b98ca2eb533d603e746a4954db2cac (diff)
downloadrust-efc300e5460fd1ed057b882e9e29adfdd217eeef.tar.gz
rust-efc300e5460fd1ed057b882e9e29adfdd217eeef.zip
Auto merge of #117644 - cuviper:beta-next, r=cuviper
[beta] backports

- ensure the parent path's existence on `x install` #116349
- Remove `cfg_match` from the prelude #117162
- improve and fix `x install` #117383
- Update to LLVM 17.0.4 #117436

r? cuviper
-rw-r--r--library/core/src/lib.rs3
-rw-r--r--library/core/src/macros/mod.rs177
-rw-r--r--src/bootstrap/install.rs58
m---------src/llvm-project0
4 files changed, 124 insertions, 114 deletions
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 3092c467a4a..8b15e8269da 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -290,6 +290,9 @@ pub mod assert_matches {
     pub use crate::macros::{assert_matches, debug_assert_matches};
 }
 
+#[unstable(feature = "cfg_match", issue = "115585")]
+pub use crate::macros::cfg_match;
+
 #[macro_use]
 mod internal_macros;
 
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index c27be8d2ffd..123661b3588 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -168,6 +168,94 @@ pub macro assert_matches {
     },
 }
 
+/// A macro for defining `#[cfg]` match-like statements.
+///
+/// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of
+/// `#[cfg]` cases, emitting the implementation which matches first.
+///
+/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
+/// without having to rewrite each clause multiple times.
+///
+/// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when
+/// all previous declarations do not evaluate to true.
+///
+/// # Example
+///
+/// ```
+/// #![feature(cfg_match)]
+///
+/// cfg_match! {
+///     cfg(unix) => {
+///         fn foo() { /* unix specific functionality */ }
+///     }
+///     cfg(target_pointer_width = "32") => {
+///         fn foo() { /* non-unix, 32-bit functionality */ }
+///     }
+///     _ => {
+///         fn foo() { /* fallback implementation */ }
+///     }
+/// }
+/// ```
+#[unstable(feature = "cfg_match", issue = "115585")]
+#[rustc_diagnostic_item = "cfg_match"]
+pub macro cfg_match {
+    // with a final wildcard
+    (
+        $(cfg($initial_meta:meta) => { $($initial_tokens:item)* })+
+        _ => { $($extra_tokens:item)* }
+    ) => {
+        cfg_match! {
+            @__items ();
+            $((($initial_meta) ($($initial_tokens)*)),)+
+            (() ($($extra_tokens)*)),
+        }
+    },
+
+    // without a final wildcard
+    (
+        $(cfg($extra_meta:meta) => { $($extra_tokens:item)* })*
+    ) => {
+        cfg_match! {
+            @__items ();
+            $((($extra_meta) ($($extra_tokens)*)),)*
+        }
+    },
+
+    // Internal and recursive macro to emit all the items
+    //
+    // Collects all the previous cfgs in a list at the beginning, so they can be
+    // negated. After the semicolon is all the remaining items.
+    (@__items ($($_:meta,)*);) => {},
+    (
+        @__items ($($no:meta,)*);
+        (($($yes:meta)?) ($($tokens:item)*)),
+        $($rest:tt,)*
+    ) => {
+        // Emit all items within one block, applying an appropriate #[cfg]. The
+        // #[cfg] will require all `$yes` matchers specified and must also negate
+        // all previous matchers.
+        #[cfg(all(
+            $($yes,)?
+            not(any($($no),*))
+        ))]
+        cfg_match! { @__identity $($tokens)* }
+
+        // Recurse to emit all other items in `$rest`, and when we do so add all
+        // our `$yes` matchers to the list of `$no` matchers as future emissions
+        // will have to negate everything we just matched as well.
+        cfg_match! {
+            @__items ($($no,)* $($yes,)?);
+            $($rest,)*
+        }
+    },
+
+    // Internal macro to make __apply work out right for different match types,
+    // because of how macros match/expand stuff.
+    (@__identity $($tokens:item)*) => {
+        $($tokens)*
+    }
+}
+
 /// Asserts that a boolean expression is `true` at runtime.
 ///
 /// This will invoke the [`panic!`] macro if the provided expression cannot be
@@ -321,95 +409,6 @@ pub macro debug_assert_matches($($arg:tt)*) {
     }
 }
 
-/// A macro for defining `#[cfg]` match-like statements.
-///
-/// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of
-/// `#[cfg]` cases, emitting the implementation which matches first.
-///
-/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
-/// without having to rewrite each clause multiple times.
-///
-/// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when
-/// all previous declarations do not evaluate to true.
-///
-/// # Example
-///
-/// ```
-/// #![feature(cfg_match)]
-///
-/// cfg_match! {
-///     cfg(unix) => {
-///         fn foo() { /* unix specific functionality */ }
-///     }
-///     cfg(target_pointer_width = "32") => {
-///         fn foo() { /* non-unix, 32-bit functionality */ }
-///     }
-///     _ => {
-///         fn foo() { /* fallback implementation */ }
-///     }
-/// }
-/// ```
-#[macro_export]
-#[unstable(feature = "cfg_match", issue = "115585")]
-#[rustc_diagnostic_item = "cfg_match"]
-macro_rules! cfg_match {
-    // with a final wildcard
-    (
-        $(cfg($initial_meta:meta) => { $($initial_tokens:item)* })+
-        _ => { $($extra_tokens:item)* }
-    ) => {
-        cfg_match! {
-            @__items ();
-            $((($initial_meta) ($($initial_tokens)*)),)+
-            (() ($($extra_tokens)*)),
-        }
-    };
-
-    // without a final wildcard
-    (
-        $(cfg($extra_meta:meta) => { $($extra_tokens:item)* })*
-    ) => {
-        cfg_match! {
-            @__items ();
-            $((($extra_meta) ($($extra_tokens)*)),)*
-        }
-    };
-
-    // Internal and recursive macro to emit all the items
-    //
-    // Collects all the previous cfgs in a list at the beginning, so they can be
-    // negated. After the semicolon is all the remaining items.
-    (@__items ($($_:meta,)*);) => {};
-    (
-        @__items ($($no:meta,)*);
-        (($($yes:meta)?) ($($tokens:item)*)),
-        $($rest:tt,)*
-    ) => {
-        // Emit all items within one block, applying an appropriate #[cfg]. The
-        // #[cfg] will require all `$yes` matchers specified and must also negate
-        // all previous matchers.
-        #[cfg(all(
-            $($yes,)?
-            not(any($($no),*))
-        ))]
-        cfg_match! { @__identity $($tokens)* }
-
-        // Recurse to emit all other items in `$rest`, and when we do so add all
-        // our `$yes` matchers to the list of `$no` matchers as future emissions
-        // will have to negate everything we just matched as well.
-        cfg_match! {
-            @__items ($($no,)* $($yes,)?);
-            $($rest,)*
-        }
-    };
-
-    // Internal macro to make __apply work out right for different match types,
-    // because of how macros match/expand stuff.
-    (@__identity $($tokens:item)*) => {
-        $($tokens)*
-    };
-}
-
 /// Returns whether the given expression matches any of the given patterns.
 ///
 /// Like in a `match` expression, the pattern can be optionally followed by `if`
diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs
index 85cd8abb995..500b20b8642 100644
--- a/src/bootstrap/install.rs
+++ b/src/bootstrap/install.rs
@@ -46,10 +46,10 @@ fn sanitize_sh(path: &Path) -> String {
 }
 
 fn is_dir_writable_for_user(dir: &PathBuf) -> bool {
-    let tmp_file = dir.join(".tmp");
-    match fs::File::create(&tmp_file) {
+    let tmp = dir.join(".tmp");
+    match fs::create_dir_all(&tmp) {
         Ok(_) => {
-            fs::remove_file(tmp_file).unwrap();
+            fs::remove_dir_all(tmp).unwrap();
             true
         }
         Err(e) => {
@@ -73,16 +73,27 @@ fn install_sh(
 
     let prefix = default_path(&builder.config.prefix, "/usr/local");
     let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc"));
+    let destdir_env = env::var_os("DESTDIR").map(PathBuf::from);
 
-    // Sanity check for the user write access on prefix and sysconfdir
-    assert!(
-        is_dir_writable_for_user(&prefix),
-        "User doesn't have write access on `install.prefix` path in the `config.toml`.",
-    );
-    assert!(
-        is_dir_writable_for_user(&sysconfdir),
-        "User doesn't have write access on `install.sysconfdir` path in `config.toml`."
-    );
+    // Sanity checks on the write access of user.
+    //
+    // When the `DESTDIR` environment variable is present, there is no point to
+    // check write access for `prefix` and `sysconfdir` individually, as they
+    // are combined with the path from the `DESTDIR` environment variable. In
+    // this case, we only need to check the `DESTDIR` path, disregarding the
+    // `prefix` and `sysconfdir` paths.
+    if let Some(destdir) = &destdir_env {
+        assert!(is_dir_writable_for_user(destdir), "User doesn't have write access on DESTDIR.");
+    } else {
+        assert!(
+            is_dir_writable_for_user(&prefix),
+            "User doesn't have write access on `install.prefix` path in the `config.toml`.",
+        );
+        assert!(
+            is_dir_writable_for_user(&sysconfdir),
+            "User doesn't have write access on `install.sysconfdir` path in `config.toml`."
+        );
+    }
 
     let datadir = prefix.join(default_path(&builder.config.datadir, "share"));
     let docdir = prefix.join(default_path(&builder.config.docdir, "share/doc/rust"));
@@ -96,13 +107,13 @@ fn install_sh(
     let mut cmd = Command::new(SHELL);
     cmd.current_dir(&empty_dir)
         .arg(sanitize_sh(&tarball.decompressed_output().join("install.sh")))
-        .arg(format!("--prefix={}", prepare_dir(prefix)))
-        .arg(format!("--sysconfdir={}", prepare_dir(sysconfdir)))
-        .arg(format!("--datadir={}", prepare_dir(datadir)))
-        .arg(format!("--docdir={}", prepare_dir(docdir)))
-        .arg(format!("--bindir={}", prepare_dir(bindir)))
-        .arg(format!("--libdir={}", prepare_dir(libdir)))
-        .arg(format!("--mandir={}", prepare_dir(mandir)))
+        .arg(format!("--prefix={}", prepare_dir(&destdir_env, prefix)))
+        .arg(format!("--sysconfdir={}", prepare_dir(&destdir_env, sysconfdir)))
+        .arg(format!("--datadir={}", prepare_dir(&destdir_env, datadir)))
+        .arg(format!("--docdir={}", prepare_dir(&destdir_env, docdir)))
+        .arg(format!("--bindir={}", prepare_dir(&destdir_env, bindir)))
+        .arg(format!("--libdir={}", prepare_dir(&destdir_env, libdir)))
+        .arg(format!("--mandir={}", prepare_dir(&destdir_env, mandir)))
         .arg("--disable-ldconfig");
     builder.run(&mut cmd);
     t!(fs::remove_dir_all(&empty_dir));
@@ -112,19 +123,16 @@ fn default_path(config: &Option<PathBuf>, default: &str) -> PathBuf {
     config.as_ref().cloned().unwrap_or_else(|| PathBuf::from(default))
 }
 
-fn prepare_dir(mut path: PathBuf) -> String {
+fn prepare_dir(destdir_env: &Option<PathBuf>, mut path: PathBuf) -> String {
     // The DESTDIR environment variable is a standard way to install software in a subdirectory
     // while keeping the original directory structure, even if the prefix or other directories
     // contain absolute paths.
     //
     // More information on the environment variable is available here:
     // https://www.gnu.org/prep/standards/html_node/DESTDIR.html
-    if let Some(destdir) = env::var_os("DESTDIR").map(PathBuf::from) {
-        // Sanity check for the user write access on DESTDIR
-        assert!(is_dir_writable_for_user(&destdir), "User doesn't have write access on DESTDIR.");
-
+    if let Some(destdir) = destdir_env {
         let without_destdir = path.clone();
-        path = destdir;
+        path = destdir.clone();
         // Custom .join() which ignores disk roots.
         for part in without_destdir.components() {
             if let Component::Normal(s) = part {
diff --git a/src/llvm-project b/src/llvm-project
-Subproject febc39711a7c91560eb0f0980916ae23c343b99
+Subproject fef3d7b14ede45d051dc688aae0bb8c8b02a056