about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-02-16 21:23:25 +0000
committerbors <bors@rust-lang.org>2025-02-16 21:23:25 +0000
commitd1fb81e8dd5354ddf7cb334d5a234cab7f64b3bb (patch)
tree80e2993f00d5200299e7d2da384f6b8e0ae67b76 /src
parent5bc62314547c7639484481f62f218156697cfef0 (diff)
parente802a8cc015436382fc8b125dddc56016fe5e490 (diff)
downloadrust-d1fb81e8dd5354ddf7cb334d5a234cab7f64b3bb.tar.gz
rust-d1fb81e8dd5354ddf7cb334d5a234cab7f64b3bb.zip
Auto merge of #137143 - matthiaskrgr:rollup-9hapmyd, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #136986 (Apply unsafe_op_in_unsafe_fn to the standard library)
 - #137012 (add docs and ut for bootstrap util cc-detect)
 - #137072 (Load all builtin targets at once instead of one by one in check-cfg)
 - #137102 (Rework `name_regions` to not rely on reverse scc graph for non-member-constrain usages)
 - #137112 (Don't project into `NonNull` when dropping a `Box`)
 - #137114 (Add an example for `std::error::Error`)
 - #137117 (Fix test that relies on error language)
 - #137119 (fix broken `x {doc, build} core`)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/doc.rs5
-rw-r--r--src/bootstrap/src/core/builder/mod.rs12
-rw-r--r--src/bootstrap/src/utils/cc_detect.rs34
-rw-r--r--src/bootstrap/src/utils/cc_detect/tests.rs254
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort1.rs2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort2.rs2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort3.rs2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort4.rs2
9 files changed, 299 insertions, 16 deletions
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 479327d6369..84cf99b5540 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -95,7 +95,7 @@ impl Step for Std {
     const DEFAULT: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.crate_or_deps("sysroot").path("library").alias("core")
+        run.crate_or_deps("sysroot").path("library")
     }
 
     fn make_run(run: RunConfig<'_>) {
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index dedcc139ae1..23bb47dcc58 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -572,10 +572,7 @@ impl Step for Std {
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
         let builder = run.builder;
-        run.crate_or_deps("sysroot")
-            .path("library")
-            .alias("core")
-            .default_condition(builder.config.docs)
+        run.crate_or_deps("sysroot").path("library").default_condition(builder.config.docs)
     }
 
     fn make_run(run: RunConfig<'_>) {
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index ecec589fc32..52876c3fb3f 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -127,10 +127,14 @@ impl RunConfig<'_> {
     pub fn cargo_crates_in_set(&self) -> Vec<String> {
         let mut crates = Vec::new();
         for krate in &self.paths {
-            let path = krate.assert_single_path();
-            let Some(crate_name) = self.builder.crate_paths.get(&path.path) else {
-                panic!("missing crate for path {}", path.path.display())
-            };
+            let path = &krate.assert_single_path().path;
+
+            let crate_name = self
+                .builder
+                .crate_paths
+                .get(path)
+                .unwrap_or_else(|| panic!("missing crate for path {}", path.display()));
+
             crates.push(crate_name.to_string());
         }
         crates
diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs
index 45797c1276c..1e84a7deff1 100644
--- a/src/bootstrap/src/utils/cc_detect.rs
+++ b/src/bootstrap/src/utils/cc_detect.rs
@@ -29,6 +29,7 @@ use crate::core::config::TargetSelection;
 use crate::utils::exec::{BootstrapCommand, command};
 use crate::{Build, CLang, GitRepo};
 
+/// Finds archiver tool for the given target if possible.
 /// FIXME(onur-ozkan): This logic should be replaced by calling into the `cc` crate.
 fn cc2ar(cc: &Path, target: TargetSelection, default_ar: PathBuf) -> Option<PathBuf> {
     if let Some(ar) = env::var_os(format!("AR_{}", target.triple.replace('-', "_"))) {
@@ -58,6 +59,7 @@ fn cc2ar(cc: &Path, target: TargetSelection, default_ar: PathBuf) -> Option<Path
     }
 }
 
+/// Creates and configures a new [`cc::Build`] instance for the given target.
 fn new_cc_build(build: &Build, target: TargetSelection) -> cc::Build {
     let mut cfg = cc::Build::new();
     cfg.cargo_metadata(false)
@@ -84,6 +86,12 @@ fn new_cc_build(build: &Build, target: TargetSelection) -> cc::Build {
     cfg
 }
 
+/// Probes for C and C++ compilers and configures the corresponding entries in the [`Build`]
+/// structure.
+///
+/// This function determines which targets need a C compiler (and, if needed, a C++ compiler)
+/// by combining the primary build target, host targets, and any additional targets. For
+/// each target, it calls [`find_target`] to configure the necessary compiler tools.
 pub fn find(build: &Build) {
     let targets: HashSet<_> = match build.config.cmd {
         // We don't need to check cross targets for these commands.
@@ -112,6 +120,11 @@ pub fn find(build: &Build) {
     }
 }
 
+/// Probes and configures the C and C++ compilers for a single target.
+///
+/// This function uses both user-specified configuration (from `config.toml`) and auto-detection
+/// logic to determine the correct C/C++ compilers for the target. It also determines the appropriate
+/// archiver (`ar`) and sets up additional compilation flags (both handled and unhandled).
 pub fn find_target(build: &Build, target: TargetSelection) {
     let mut cfg = new_cc_build(build, target);
     let config = build.config.target_config.get(&target);
@@ -172,6 +185,8 @@ pub fn find_target(build: &Build, target: TargetSelection) {
     }
 }
 
+/// Determines the default compiler for a given target and language when not explicitly
+/// configured in `config.toml`.
 fn default_compiler(
     cfg: &mut cc::Build,
     compiler: Language,
@@ -248,6 +263,12 @@ fn default_compiler(
     }
 }
 
+/// Constructs the path to the Android NDK compiler for the given target triple and language.
+///
+/// This helper function transform the target triple by converting certain architecture names
+/// (for example, translating "arm" to "arm7a"), appends the minimum API level (hardcoded as "21"
+/// for NDK r26d), and then constructs the full path based on the provided NDK directory and host
+/// platform.
 pub(crate) fn ndk_compiler(compiler: Language, triple: &str, ndk: &Path) -> PathBuf {
     let mut triple_iter = triple.split('-');
     let triple_translated = if let Some(arch) = triple_iter.next() {
@@ -277,7 +298,11 @@ pub(crate) fn ndk_compiler(compiler: Language, triple: &str, ndk: &Path) -> Path
     ndk.join("toolchains").join("llvm").join("prebuilt").join(host_tag).join("bin").join(compiler)
 }
 
-/// The target programming language for a native compiler.
+/// Representing the target programming language for a native compiler.
+///
+/// This enum is used to indicate whether a particular compiler is intended for C or C++.
+/// It also provides helper methods for obtaining the standard executable names for GCC and
+/// clang-based compilers.
 #[derive(PartialEq)]
 pub(crate) enum Language {
     /// The compiler is targeting C.
@@ -287,7 +312,7 @@ pub(crate) enum Language {
 }
 
 impl Language {
-    /// Obtains the name of a compiler in the GCC collection.
+    /// Returns the executable name for a GCC compiler corresponding to this language.
     fn gcc(self) -> &'static str {
         match self {
             Language::C => "gcc",
@@ -295,7 +320,7 @@ impl Language {
         }
     }
 
-    /// Obtains the name of a compiler in the clang suite.
+    /// Returns the executable name for a clang-based compiler corresponding to this language.
     fn clang(self) -> &'static str {
         match self {
             Language::C => "clang",
@@ -303,3 +328,6 @@ impl Language {
         }
     }
 }
+
+#[cfg(test)]
+mod tests;
diff --git a/src/bootstrap/src/utils/cc_detect/tests.rs b/src/bootstrap/src/utils/cc_detect/tests.rs
new file mode 100644
index 00000000000..006dfe7e5d7
--- /dev/null
+++ b/src/bootstrap/src/utils/cc_detect/tests.rs
@@ -0,0 +1,254 @@
+use std::path::{Path, PathBuf};
+use std::{env, iter};
+
+use super::*;
+use crate::core::config::{Target, TargetSelection};
+use crate::{Build, Config, Flags};
+
+#[test]
+fn test_cc2ar_env_specific() {
+    let triple = "x86_64-unknown-linux-gnu";
+    let key = "AR_x86_64_unknown_linux_gnu";
+    env::set_var(key, "custom-ar");
+    let target = TargetSelection::from_user(triple);
+    let cc = Path::new("/usr/bin/clang");
+    let default_ar = PathBuf::from("default-ar");
+    let result = cc2ar(cc, target, default_ar);
+    env::remove_var(key);
+    assert_eq!(result, Some(PathBuf::from("custom-ar")));
+}
+
+#[test]
+fn test_cc2ar_musl() {
+    let triple = "x86_64-unknown-linux-musl";
+    env::remove_var("AR_x86_64_unknown_linux_musl");
+    env::remove_var("AR");
+    let target = TargetSelection::from_user(triple);
+    let cc = Path::new("/usr/bin/clang");
+    let default_ar = PathBuf::from("default-ar");
+    let result = cc2ar(cc, target, default_ar);
+    assert_eq!(result, Some(PathBuf::from("ar")));
+}
+
+#[test]
+fn test_cc2ar_openbsd() {
+    let triple = "x86_64-unknown-openbsd";
+    env::remove_var("AR_x86_64_unknown_openbsd");
+    env::remove_var("AR");
+    let target = TargetSelection::from_user(triple);
+    let cc = Path::new("/usr/bin/cc");
+    let default_ar = PathBuf::from("default-ar");
+    let result = cc2ar(cc, target, default_ar);
+    assert_eq!(result, Some(PathBuf::from("ar")));
+}
+
+#[test]
+fn test_cc2ar_vxworks() {
+    let triple = "armv7-wrs-vxworks";
+    env::remove_var("AR_armv7_wrs_vxworks");
+    env::remove_var("AR");
+    let target = TargetSelection::from_user(triple);
+    let cc = Path::new("/usr/bin/clang");
+    let default_ar = PathBuf::from("default-ar");
+    let result = cc2ar(cc, target, default_ar);
+    assert_eq!(result, Some(PathBuf::from("wr-ar")));
+}
+
+#[test]
+fn test_cc2ar_nto_i586() {
+    let triple = "i586-unknown-nto-something";
+    env::remove_var("AR_i586_unknown_nto_something");
+    env::remove_var("AR");
+    let target = TargetSelection::from_user(triple);
+    let cc = Path::new("/usr/bin/clang");
+    let default_ar = PathBuf::from("default-ar");
+    let result = cc2ar(cc, target, default_ar);
+    assert_eq!(result, Some(PathBuf::from("ntox86-ar")));
+}
+
+#[test]
+fn test_cc2ar_nto_aarch64() {
+    let triple = "aarch64-unknown-nto-something";
+    env::remove_var("AR_aarch64_unknown_nto_something");
+    env::remove_var("AR");
+    let target = TargetSelection::from_user(triple);
+    let cc = Path::new("/usr/bin/clang");
+    let default_ar = PathBuf::from("default-ar");
+    let result = cc2ar(cc, target, default_ar);
+    assert_eq!(result, Some(PathBuf::from("ntoaarch64-ar")));
+}
+
+#[test]
+fn test_cc2ar_nto_x86_64() {
+    let triple = "x86_64-unknown-nto-something";
+    env::remove_var("AR_x86_64_unknown_nto_something");
+    env::remove_var("AR");
+    let target = TargetSelection::from_user(triple);
+    let cc = Path::new("/usr/bin/clang");
+    let default_ar = PathBuf::from("default-ar");
+    let result = cc2ar(cc, target, default_ar);
+    assert_eq!(result, Some(PathBuf::from("ntox86_64-ar")));
+}
+
+#[test]
+#[should_panic(expected = "Unknown architecture, cannot determine archiver for Neutrino QNX")]
+fn test_cc2ar_nto_unknown() {
+    let triple = "powerpc-unknown-nto-something";
+    env::remove_var("AR_powerpc_unknown_nto_something");
+    env::remove_var("AR");
+    let target = TargetSelection::from_user(triple);
+    let cc = Path::new("/usr/bin/clang");
+    let default_ar = PathBuf::from("default-ar");
+    let _ = cc2ar(cc, target, default_ar);
+}
+
+#[test]
+fn test_ndk_compiler_c() {
+    let ndk_path = PathBuf::from("/ndk");
+    let target_triple = "arm-unknown-linux-android";
+    let expected_triple_translated = "armv7a-unknown-linux-android";
+    let expected_compiler = format!("{}21-{}", expected_triple_translated, Language::C.clang());
+    let host_tag = if cfg!(target_os = "macos") {
+        "darwin-x86_64"
+    } else if cfg!(target_os = "windows") {
+        "windows-x86_64"
+    } else {
+        "linux-x86_64"
+    };
+    let expected_path = ndk_path
+        .join("toolchains")
+        .join("llvm")
+        .join("prebuilt")
+        .join(host_tag)
+        .join("bin")
+        .join(&expected_compiler);
+    let result = ndk_compiler(Language::C, target_triple, &ndk_path);
+    assert_eq!(result, expected_path);
+}
+
+#[test]
+fn test_ndk_compiler_cpp() {
+    let ndk_path = PathBuf::from("/ndk");
+    let target_triple = "arm-unknown-linux-android";
+    let expected_triple_translated = "armv7a-unknown-linux-android";
+    let expected_compiler =
+        format!("{}21-{}", expected_triple_translated, Language::CPlusPlus.clang());
+    let host_tag = if cfg!(target_os = "macos") {
+        "darwin-x86_64"
+    } else if cfg!(target_os = "windows") {
+        "windows-x86_64"
+    } else {
+        "linux-x86_64"
+    };
+    let expected_path = ndk_path
+        .join("toolchains")
+        .join("llvm")
+        .join("prebuilt")
+        .join(host_tag)
+        .join("bin")
+        .join(&expected_compiler);
+    let result = ndk_compiler(Language::CPlusPlus, target_triple, &ndk_path);
+    assert_eq!(result, expected_path);
+}
+
+#[test]
+fn test_language_gcc() {
+    assert_eq!(Language::C.gcc(), "gcc");
+    assert_eq!(Language::CPlusPlus.gcc(), "g++");
+}
+
+#[test]
+fn test_language_clang() {
+    assert_eq!(Language::C.clang(), "clang");
+    assert_eq!(Language::CPlusPlus.clang(), "clang++");
+}
+
+#[test]
+fn test_new_cc_build() {
+    let build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
+    let target = TargetSelection::from_user("x86_64-unknown-linux-gnu");
+    let cfg = new_cc_build(&build, target.clone());
+    let compiler = cfg.get_compiler();
+    assert!(!compiler.path().to_str().unwrap().is_empty(), "Compiler path should not be empty");
+}
+
+#[test]
+fn test_default_compiler_wasi() {
+    let build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
+    let target = TargetSelection::from_user("wasm32-wasi");
+    let wasi_sdk = PathBuf::from("/wasi-sdk");
+    env::set_var("WASI_SDK_PATH", &wasi_sdk);
+    let mut cfg = cc::Build::new();
+    if let Some(result) = default_compiler(&mut cfg, Language::C, target.clone(), &build) {
+        let expected = {
+            let compiler = format!("{}-clang", target.triple);
+            wasi_sdk.join("bin").join(compiler)
+        };
+        assert_eq!(result, expected);
+    } else {
+        panic!(
+            "default_compiler should return a compiler path for wasi target when WASI_SDK_PATH is set"
+        );
+    }
+    env::remove_var("WASI_SDK_PATH");
+}
+
+#[test]
+fn test_default_compiler_fallback() {
+    let build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
+    let target = TargetSelection::from_user("x86_64-unknown-linux-gnu");
+    let mut cfg = cc::Build::new();
+    let result = default_compiler(&mut cfg, Language::C, target, &build);
+    assert!(result.is_none(), "default_compiler should return None for generic targets");
+}
+
+#[test]
+fn test_find_target_with_config() {
+    let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
+    let target = TargetSelection::from_user("x86_64-unknown-linux-gnu");
+    let mut target_config = Target::default();
+    target_config.cc = Some(PathBuf::from("dummy-cc"));
+    target_config.cxx = Some(PathBuf::from("dummy-cxx"));
+    target_config.ar = Some(PathBuf::from("dummy-ar"));
+    target_config.ranlib = Some(PathBuf::from("dummy-ranlib"));
+    build.config.target_config.insert(target.clone(), target_config);
+    find_target(&build, target.clone());
+    let binding = build.cc.borrow();
+    let cc_tool = binding.get(&target).unwrap();
+    assert_eq!(cc_tool.path(), &PathBuf::from("dummy-cc"));
+    let binding = build.cxx.borrow();
+    let cxx_tool = binding.get(&target).unwrap();
+    assert_eq!(cxx_tool.path(), &PathBuf::from("dummy-cxx"));
+    let binding = build.ar.borrow();
+    let ar = binding.get(&target).unwrap();
+    assert_eq!(ar, &PathBuf::from("dummy-ar"));
+    let binding = build.ranlib.borrow();
+    let ranlib = binding.get(&target).unwrap();
+    assert_eq!(ranlib, &PathBuf::from("dummy-ranlib"));
+}
+
+#[test]
+fn test_find_target_without_config() {
+    let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
+    let target = TargetSelection::from_user("x86_64-unknown-linux-gnu");
+    build.config.target_config.clear();
+    find_target(&build, target.clone());
+    assert!(build.cc.borrow().contains_key(&target));
+    if !target.triple.contains("vxworks") {
+        assert!(build.cxx.borrow().contains_key(&target));
+    }
+    assert!(build.ar.borrow().contains_key(&target));
+}
+
+#[test]
+fn test_find() {
+    let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
+    let target1 = TargetSelection::from_user("x86_64-unknown-linux-gnu");
+    let target2 = TargetSelection::from_user("arm-linux-androideabi");
+    build.targets.push(target1.clone());
+    build.hosts.push(target2.clone());
+    find(&build);
+    for t in build.hosts.iter().chain(build.targets.iter()).chain(iter::once(&build.build)) {
+        assert!(build.cc.borrow().contains_key(t), "CC not set for target {}", t.triple);
+    }
+}
diff --git a/src/tools/miri/tests/fail/panic/panic_abort1.rs b/src/tools/miri/tests/fail/panic/panic_abort1.rs
index 300bfa32ecb..7552c7b7e80 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort1.rs
+++ b/src/tools/miri/tests/fail/panic/panic_abort1.rs
@@ -1,6 +1,6 @@
 //@error-in-other-file: the program aborted execution
 //@normalize-stderr-test: "\| +\^+" -> "| ^"
-//@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();"
+//@normalize-stderr-test: "unsafe \{ libc::abort\(\); \}|core::intrinsics::abort\(\);" -> "ABORT();"
 //@compile-flags: -C panic=abort
 
 fn main() {
diff --git a/src/tools/miri/tests/fail/panic/panic_abort2.rs b/src/tools/miri/tests/fail/panic/panic_abort2.rs
index 5d691350577..624f9933545 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort2.rs
+++ b/src/tools/miri/tests/fail/panic/panic_abort2.rs
@@ -1,6 +1,6 @@
 //@error-in-other-file: the program aborted execution
 //@normalize-stderr-test: "\| +\^+" -> "| ^"
-//@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();"
+//@normalize-stderr-test: "unsafe \{ libc::abort\(\); \}|core::intrinsics::abort\(\);" -> "ABORT();"
 //@compile-flags: -C panic=abort
 
 fn main() {
diff --git a/src/tools/miri/tests/fail/panic/panic_abort3.rs b/src/tools/miri/tests/fail/panic/panic_abort3.rs
index 25afc315628..d1435b55946 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort3.rs
+++ b/src/tools/miri/tests/fail/panic/panic_abort3.rs
@@ -1,6 +1,6 @@
 //@error-in-other-file: the program aborted execution
 //@normalize-stderr-test: "\| +\^+" -> "| ^"
-//@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();"
+//@normalize-stderr-test: "unsafe \{ libc::abort\(\); \}|core::intrinsics::abort\(\);" -> "ABORT();"
 //@compile-flags: -C panic=abort
 
 fn main() {
diff --git a/src/tools/miri/tests/fail/panic/panic_abort4.rs b/src/tools/miri/tests/fail/panic/panic_abort4.rs
index 025b51a5cf5..54b9c9cbfdb 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort4.rs
+++ b/src/tools/miri/tests/fail/panic/panic_abort4.rs
@@ -1,6 +1,6 @@
 //@error-in-other-file: the program aborted execution
 //@normalize-stderr-test: "\| +\^+" -> "| ^"
-//@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();"
+//@normalize-stderr-test: "unsafe \{ libc::abort\(\); \}|core::intrinsics::abort\(\);" -> "ABORT();"
 //@compile-flags: -C panic=abort
 
 fn main() {