diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index 8cef9e0644bb0..e3e94e440f694 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -37,7 +37,6 @@ features = ['override_allocator_on_supported_platforms'] check_only = ['rustc_driver_impl/check_only'] jemalloc = ['dep:tikv-jemalloc-sys'] llvm = ['rustc_driver_impl/llvm'] -llvm_enzyme = ['rustc_driver_impl/llvm_enzyme'] llvm_offload = ['rustc_driver_impl/llvm_offload'] max_level_info = ['rustc_driver_impl/max_level_info'] rustc_randomized_layouts = ['rustc_driver_impl/rustc_randomized_layouts'] diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index 624f4ffea6ffc..8f265bad9728e 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -35,5 +35,4 @@ tracing = "0.1" [features] # tidy-alphabetical-start -llvm_enzyme = [] # tidy-alphabetical-end diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index c42ad17498136..8beb69f7b37d1 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -43,7 +43,6 @@ tracing = "0.1" [features] # tidy-alphabetical-start check_only = ["rustc_llvm/check_only"] -llvm_enzyme = [] llvm_offload = [] # tidy-alphabetical-end diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index b2d22876c1858..70d48def59e91 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -617,7 +617,7 @@ pub(crate) fn run_pass_manager( ); } - if cfg!(feature = "llvm_enzyme") && enable_ad && !thin { + if enable_ad && !thin { let opt_stage = llvm::OptStage::FatLTO; let stage = write::AutodiffStage::PostAD; if !config.autodiff.contains(&config::AutoDiff::NoPostopt) diff --git a/compiler/rustc_codegen_llvm/src/typetree.rs b/compiler/rustc_codegen_llvm/src/typetree.rs index 7c2e09227e46b..9988ccfaee052 100644 --- a/compiler/rustc_codegen_llvm/src/typetree.rs +++ b/compiler/rustc_codegen_llvm/src/typetree.rs @@ -75,15 +75,9 @@ enum TTLocation { Callsite, } -#[cfg_attr(not(feature = "llvm_enzyme"), allow(unused))] pub(crate) fn add_tt<'tcx, 'll>(cx: &FullCx<'ll, 'tcx>, fn_def: &'ll Value, tt: FncTree) { - // TypeTree processing uses functions from Enzyme, which we might not have available if we did - // not build this compiler with `llvm_enzyme`. This feature is not strictly necessary, but - // skipping this function increases the chance that Enzyme fails to compile some code. - // FIXME(autodiff): In the future we should conditionally run this function even without the - // `llvm_enzyme` feature, in case that libEnzyme was provided via rustup. - #[cfg(not(feature = "llvm_enzyme"))] - return; + // TypeTree processing uses functions from Enzyme. This feature is not strictly necessary, + // but skipping this function increases the chance that Enzyme fails to compile some code. let tcx = cx.tcx; if !tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable) { diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 214d653d23c13..0598fbfad6e4d 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -641,7 +641,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Unlike all the other GC helpers where we check if an `AllocId` is found in the interpreter or // is live, here all the IDs in the map are for dead allocations so we don't // need to check for liveness. - #[allow(rustc::potential_query_instability)] // Only used from Miri, not queries. self.memory.dead_alloc_map.retain(|id, _| reachable_allocs.contains(id)); } } diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index aeb2063e76960..c7d3e4fae3fc5 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -58,7 +58,6 @@ ctrlc = "3.4.4" # tidy-alphabetical-start check_only = ['rustc_interface/check_only'] llvm = ['rustc_interface/llvm'] -llvm_enzyme = ['rustc_interface/llvm_enzyme'] llvm_offload = ['rustc_interface/llvm_offload'] max_level_info = ['rustc_log/max_level_info'] rustc_randomized_layouts = [ diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index 9c115736a3d4f..4a272867046b4 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -57,6 +57,5 @@ rustc_abi = { path = "../rustc_abi" } # tidy-alphabetical-start check_only = ['rustc_codegen_llvm?/check_only'] llvm = ['dep:rustc_codegen_llvm'] -llvm_enzyme = ['rustc_builtin_macros/llvm_enzyme', 'rustc_codegen_llvm/llvm_enzyme'] llvm_offload = ['rustc_codegen_llvm/llvm_offload'] # tidy-alphabetical-end diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 22b643e74e582..4aa9f4d2eb1b0 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -828,6 +828,7 @@ fn test_unstable_options_tracking_hash() { tracked!(function_sections, Some(false)); tracked!(hint_mostly_unused, true); tracked!(human_readable_cgu_names, true); + tracked!(implicit_sysroot_deps, false); tracked!(incremental_ignore_spans, true); tracked!(indirect_branch_cs_prefix, true); tracked!(inline_mir, Some(true)); diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index f9ef016a16af6..c99575ff7431d 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -92,8 +92,6 @@ impl SubdiagnosticDerive { let diag = &self.diag; - // FIXME(edition_2024): Fix the `keyword_idents_2024` lint to not trigger here? - #[allow(keyword_idents_2024)] let ret = structure.gen_impl(quote! { gen impl rustc_errors::Subdiagnostic for @Self { fn add_to_diag<__G>( diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 8624e0524b04e..5ce4fe5113a93 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -1,5 +1,4 @@ // tidy-alphabetical-start -#![allow(rustc::default_hash_types)] #![feature(never_type)] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_tracked_env)] diff --git a/compiler/rustc_macros/src/print_attribute.rs b/compiler/rustc_macros/src/print_attribute.rs index 0114e0dfde0db..132a98a98ee07 100644 --- a/compiler/rustc_macros/src/print_attribute.rs +++ b/compiler/rustc_macros/src/print_attribute.rs @@ -120,7 +120,6 @@ pub(crate) fn print_attribute(input: Structure<'_>) -> TokenStream { } }; - #[allow(keyword_idents_2024)] input.gen_impl(quote! { #[allow(unused)] gen impl PrintAttribute for @Self { diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index 9e405c801867e..324ce0a4025e7 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -3,7 +3,7 @@ //! [`rustc`] module. // tidy-alphabetical-start -#![allow(unused_crate_dependencies)] +#![cfg_attr(test, allow(unused_crate_dependencies))] // Used for integration tests, not unit tests // tidy-alphabetical-end pub(crate) mod checks; diff --git a/compiler/rustc_session/src/config/sigpipe.rs b/compiler/rustc_session/src/config/sigpipe.rs index 1830ee034855b..5777e82d65d0e 100644 --- a/compiler/rustc_session/src/config/sigpipe.rs +++ b/compiler/rustc_session/src/config/sigpipe.rs @@ -5,21 +5,17 @@ /// /// Note that `SIG_IGN` has been the Rust default since 2014. See /// . -#[allow(dead_code)] pub const DEFAULT: u8 = 0; /// Do not touch `SIGPIPE`. Use whatever the parent process uses. -#[allow(dead_code)] pub const INHERIT: u8 = 1; /// Change `SIGPIPE` to `SIG_IGN` so that failed writes results in `EPIPE` /// that are eventually converted to `ErrorKind::BrokenPipe`. -#[allow(dead_code)] pub const SIG_IGN: u8 = 2; /// Change `SIGPIPE` to `SIG_DFL` so that the process is killed when trying /// to write to a closed pipe. This is usually the desired behavior for CLI /// apps that produce textual output that you want to pipe to other programs /// such as `head -n 1`. -#[allow(dead_code)] pub const SIG_DFL: u8 = 3; diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index bf1e1f5f12811..b2290f92aae12 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -12,6 +12,7 @@ use crate::search_paths::{PathKind, SearchPath}; pub struct FileSearch { cli_search_paths: Vec, tlib_path: SearchPath, + use_implicit_sysroot_deps: bool, } impl FileSearch { @@ -20,16 +21,27 @@ impl FileSearch { } pub fn search_paths<'b>(&'b self, kind: PathKind) -> impl Iterator { + // If the crate is `PathKind::Crate` (a top level dependency) + // and `-Z implicit-sysroot-deps=false`, then don't include the sysroot in the search paths. + let exclude_sysroot = kind.matches(PathKind::Crate) && !self.use_implicit_sysroot_deps; + let maybe_tlib = (!exclude_sysroot).then_some(&self.tlib_path); + self.cli_search_paths .iter() .filter(move |sp| sp.kind.matches(kind)) - .chain(std::iter::once(&self.tlib_path)) + .chain(maybe_tlib.into_iter()) } - pub fn new(cli_search_paths: &[SearchPath], tlib_path: &SearchPath, target: &Target) -> Self { + pub fn new( + cli_search_paths: &[SearchPath], + tlib_path: &SearchPath, + target: &Target, + use_implicit_sysroot_deps: bool, + ) -> Self { let this = FileSearch { cli_search_paths: cli_search_paths.to_owned(), tlib_path: tlib_path.clone(), + use_implicit_sysroot_deps, }; this.refine(&["lib", &target.staticlib_prefix, &target.dll_prefix]) } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 5b71c0435185a..ecfff0e64baf1 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2531,6 +2531,8 @@ options! { "display unnamed regions as `'`, using a non-ident unique id (default: no)"), ignore_directory_in_diagnostics_source_blocks: Vec = (Vec::new(), parse_string_push, [UNTRACKED], "do not display the source code block in diagnostics for files in the directory"), + implicit_sysroot_deps: bool = (true, parse_bool, [TRACKED], + "allows rust to search sysroot for a crate's dependencies (default: yes)"), incremental_ignore_spans: bool = (false, parse_bool, [TRACKED], "ignore spans during ICH computation -- used for testing (default: no)"), incremental_info: bool = (false, parse_bool, [UNTRACKED], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index eebead6fc1f47..e7f335e01d2f1 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1335,9 +1335,18 @@ pub fn build_session( }); let asm_arch = if target.allow_asm { InlineAsmArch::from_arch(&target.arch) } else { None }; - let target_filesearch = - filesearch::FileSearch::new(&sopts.search_paths, &target_tlib_path, &target); - let host_filesearch = filesearch::FileSearch::new(&sopts.search_paths, &host_tlib_path, &host); + let target_filesearch = filesearch::FileSearch::new( + &sopts.search_paths, + &target_tlib_path, + &target, + sopts.unstable_opts.implicit_sysroot_deps, + ); + let host_filesearch = filesearch::FileSearch::new( + &sopts.search_paths, + &host_tlib_path, + &host, + sopts.unstable_opts.implicit_sysroot_deps, + ); let timings = TimingSectionHandler::new(sopts.json_timings); diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml index 5421b1d2a2652..3f5f9f454a99d 100644 --- a/library/core/Cargo.toml +++ b/library/core/Cargo.toml @@ -23,7 +23,6 @@ optimize_for_size = [] # Make `RefCell` store additional debugging information, which is printed out when # a borrow error occurs debug_refcell = [] -llvm_enzyme = [] [lints.rust.unexpected_cfgs] level = "warn" @@ -39,7 +38,6 @@ check-cfg = [ 'cfg(target_has_reliable_f16_math)', 'cfg(target_has_reliable_f128)', 'cfg(target_has_reliable_f128_math)', - 'cfg(llvm_enzyme)', # Prevents use of a static variable for providing platform specific RawOsError # functionality 'cfg(no_io_statics)', diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 38340cd6aba73..424587bf75566 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -125,8 +125,6 @@ optimize_for_size = ["core/optimize_for_size", "alloc/optimize_for_size"] # a borrow error occurs debug_refcell = ["core/debug_refcell"] -llvm_enzyme = ["core/llvm_enzyme"] - # Enable using raw-dylib for Windows imports. # This will eventually be the default. windows_raw_dylib = ["windows-link/windows_raw_dylib"] diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml index b2069ef6a613b..10562389d62d3 100644 --- a/library/sysroot/Cargo.toml +++ b/library/sysroot/Cargo.toml @@ -32,4 +32,3 @@ optimize_for_size = ["std/optimize_for_size"] panic-unwind = ["std/panic-unwind"] profiler = ["dep:profiler_builtins"] windows_raw_dylib = ["std/windows_raw_dylib"] -llvm_enzyme = ["std/llvm_enzyme"] diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 57d7518792926..a2184f75487fe 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -13,6 +13,8 @@ use std::path::{Path, PathBuf}; use std::process::Command; use std::{env, fs, iter}; +use build_helper::git::get_closest_upstream_commit; + use crate::core::build_steps::compile::{ArtifactKeepMode, Std, run_cargo}; use crate::core::build_steps::doc::{DocumentationFormat, prepare_doc_compiler}; use crate::core::build_steps::gcc::{Gcc, GccTargetPair, add_cg_gcc_cargo_flags}; @@ -4613,3 +4615,90 @@ impl CommandLineStep for RemoteTestClientTests { ); } } + +fn check_if_cargo_semver_checks_is_installed(builder: &Builder<'_>) -> bool { + command("cargo") + .allow_failure() + .arg("semver-checks") + .arg("--version") + // Cache the output to avoid running this command more than once (per builder). + .cached() + .run_capture_stdout(builder) + .is_success() +} + +/// Run cargo-semver-checks on the standard library and compare its API +/// versus a previous baseline, using rustdoc JSON data. +/// +/// Fails if a semver-breaking change is detected. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct StdSemverCheck { + build_compiler: Compiler, + target: TargetSelection, + /// The baseline commit that we are comparing the local stdlib API against. + commit: String, +} + +impl CommandLineStep for StdSemverCheck { + type Output = (); + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("std-semver-check") + } + + fn make_run(run: RunConfig<'_>) { + if !check_if_cargo_semver_checks_is_installed(run.builder) { + panic!("cargo-semver-checks was not found, please install it"); + } + + let baseline_commit = match get_closest_upstream_commit( + Some(&run.builder.config.src), + &run.builder.config.git_config(), + run.builder.config.ci_env, + ) { + Ok(Some(commit)) => commit, + Ok(None) => { + panic!("No baseline parent commit found for std-semver-check"); + } + Err(error) => { + panic!("Cannot get baseline parent commit for std-semver-check: {error:?}"); + } + }; + + run.builder.ensure(Self { + build_compiler: run.builder.compiler_for_std(run.builder.top_stage), + target: run.target, + commit: baseline_commit, + }); + } + + fn run(self, builder: &Builder<'_>) { + let Some(docs_dir) = builder.config.download_std_json_docs(self.target, &self.commit) + else { + return; + }; + + let directory = builder.ensure(crate::core::build_steps::doc::Std::from_build_compiler( + self.build_compiler, + self.target, + DocumentationFormat::Json, + )); + let baseline_dir = docs_dir.join("share").join("doc").join("rust").join("json"); + + for library in ["core", "alloc", "std"] { + println!("Checking semver compatibility of {library}"); + let mut cmd = command("cargo"); + cmd.arg("semver-checks") + .arg("-Z") + .arg("unstable-options") + .arg("--stability-aware") + .arg("--release-type") + .arg("minor") + .arg("--current-rustdoc") + .arg(directory.join(format!("{library}.json"))) + .arg("--baseline-rustdoc") + .arg(baseline_dir.join(format!("{library}.json"))); + cmd.run(builder); + } + } +} diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_semver_check.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_semver_check.snap new file mode 100644 index 0000000000000..0a2720e55b785 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_semver_check.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test std-semver-check +--- +[Test] test::StdSemverCheck + targets: [aarch64-unknown-linux-gnu] + - Set({test::std-semver-check}) diff --git a/src/bootstrap/src/core/builder/cli_paths/tests.rs b/src/bootstrap/src/core/builder/cli_paths/tests.rs index 465a370ad69f8..45655b71e611a 100644 --- a/src/bootstrap/src/core/builder/cli_paths/tests.rs +++ b/src/bootstrap/src/core/builder/cli_paths/tests.rs @@ -170,6 +170,7 @@ declare_tests!( (x_test_librustdoc_rustdoc_html, "test librustdoc rustdoc-html"), (x_test_rustdoc, "test rustdoc"), (x_test_rustdoc_html, "test rustdoc-html"), + (x_test_semver_check, "test std-semver-check"), (x_test_skip_coverage, "test --skip=coverage"), (x_test_skip_coverage_map, "test --skip=coverage-map"), (x_test_skip_coverage_run, "test --skip=coverage-run"), diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 50188887a5314..ce476883c8839 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -974,6 +974,7 @@ impl<'a> Builder<'a> { test::RunMake, test::RunMakeCargo, test::BuildStd, + test::StdSemverCheck, test::IntrinsicTest, ), Kind::Miri => describe!(test::Crate), diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index e6d55fd530adb..d3bc5718b171e 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -173,6 +173,30 @@ impl Config { ); } + pub(crate) fn download_std_json_docs( + &self, + target: TargetSelection, + commit: &str, + ) -> Option { + if self.dry_run() { + return None; + } + + self.do_if_verbose(|| println!("using downloaded std json docs from CI (commit {commit})")); + + let version = self.artifact_version_part(commit); + download_component( + DownloadContext::from(self), + &self.out, + DownloadSource::CI, + format!("rust-docs-json-{version}-{target}.tar.xz"), + "rust-docs-json-preview", + // When using DownloadSource::CI, the key is assumed to end with -llvm-assertions + &format!("{commit}-{}", self.llvm_assertions), + "ci-docs-json", + ) + } + fn download_toolchain( &self, version: &str, @@ -785,11 +809,11 @@ fn download_component<'a>( prefix: &str, key: &str, destination: &str, -) { +) -> Option { let dwn_ctx = dwn_ctx.as_ref(); if dwn_ctx.exec_ctx.dry_run() { - return; + return None; } let cache_dst = @@ -834,8 +858,7 @@ fn download_component<'a>( let sha256 = dwn_ctx.stage0_metadata.checksums_sha256.get(&url).expect(&error); if tarball.exists() { if verify(dwn_ctx.exec_ctx, &tarball, sha256) { - unpack(dwn_ctx.exec_ctx, &tarball, &bin_root, prefix); - return; + return Some(unpack(dwn_ctx.exec_ctx, &tarball, &bin_root, prefix)); } else { dwn_ctx.exec_ctx.do_if_verbose(|| { println!( @@ -848,8 +871,7 @@ fn download_component<'a>( } Some(sha256) } else if tarball.exists() { - unpack(dwn_ctx.exec_ctx, &tarball, &bin_root, prefix); - return; + return Some(unpack(dwn_ctx.exec_ctx, &tarball, &bin_root, prefix)); } else { None }; @@ -872,7 +894,7 @@ download-rustc = false panic!("failed to verify {}", tarball.display()); } - unpack(dwn_ctx.exec_ctx, &tarball, &bin_root, prefix); + Some(unpack(dwn_ctx.exec_ctx, &tarball, &bin_root, prefix)) } pub(crate) fn verify(exec_ctx: &ExecutionContext, path: &Path, expected: &str) -> bool { @@ -916,7 +938,7 @@ pub(crate) fn verify(exec_ctx: &ExecutionContext, path: &Path, expected: &str) - verified } -fn unpack(exec_ctx: &ExecutionContext, tarball: &Path, dst: &Path, pattern: &str) { +fn unpack(exec_ctx: &ExecutionContext, tarball: &Path, dst: &Path, pattern: &str) -> PathBuf { eprintln!("extracting {} to {}", tarball.display(), dst.display()); if !dst.exists() { t!(fs::create_dir_all(dst)); @@ -979,6 +1001,7 @@ fn unpack(exec_ctx: &ExecutionContext, tarball: &Path, dst: &Path, pattern: &str if dst_dir.exists() { t!(fs::remove_dir_all(&dst_dir), format!("failed to remove {}", dst_dir.display())); } + dst.to_path_buf() } fn download_file<'a>( diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index df35face8b5d8..3babca128d471 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -848,10 +848,6 @@ impl Build { features.insert("compiler-builtins-mem"); } - if self.config.llvm_enzyme { - features.insert("llvm_enzyme"); - } - features.into_iter().collect::>().join(" ") } @@ -874,9 +870,6 @@ impl Build { if (self.config.llvm_enabled(target) || kind == Kind::Check) && check("llvm") { features.push("llvm"); } - if self.config.llvm_enzyme { - features.push("llvm_enzyme"); - } if self.config.llvm_offload { features.push("llvm_offload"); } diff --git a/src/ci/citool/Cargo.lock b/src/ci/citool/Cargo.lock index a208de47256ca..185eecbde1a02 100644 --- a/src/ci/citool/Cargo.lock +++ b/src/ci/citool/Cargo.lock @@ -66,9 +66,9 @@ checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] name = "askama" -version = "0.15.4" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08e1676b346cadfec169374f949d7490fd80a24193d37d2afce0c047cf695e57" +checksum = "f1bf825125edd887a019d0a3a837dcc5499a68b0d034cc3eb594070c3e18addc" dependencies = [ "askama_macros", "itoa", @@ -79,12 +79,13 @@ dependencies = [ [[package]] name = "askama_derive" -version = "0.15.4" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7661ff56517787343f376f75db037426facd7c8d3049cef8911f1e75016f3a37" +checksum = "e1c7065972a130eafa84215f21352ae15b4a7393da48c1f5e103904490736738" dependencies = [ "askama_parser", "basic-toml", + "glob", "memchr", "proc-macro2", "quote", @@ -96,18 +97,18 @@ dependencies = [ [[package]] name = "askama_macros" -version = "0.15.4" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713ee4dbfd1eb719c2dab859465b01fa1d21cb566684614a713a6b7a99a4e47b" +checksum = "0e23b1d2c4bd39a41971f6124cef4cc6fd0540913ecb90919b69ab3bbe44ae1a" dependencies = [ "askama_derive", ] [[package]] name = "askama_parser" -version = "0.15.4" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d62d674238a526418b30c0def480d5beadb9d8964e7f38d635b03bf639c704c" +checksum = "7db09fde9143e7ac4513358fb32ee32847125b63b18ea715afd487956da715da" dependencies = [ "rustc-hash", "serde", @@ -380,6 +381,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "glob" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" + [[package]] name = "glob-match" version = "0.2.1" @@ -1105,9 +1112,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.7.6" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" dependencies = [ "memchr", ] diff --git a/src/ci/citool/src/test_dashboard.rs b/src/ci/citool/src/test_dashboard.rs index c9de38852e5a8..bfcb2ba790e3e 100644 --- a/src/ci/citool/src/test_dashboard.rs +++ b/src/ci/citool/src/test_dashboard.rs @@ -1,4 +1,4 @@ -use std::collections::{BTreeMap, HashMap}; +use std::collections::{BTreeMap, HashMap, HashSet}; use std::fs::File; use std::io::BufWriter; use std::path::{Path, PathBuf}; @@ -17,12 +17,14 @@ pub fn generate_test_dashboard( output_dir: &Path, ) -> anyhow::Result<()> { let metrics = download_auto_job_metrics(&db, None, current)?; - let suites = gather_test_suites(&metrics); + let mut suites = gather_test_suites(&metrics); std::fs::create_dir_all(output_dir)?; + let jobsets = assign_jobsets(&mut suites); + let test_count = suites.test_count(); - write_page(output_dir, "index.html", &TestSuitesPage { suites, test_count })?; + write_page(output_dir, "index.html", &TestSuitesPage { suites, test_count, jobsets })?; Ok(()) } @@ -33,6 +35,45 @@ fn write_page(dir: &Path, name: &str, template: &T) -> anyhow::Resu Ok(()) } +struct JobSets { + sets: Vec<(u32, Vec)>, +} + +fn assign_jobsets(suites: &mut TestSuites) -> JobSets { + let mut jobsets: HashMap, u32> = HashMap::new(); + + fn visit(jobsets: &mut HashMap, u32>, group: &mut TestGroup) { + for (_, test) in &mut group.root_tests { + for (_, results) in &mut test.revisions { + let mut jobset: HashSet = HashSet::new(); + for test in &results.passed { + jobset.insert(test.job.to_string()); + } + let mut jobset: Vec = jobset.into_iter().collect(); + jobset.sort(); + + let jobset_count = jobsets.len() as u32; + let jobset_id = jobsets.entry(jobset).or_insert_with(|| jobset_count); + results.passed_jobset = Some(*jobset_id); + } + } + for (_, group) in &mut group.groups { + visit(jobsets, group); + } + } + for suite in &mut suites.suites { + visit(&mut jobsets, &mut suite.group); + } + + let mut jobsets: Vec<(u32, Vec)> = jobsets.into_iter().map(|(k, v)| (v, k)).collect(); + jobsets.sort_unstable_by(|a, b| a.0.cmp(&b.0)); + for (_, set) in &mut jobsets { + set.sort_unstable(); + } + + JobSets { sets: jobsets } +} + fn gather_test_suites(job_metrics: &HashMap) -> TestSuites<'_> { struct CoarseTestSuite<'a> { tests: BTreeMap>, @@ -68,10 +109,9 @@ fn gather_test_suites(job_metrics: &HashMap) -> TestSuites< .tests .entry(test_name.clone()) .or_insert_with(|| Test { revisions: Default::default() }); - let variant_entry = test_entry - .revisions - .entry(variant_name) - .or_insert_with(|| TestResults { passed: vec![], ignored: vec![] }); + let variant_entry = test_entry.revisions.entry(variant_name).or_insert_with(|| { + TestResults { passed: vec![], passed_jobset: None, ignored: vec![] } + }); match test.outcome { TestOutcome::Passed => { @@ -161,6 +201,8 @@ struct TestSuite<'a> { struct TestResults<'a> { passed: Vec>, + /// An id representing a set of jobs on which this test has passed. + passed_jobset: Option, ignored: Vec>, } @@ -213,4 +255,5 @@ impl<'a> TestGroup<'a> { struct TestSuitesPage<'a> { suites: TestSuites<'a>, test_count: u64, + jobsets: JobSets, } diff --git a/src/ci/citool/templates/test_group.askama b/src/ci/citool/templates/test_group.askama index 1a72c47d3788a..2e9a8327c8537 100644 --- a/src/ci/citool/templates/test_group.askama +++ b/src/ci/citool/templates/test_group.askama @@ -1,5 +1,5 @@ -{% macro test_result(r) -%} -passed: {{ r.passed.len() }}, ignored: {{ r.ignored.len() }} +{% macro test_result(r, jobset) -%} +passed: {{ r.passed.len() }}, ignored: {{ r.ignored.len() }} {%- endmacro %}
  • @@ -24,12 +24,12 @@ passed: {{ r.passed.len() }}, ignored: {{ r.ignored.len() }} {% for (name, test) in root_tests %}
  • {% if let Some(result) = test.single_test() %} - {{ name }} ({% call test_result(result) %}{% endcall %}) + {{ name }} ({% call test_result(result, result.passed_jobset.as_ref().unwrap()) %}{% endcall %}) {% else %} {{ name }} ({{ test.revisions.len() }} revision{{ test.revisions.len() | pluralize }})
      {% for (revision, result) in test.revisions %} -
    • #{{ revision }} ({% call test_result(result) %}{% endcall %})
    • +
    • #{{ revision }} ({% call test_result(result, result.passed_jobset.as_ref().unwrap()) %}{% endcall %})
    • {% endfor %}
    {% endif %} diff --git a/src/ci/citool/templates/test_suites.askama b/src/ci/citool/templates/test_suites.askama index 4997f6a3f1c9a..59ba2b7e86916 100644 --- a/src/ci/citool/templates/test_suites.askama +++ b/src/ci/citool/templates/test_suites.askama @@ -20,11 +20,26 @@ the count includes all combinations of "stage" x "target" x "CI job where the te -
      +
        {% for suite in suites.suites %} {{ suite.group|safe }} {% endfor %}
      +
      +

      Job sets

      +
      + {% for (id, jobs) in jobsets.sets %} + {% if !jobs.is_empty() %} +
      J{{ id }}
      +
        + {% for job in jobs %} +
      • {{ job }}
      • + {% endfor %} +
      + {% endif %} + {% endfor %} +
      +
      {% endblock %} @@ -34,6 +49,9 @@ h1 { color: #333333; margin-bottom: 30px; } +a:visited { + color: blue; +} .summary { display: flex; @@ -55,10 +73,14 @@ ul { padding-left: 0; } -li { +.tests li { list-style: none; padding-left: 20px; } +.jobsets li { + margin-left: 30px; +} + summary { margin-bottom: 5px; padding: 6px; diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index aeaea8ca9bb5b..342743d21340f 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -38,6 +38,7 @@ macro_rules! location { #[rustfmt::skip] const LICENSES: &[&str] = &[ // tidy-alphabetical-start + "(MIT OR Apache-2.0) AND MIT", "0BSD OR MIT OR Apache-2.0", // adler2 license "Apache-2.0 / MIT", "Apache-2.0 OR ISC OR MIT", diff --git a/tests/run-make/implicit-sysroot-deps/bar.rs b/tests/run-make/implicit-sysroot-deps/bar.rs new file mode 100644 index 0000000000000..ececc69fe9514 --- /dev/null +++ b/tests/run-make/implicit-sysroot-deps/bar.rs @@ -0,0 +1,4 @@ +#![feature(no_core)] +#![no_core] +#![no_std] +extern crate baz; diff --git a/tests/run-make/implicit-sysroot-deps/baz.rs b/tests/run-make/implicit-sysroot-deps/baz.rs new file mode 100644 index 0000000000000..ef13d56b7d4f0 --- /dev/null +++ b/tests/run-make/implicit-sysroot-deps/baz.rs @@ -0,0 +1,3 @@ +#![feature(no_core)] +#![no_core] +#![no_std] diff --git a/tests/run-make/implicit-sysroot-deps/foo.rs b/tests/run-make/implicit-sysroot-deps/foo.rs new file mode 100644 index 0000000000000..90d13bd02b1db --- /dev/null +++ b/tests/run-make/implicit-sysroot-deps/foo.rs @@ -0,0 +1,4 @@ +#![feature(no_core)] +#![no_core] +#![no_std] +extern crate bar; diff --git a/tests/run-make/implicit-sysroot-deps/rmake.rs b/tests/run-make/implicit-sysroot-deps/rmake.rs new file mode 100644 index 0000000000000..a748bda4db271 --- /dev/null +++ b/tests/run-make/implicit-sysroot-deps/rmake.rs @@ -0,0 +1,38 @@ +use run_make_support::rfs::create_dir_all; +use run_make_support::{rust_lib_name, rustc, target}; + +// Tests `-Zimplicit-sysroot-deps=false` with arbitrary crates passed via `--extern` +// See `tests/ui/crate-loading` for tests with the standard library + +fn main() { + // Create test sysroot + let test_sysroot = format!("./testsysroot/lib/rustlib/{}/lib/", target()); + create_dir_all(&test_sysroot); + + // Layout: + // - Foo depends directly on Bar + // - Bar depends directly on Baz + // - Baz can be found in the sysroot. + + // 1) Depending transitively on a lib in the sysroot resolves + // fine with `-Zimplicit-sysroot-deps=false` + rustc().input("baz.rs").crate_type("lib").out_dir(test_sysroot).run(); + rustc().input("bar.rs").crate_type("lib").sysroot("./testsysroot").run(); + rustc() + .input("foo.rs") + .crate_type("lib") + .extern_("bar", rust_lib_name("bar")) + .sysroot("./testsysroot") + .arg("-Zimplicit-sysroot-deps=false") + .run(); + + // 2) Depending directly on a lib in the sysroot does not resolve + // implicitly with `-Zimplicit-sysroot-deps=false` + rustc() + .input("bar.rs") + .crate_type("lib") + .sysroot("./testsysroot") + .arg("-Zimplicit-sysroot-deps=false") + .run_fail() + .assert_stderr_contains("can't find crate for `baz`"); +} diff --git a/tests/ui/crate-loading/auxiliary/crate-dep-std.rs b/tests/ui/crate-loading/auxiliary/crate-dep-std.rs new file mode 100644 index 0000000000000..5eec10bfc3e4a --- /dev/null +++ b/tests/ui/crate-loading/auxiliary/crate-dep-std.rs @@ -0,0 +1,3 @@ +pub fn bar() { + println!("I depend on std."); +} diff --git a/tests/ui/crate-loading/no-implicit-sysroot-deps-pass.rs b/tests/ui/crate-loading/no-implicit-sysroot-deps-pass.rs new file mode 100644 index 0000000000000..a2ce18597e0b8 --- /dev/null +++ b/tests/ui/crate-loading/no-implicit-sysroot-deps-pass.rs @@ -0,0 +1,16 @@ +//@ check-pass +//@ aux-build:crate-dep-std.rs +//@ compile-flags: --crate-type=lib -Zimplicit-sysroot-deps=false -Cpanic=abort + +// This test ensures that `-Zimplicit-sysroot-deps=false` allows loading transitive +// dependencies from the sysroot when required. + +#![feature(no_core)] +#![no_std] +#![no_core] + +extern crate crate_dep_std as foo; +use foo::bar; +pub fn bark() { + bar(); +} diff --git a/tests/ui/crate-loading/no-implicit-sysroot-deps.rs b/tests/ui/crate-loading/no-implicit-sysroot-deps.rs new file mode 100644 index 0000000000000..9a280cc681571 --- /dev/null +++ b/tests/ui/crate-loading/no-implicit-sysroot-deps.rs @@ -0,0 +1,14 @@ +//~ ERROR can't find crate for `std` +//~| NOTE can't find crate +//~| NOTE target may not be installed +//~| HELP consider building the standard library from source with `cargo build -Zbuild-std` +//~| HELP consider downloading the target with + +//@ compile-flags: --target x86_64-unknown-linux-gnu -Z implicit-sysroot-deps=false +//@ needs-llvm-components: x86 + +// This program has an implicit dependency on std, injected by rust. This test ensures that rustc +// does not search in the sysroot for it when `-Zimplicit-sysroot-deps` is false, and that an +// error is thrown when std is not available on any other search paths. + +fn main() {} diff --git a/tests/ui/crate-loading/no-implicit-sysroot-deps.stderr b/tests/ui/crate-loading/no-implicit-sysroot-deps.stderr new file mode 100644 index 0000000000000..688664cad9596 --- /dev/null +++ b/tests/ui/crate-loading/no-implicit-sysroot-deps.stderr @@ -0,0 +1,9 @@ +error[E0463]: can't find crate for `std` + | + = note: the `x86_64-unknown-linux-gnu` target may not be installed + = help: consider downloading the target with `rustup target add x86_64-unknown-linux-gnu` + = help: consider building the standard library from source with `cargo build -Zbuild-std` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0463`.