diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 479327d63695c..be9e47edb33af 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -16,6 +16,8 @@ use std::process::Stdio; use std::{env, fs, str}; use serde_derive::Deserialize; +#[cfg(feature = "tracing")] +use tracing::instrument; use crate::core::build_steps::tool::SourceType; use crate::core::build_steps::{dist, llvm}; @@ -30,7 +32,7 @@ use crate::utils::exec::command; use crate::utils::helpers::{ exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, symlink_dir, t, up_to_date, }; -use crate::{CLang, Compiler, DependencyType, GitRepo, LLVM_TOOLS, Mode}; +use crate::{CLang, Compiler, DependencyType, GitRepo, LLVM_TOOLS, Mode, debug, trace}; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Std { @@ -40,8 +42,9 @@ pub struct Std { /// /// This shouldn't be used from other steps; see the comment on [`Rustc`]. crates: Vec, - /// When using download-rustc, we need to use a new build of `std` for running unit tests of Std itself, - /// but we need to use the downloaded copy of std for linking to rustdoc. Allow this to be overridden by `builder.ensure` from other steps. + /// When using `download-rustc`, we need to use a new build of `std` for running unit tests of + /// std itself, but we need to use the downloaded copy of std for linking to rustdoc. Allow this + /// to be overridden by `builder.ensure` from other steps. force_recompile: bool, extra_rust_args: &'static [&'static str], is_for_mir_opt_tests: bool, @@ -102,12 +105,20 @@ impl Step for Std { let crates = std_crates_for_run_make(&run); let builder = run.builder; - // Force compilation of the standard library from source if the `library` is modified. This allows - // library team to compile the standard library without needing to compile the compiler with - // the `rust.download-rustc=true` option. + // Force compilation of the standard library from source if the `library` is modified. This + // allows library team to compile the standard library without needing to compile the + // compiler with the `rust.download-rustc=true` option. let force_recompile = builder.rust_info().is_managed_git_subrepository() && builder.download_rustc() && builder.config.last_modified_commit(&["library"], "download-rustc", true).is_none(); + trace!( + ?force_recompile, + is_git_managed = builder.rust_info().is_managed_git_subrepository(), + download_rustc = builder.download_rustc(), + last_modified_commit = + ?builder.config.last_modified_commit(&["library"], "download-rustc", true), + "checking std force-recompile" + ); run.builder.ensure(Std { compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()), @@ -121,9 +132,18 @@ impl Step for Std { /// Builds the standard library. /// - /// This will build the standard library for a particular stage of the build - /// using the `compiler` targeting the `target` architecture. The artifacts - /// created will also be linked into the sysroot directory. + /// This will build the standard library for a particular stage of the build using the + /// `compiler` targeting the `target` architecture. The artifacts created will also be linked + /// into the sysroot directory. + #[cfg_attr( + feature = "tracing", + instrument( + level = "trace", + name = "Std::run", + skip_all, + fields(target = ?self.target, compiler = ?self.compiler), + ), + )] fn run(self, builder: &Builder<'_>) { let target = self.target; let compiler = self.compiler; @@ -131,8 +151,8 @@ impl Step for Std { // When using `download-rustc`, we already have artifacts for the host available. Don't // recompile them. if builder.download_rustc() && target == builder.build.build - // NOTE: the beta compiler may generate different artifacts than the downloaded compiler, so - // its artifacts can't be reused. + // NOTE: the beta compiler may generate different artifacts than the downloaded + // compiler, so its artifacts can't be reused. && compiler.stage != 0 && !self.force_recompile { @@ -912,8 +932,9 @@ impl Step for Rustc { fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { let mut crates = run.builder.in_tree_crates("rustc-main", None); for (i, krate) in crates.iter().enumerate() { - // We can't allow `build rustc` as an alias for this Step, because that's reserved by `Assemble`. - // Ideally Assemble would use `build compiler` instead, but that seems too confusing to be worth the breaking change. + // We can't allow `build rustc` as an alias for this Step, because that's reserved by + // `Assemble`. Ideally Assemble would use `build compiler` instead, but that seems too + // confusing to be worth the breaking change. if krate.name == "rustc-main" { crates.swap_remove(i); break; @@ -931,11 +952,20 @@ impl Step for Rustc { }); } - /// Builds the compiler. + /// Builds the requested compiler at the requested stage. /// - /// This will build the compiler for a particular stage of the build using - /// the `compiler` targeting the `target` architecture. The artifacts - /// created will also be linked into the sysroot directory. + /// This will build the compiler for a particular stage of the build using the `compiler` + /// targeting the `target` architecture. The artifacts created will also be linked into the + /// sysroot directory. + #[cfg_attr( + feature = "tracing", + instrument( + level = "trace", + name = "Rustc::run", + skip_all, + fields(target = ?self.target, compiler = ?self.compiler), + ), + )] fn run(self, builder: &Builder<'_>) -> u32 { let compiler = self.compiler; let target = self.target; @@ -943,6 +973,10 @@ impl Step for Rustc { // NOTE: the ABI of the beta compiler is different from the ABI of the downloaded compiler, // so its artifacts can't be reused. if builder.download_rustc() && compiler.stage != 0 { + debug!( + "download-rustc requested; stage 0 rustc artifacts may not be reused, copying \ + rustc components to ci sysroot" + ); let sysroot = builder.ensure(Sysroot { compiler, force_recompile: false }); cp_rustc_component_to_ci_sysroot( builder, @@ -1615,8 +1649,18 @@ impl Step for Sysroot { } /// Returns the sysroot that `compiler` is supposed to use. - /// For the stage0 compiler, this is stage0-sysroot (because of the initial std build). - /// For all other stages, it's the same stage directory that the compiler lives in. + /// + /// - For the stage0 compiler, this is stage0-sysroot (because of the initial std build). + /// - For all other stages, it's the same stage directory that the compiler lives in. + #[cfg_attr( + feature = "tracing", + instrument( + level = "trace", + name = "Sysroot::run", + skip_all, + fields(compiler = ?self.compiler), + ), + )] fn run(self, builder: &Builder<'_>) -> PathBuf { let compiler = self.compiler; let host_dir = builder.out.join(compiler.host); @@ -1633,6 +1677,7 @@ impl Step for Sysroot { } }; let sysroot = sysroot_dir(compiler.stage); + trace!(?sysroot); builder .verbose(|| println!("Removing sysroot {} to avoid caching bugs", sysroot.display())); @@ -1640,23 +1685,27 @@ impl Step for Sysroot { t!(fs::create_dir_all(&sysroot)); // In some cases(see https://github.com/rust-lang/rust/issues/109314), when the stage0 - // compiler relies on more recent version of LLVM than the beta compiler, it may not - // be able to locate the correct LLVM in the sysroot. This situation typically occurs - // when we upgrade LLVM version while the beta compiler continues to use an older version. + // compiler relies on more recent version of LLVM than the beta compiler, it may not be able + // to locate the correct LLVM in the sysroot. This situation typically occurs when we + // upgrade LLVM version while the beta compiler continues to use an older version. // // Make sure to add the correct version of LLVM into the stage0 sysroot. if compiler.stage == 0 { dist::maybe_install_llvm_target(builder, compiler.host, &sysroot); } - // If we're downloading a compiler from CI, we can use the same compiler for all stages other than 0. + // If we're downloading a compiler from CI, we can use the same compiler for all stages + // other than 0. if builder.download_rustc() && compiler.stage != 0 { + debug!("download-rustc requested; reusing same compiler for stages > 0"); + assert_eq!( builder.config.build, compiler.host, "Cross-compiling is not yet supported with `download-rustc`", ); - // #102002, cleanup old toolchain folders when using download-rustc so people don't use them by accident. + // #102002, cleanup old toolchain folders when using download-rustc so people don't use + // them by accident. for stage in 0..=2 { if stage != compiler.stage { let dir = sysroot_dir(stage); @@ -1667,12 +1716,14 @@ impl Step for Sysroot { } // Copy the compiler into the correct sysroot. - // NOTE(#108767): We intentionally don't copy `rustc-dev` artifacts until they're requested with `builder.ensure(Rustc)`. - // This fixes an issue where we'd have multiple copies of libc in the sysroot with no way to tell which to load. - // There are a few quirks of bootstrap that interact to make this reliable: + // + // NOTE(#108767): We intentionally don't copy `rustc-dev` artifacts until they're + // requested with `builder.ensure(Rustc)`. This fixes an issue where we'd have multiple + // copies of libc in the sysroot with no way to tell which to load. There are a few + // quirks of bootstrap that interact to make this reliable: // 1. The order `Step`s are run is hard-coded in `builder.rs` and not configurable. This - // avoids e.g. reordering `test::UiFulldeps` before `test::Ui` and causing the latter to - // fail because of duplicate metadata. + // avoids e.g. reordering `test::UiFulldeps` before `test::Ui` and causing the latter + // to fail because of duplicate metadata. // 2. The sysroot is deleted and recreated between each invocation, so running `x test // ui-fulldeps && x test ui` can't cause failures. let mut filtered_files = Vec::new(); @@ -1713,11 +1764,11 @@ impl Step for Sysroot { }); } - // Symlink the source root into the same location inside the sysroot, - // where `rust-src` component would go (`$sysroot/lib/rustlib/src/rust`), - // so that any tools relying on `rust-src` also work for local builds, - // and also for translating the virtual `/rustc/$hash` back to the real - // directory (for running tests with `rust.remap-debuginfo = true`). + // Symlink the source root into the same location inside the sysroot, where `rust-src` + // component would go (`$sysroot/lib/rustlib/src/rust`), so that any tools relying on + // `rust-src` also work for local builds, and also for translating the virtual + // `/rustc/$hash` back to the real directory (for running tests with `rust.remap-debuginfo = + // true`). let sysroot_lib_rustlib_src = sysroot.join("lib/rustlib/src"); t!(fs::create_dir_all(&sysroot_lib_rustlib_src)); let sysroot_lib_rustlib_src_rust = sysroot_lib_rustlib_src.join("rust"); @@ -1761,11 +1812,10 @@ impl Step for Sysroot { #[derive(Debug, PartialOrd, Ord, Clone, PartialEq, Eq, Hash)] pub struct Assemble { - /// The compiler which we will produce in this step. Assemble itself will - /// take care of ensuring that the necessary prerequisites to do so exist, - /// that is, this target can be a stage2 compiler and Assemble will build - /// previous stages for you. - pub target_compiler: Compiler, + /// The compiler which we will produce in this step. Assemble itself will take care of ensuring + /// that the necessary prerequisites to do so exist, that is, this target can be a stage2 + /// compiler and `Assemble` will build previous stages for you. + pub output_compiler: Compiler, } impl Step for Assemble { @@ -1778,56 +1828,71 @@ impl Step for Assemble { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Assemble { - target_compiler: run.builder.compiler(run.builder.top_stage + 1, run.target), + output_compiler: run.builder.compiler(run.builder.top_stage + 1, run.target), }); } /// Prepare a new compiler from the artifacts in `stage` /// - /// This will assemble a compiler in `build/$host/stage$stage`. The compiler - /// must have been previously produced by the `stage - 1` builder.build - /// compiler. + /// This will assemble a compiler in `build/$host/stage$stage`. The compiler must have been + /// previously produced by the `stage - 1` build platform compiler. + #[cfg_attr( + feature = "tracing", + instrument( + level = "debug", + name = "Assemble::run", + skip_all, + fields(output_compiler = ?self.output_compiler), + ), + )] fn run(self, builder: &Builder<'_>) -> Compiler { - let target_compiler = self.target_compiler; + let output_compiler = self.output_compiler; - if target_compiler.stage == 0 { + if output_compiler.stage == 0 { assert_eq!( - builder.config.build, target_compiler.host, + builder.config.build, output_compiler.host, "Cannot obtain compiler for non-native build triple at stage 0" ); + debug!( + stage = output_compiler.stage, + host = ?output_compiler.host, + "requested compiler is pre-built stage 0 compiler" + ); // The stage 0 compiler for the build triple is always pre-built. - return target_compiler; + return output_compiler; } - // We prepend this bin directory to the user PATH when linking Rust binaries. To - // avoid shadowing the system LLD we rename the LLD we provide to `rust-lld`. - let libdir = builder.sysroot_target_libdir(target_compiler, target_compiler.host); + // We prepend this bin directory to the user PATH when linking Rust binaries. To avoid + // shadowing the system LLD we rename the LLD we provide to `rust-lld`. + + let libdir = builder.sysroot_target_libdir(output_compiler, output_compiler.host); let libdir_bin = libdir.parent().unwrap().join("bin"); t!(fs::create_dir_all(&libdir_bin)); - if builder.config.llvm_enabled(target_compiler.host) { + if builder.config.llvm_enabled(output_compiler.host) { + debug!("llvm enabled, ensuring LLVM is available"); let llvm::LlvmResult { llvm_config, .. } = - builder.ensure(llvm::Llvm { target: target_compiler.host }); + builder.ensure(llvm::Llvm { target: output_compiler.host }); if !builder.config.dry_run() && builder.config.llvm_tools_enabled { + debug!("llvm-tools enabled, ensuring LLVM tools are available"); let llvm_bin_dir = command(llvm_config).arg("--bindir").run_capture_stdout(builder).stdout(); let llvm_bin_dir = Path::new(llvm_bin_dir.trim()); - // Since we've already built the LLVM tools, install them to the sysroot. - // This is the equivalent of installing the `llvm-tools-preview` component via - // rustup, and lets developers use a locally built toolchain to - // build projects that expect llvm tools to be present in the sysroot - // (e.g. the `bootimage` crate). + // Since we've already built the LLVM tools, install them to the sysroot. This is + // the equivalent of installing the `llvm-tools-preview` component via rustup, and + // lets developers use a locally built toolchain to build projects that expect llvm + // tools to be present in the sysroot (e.g. the `bootimage` crate). for tool in LLVM_TOOLS { - let tool_exe = exe(tool, target_compiler.host); + let tool_exe = exe(tool, output_compiler.host); let src_path = llvm_bin_dir.join(&tool_exe); - // When using `download-ci-llvm`, some of the tools - // may not exist, so skip trying to copy them. + // When using `download-ci-llvm`, some of the tools may not exist, so skip + // trying to copy them. if src_path.exists() { - // There is a chance that these tools are being installed from an external LLVM. - // Use `Builder::resolve_symlink_and_copy` instead of `Builder::copy_link` to ensure - // we are copying the original file not the symlinked path, which causes issues for - // tarball distribution. + // There is a chance that these tools are being installed from an external + // LLVM. Use `Builder::resolve_symlink_and_copy` instead of + // `Builder::copy_link` to ensure we are copying the original file not the + // symlinked path, which causes issues for tarball distribution. // // See https://github.com/rust-lang/rust/issues/135554. builder.resolve_symlink_and_copy(&src_path, &libdir_bin.join(&tool_exe)); @@ -1838,92 +1903,94 @@ impl Step for Assemble { let maybe_install_llvm_bitcode_linker = |compiler| { if builder.config.llvm_bitcode_linker_enabled { + debug!("llvm-bitcode-linker is enabled, ensuring its availability"); let src_path = builder.ensure(crate::core::build_steps::tool::LlvmBitcodeLinker { compiler, - target: target_compiler.host, + target: output_compiler.host, extra_features: vec![], }); - let tool_exe = exe("llvm-bitcode-linker", target_compiler.host); + let tool_exe = exe("llvm-bitcode-linker", output_compiler.host); builder.copy_link(&src_path, &libdir_bin.join(tool_exe)); } }; - // If we're downloading a compiler from CI, we can use the same compiler for all stages other than 0. + // If we're downloading a compiler from CI, we can use the same compiler for all stages + // other than 0. if builder.download_rustc() { - builder.ensure(Std::new(target_compiler, target_compiler.host)); + debug!( + "download-rustc requested, downloading a CI compiler when stage is not 0 for use in later stages" + ); + builder.ensure(Std::new(output_compiler, output_compiler.host)); let sysroot = - builder.ensure(Sysroot { compiler: target_compiler, force_recompile: false }); - // Ensure that `libLLVM.so` ends up in the newly created target directory, - // so that tools using `rustc_private` can use it. - dist::maybe_install_llvm_target(builder, target_compiler.host, &sysroot); + builder.ensure(Sysroot { compiler: output_compiler, force_recompile: false }); + // Ensure that `libLLVM.so` ends up in the newly created target directory, so that tools + // using `rustc_private` can use it. + dist::maybe_install_llvm_target(builder, output_compiler.host, &sysroot); // Lower stages use `ci-rustc-sysroot`, not stageN - if target_compiler.stage == builder.top_stage { - builder.info(&format!("Creating a sysroot for stage{stage} compiler (use `rustup toolchain link 'name' build/host/stage{stage}`)", stage=target_compiler.stage)); + if output_compiler.stage == builder.top_stage { + builder.info(&format!("Creating a sysroot for stage{stage} compiler (use `rustup toolchain link 'name' build/host/stage{stage}`)", stage=output_compiler.stage)); } - maybe_install_llvm_bitcode_linker(target_compiler); + maybe_install_llvm_bitcode_linker(output_compiler); - return target_compiler; + return output_compiler; } - // Get the compiler that we'll use to bootstrap ourselves. + // Get the build compiler that we'll use to start the bootstrap chain to assembly eventually + // the desired output compiler. // - // Note that this is where the recursive nature of the bootstrap - // happens, as this will request the previous stage's compiler on - // downwards to stage 0. + // Note that this is where the recursive nature of the bootstrap happens, as this will + // request the previous stage's compiler on downwards to stage 0. // - // Also note that we're building a compiler for the host platform. We - // only assume that we can run `build` artifacts, which means that to - // produce some other architecture compiler we need to start from - // `build` to get there. + // Also note that we're building a compiler for the **host** platform. We only assume that + // we can run `build` platform artifacts, which means that to produce some other + // architecture compiler runnable on the **host** platform we need to start from `build` to + // get there. // - // FIXME: It may be faster if we build just a stage 1 compiler and then - // use that to bootstrap this compiler forward. - let mut build_compiler = builder.compiler(target_compiler.stage - 1, builder.config.build); - - // Build enzyme - let enzyme_install = if builder.config.llvm_enzyme { - Some(builder.ensure(llvm::Enzyme { target: build_compiler.host })) - } else { - None - }; + // Needs investigation: It may be faster if we build just a stage 1 compiler and then use + // that to bootstrap this compiler forward. + let mut build_compiler = builder.compiler(output_compiler.stage - 1, builder.config.build); - if let Some(enzyme_install) = enzyme_install { + if builder.config.llvm_enzyme { + let enzyme_install = builder.ensure(llvm::Enzyme { target: build_compiler.host }); let lib_ext = std::env::consts::DLL_EXTENSION; let src_lib = enzyme_install.join("build/Enzyme/libEnzyme-19").with_extension(lib_ext); let libdir = builder.sysroot_target_libdir(build_compiler, build_compiler.host); let target_libdir = - builder.sysroot_target_libdir(target_compiler, target_compiler.host); + builder.sysroot_target_libdir(output_compiler, output_compiler.host); let dst_lib = libdir.join("libEnzyme-19").with_extension(lib_ext); let target_dst_lib = target_libdir.join("libEnzyme-19").with_extension(lib_ext); builder.copy_link(&src_lib, &dst_lib); builder.copy_link(&src_lib, &target_dst_lib); } - // Build the libraries for this compiler to link to (i.e., the libraries - // it uses at runtime). NOTE: Crates the target compiler compiles don't - // link to these. (FIXME: Is that correct? It seems to be correct most - // of the time but I think we do link to these for stage2/bin compilers - // when not performing a full bootstrap). - let actual_stage = builder.ensure(Rustc::new(build_compiler, target_compiler.host)); + // Build the libraries for this compiler to link to (i.e., the libraries it uses at + // runtime). + // + // NOTE: Crates the target compiler compiles don't link to these. + // + // FIXME: Is that correct? It seems to be correct most of the time but I think we do link to + // these for stage2/bin compilers when not performing a full bootstrap. + let actual_stage = builder.ensure(Rustc::new(build_compiler, output_compiler.host)); + // Current build_compiler.stage might be uplifted instead of being built; so update it // to not fail while linking the artifacts. build_compiler.stage = actual_stage; - for backend in builder.config.codegen_backends(target_compiler.host) { + for backend in builder.config.codegen_backends(output_compiler.host) { if backend == "llvm" { continue; // Already built as part of rustc } builder.ensure(CodegenBackend { compiler: build_compiler, - target: target_compiler.host, + target: output_compiler.host, backend: backend.clone(), }); } - let stage = target_compiler.stage; - let host = target_compiler.host; + let stage = output_compiler.stage; + let host = output_compiler.host; let (host_info, dir_name) = if build_compiler.host == host { ("".into(), "host".into()) } else { @@ -1939,7 +2006,7 @@ impl Step for Assemble { builder.info(&msg); // Link in all dylibs to the libdir - let stamp = build_stamp::librustc_stamp(builder, build_compiler, target_compiler.host); + let stamp = build_stamp::librustc_stamp(builder, build_compiler, output_compiler.host); let proc_macros = builder .read_stamp_file(&stamp) .into_iter() @@ -1952,8 +2019,8 @@ impl Step for Assemble { }) .collect::>(); - let sysroot = builder.sysroot(target_compiler); - let rustc_libdir = builder.rustc_libdir(target_compiler); + let sysroot = builder.sysroot(output_compiler); + let rustc_libdir = builder.rustc_libdir(output_compiler); t!(fs::create_dir_all(&rustc_libdir)); let src_libdir = builder.sysroot_target_libdir(build_compiler, host); for f in builder.read_dir(&src_libdir) { @@ -1966,8 +2033,8 @@ impl Step for Assemble { // FIXME: Also do this for Windows once incremental post-optimization stage0 tests // work without std.dll (see https://github.com/rust-lang/rust/pull/131188). let can_be_rustc_dynamic_dep = if builder - .link_std_into_rustc_driver(target_compiler.host) - && !target_compiler.host.is_windows() + .link_std_into_rustc_driver(output_compiler.host) + && !output_compiler.host.is_windows() { let is_std = filename.starts_with("std-") || filename.starts_with("libstd-"); !is_std @@ -1980,24 +2047,24 @@ impl Step for Assemble { } } - copy_codegen_backends_to_sysroot(builder, build_compiler, target_compiler); + copy_codegen_backends_to_sysroot(builder, build_compiler, output_compiler); if builder.config.lld_enabled { builder.ensure(crate::core::build_steps::tool::LldWrapper { build_compiler, - target_compiler, + target_compiler: output_compiler, }); } - if builder.config.llvm_enabled(target_compiler.host) && builder.config.llvm_tools_enabled { + if builder.config.llvm_enabled(output_compiler.host) && builder.config.llvm_tools_enabled { // `llvm-strip` is used by rustc, which is actually just a symlink to `llvm-objcopy`, so // copy and rename `llvm-objcopy`. // // But only do so if llvm-tools are enabled, as bootstrap compiler might not contain any // LLVM tools, e.g. for cg_clif. // See . - let src_exe = exe("llvm-objcopy", target_compiler.host); - let dst_exe = exe("rust-objcopy", target_compiler.host); + let src_exe = exe("llvm-objcopy", output_compiler.host); + let dst_exe = exe("rust-objcopy", output_compiler.host); builder.copy_link(&libdir_bin.join(src_exe), &libdir_bin.join(dst_exe)); } @@ -2010,7 +2077,7 @@ impl Step for Assemble { let wasm_component_ld_exe = builder.ensure(crate::core::build_steps::tool::WasmComponentLd { compiler: build_compiler, - target: target_compiler.host, + target: output_compiler.host, }); builder.copy_link( &wasm_component_ld_exe, @@ -2022,18 +2089,18 @@ impl Step for Assemble { // Ensure that `libLLVM.so` ends up in the newly build compiler directory, // so that it can be found when the newly built `rustc` is run. - dist::maybe_install_llvm_runtime(builder, target_compiler.host, &sysroot); - dist::maybe_install_llvm_target(builder, target_compiler.host, &sysroot); + dist::maybe_install_llvm_runtime(builder, output_compiler.host, &sysroot); + dist::maybe_install_llvm_target(builder, output_compiler.host, &sysroot); // Link the compiler binary itself into place let out_dir = builder.cargo_out(build_compiler, Mode::Rustc, host); let rustc = out_dir.join(exe("rustc-main", host)); let bindir = sysroot.join("bin"); t!(fs::create_dir_all(bindir)); - let compiler = builder.rustc(target_compiler); + let compiler = builder.rustc(output_compiler); builder.copy_link(&rustc, &compiler); - target_compiler + output_compiler } } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 26ed0e5deaa05..8852f2b5587af 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1,3 +1,4 @@ +// ignore-tidy-filelength //! Build-and-run steps for `./x.py test` test fixtures //! //! `./x.py test` (aka [`Kind::Test`]) is currently allowed to reach build steps in other modules. @@ -9,6 +10,8 @@ use std::path::{Path, PathBuf}; use std::{env, fs, iter}; use clap_complete::shells; +#[cfg(feature = "tracing")] +use tracing::instrument; use crate::core::build_steps::compile::run_cargo; use crate::core::build_steps::doc::DocumentationFormat; @@ -29,7 +32,7 @@ use crate::utils::helpers::{ linker_flags, t, target_supports_cranelift_backend, up_to_date, }; use crate::utils::render_tests::{add_flags_and_try_run_tests, try_run_tests}; -use crate::{CLang, DocTests, GitRepo, Mode, PathSet, envify}; +use crate::{CLang, DocTests, GitRepo, Mode, PathSet, debug, envify}; const ADB_TEST_DIR: &str = "/data/local/tmp/work"; @@ -355,50 +358,394 @@ impl Step for RustAnalyzer { const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/tools/rust-analyzer") + run.path("src/tools/rust-analyzer").alias("rust-analyzer") } fn make_run(run: RunConfig<'_>) { run.builder.ensure(Self { stage: run.builder.top_stage, host: run.target }); } - /// Runs `cargo test` for rust-analyzer + #[cfg_attr( + feature = "tracing", + instrument( + level = "debug", + name = "RustAnalyzer::run", + skip_all, + fields(stage = self.stage, host = ?self.host), + ), + )] + fn run(self, builder: &Builder<'_>) { + debug!(stage = self.stage, host = ?self.host, "ensuring compiler"); + let compiler = builder.compiler(self.stage, self.host); + + debug!(stage = self.stage, host = ?self.host, "ensuring std"); + builder.ensure(compile::Rustc::new(compiler, self.host)); + + let mut cargo = tool::prepare_tool_cargo( + builder, + compiler, + Mode::ToolRustc, + self.host, + Kind::Test, + "src/tools/rust-analyzer", + SourceType::InTree, + &["in-rust-tree".to_owned()], + ); + cargo.allow_features(tool::RustAnalyzer::ALLOW_FEATURES); + + // RA's test suite tries to write to the source directory, that can't work in Rust CI. + cargo.env("SKIP_SLOW_TESTS", "1"); + + // NOTE: unlike `proc-macro-srv` step, we must **not** set `CARGO_WORKSPACE_DIR` because I + // believe `src/tools/rust-analyzer/.cargo/config.toml`'s relative `CARGO_WORKSPACE_DIR` + // takes effect, + + cargo.add_rustc_lib_path(builder); + + // NOTE: we need to skip `src/tools/rust-analyzer/xtask` as they seem to exercise rustup / + // stable rustfmt. + // + // NOTE: you can only skip a specific workspace package via `--skip=...` if you *also* + // specify `--workspace`. + cargo.arg("--workspace"); + cargo.arg("--exclude=xtask"); + + let mut skip_tests = vec![ + // FIXME: may need a fix from https://github.com/rust-lang/rust-analyzer/pull/19124. + "config::tests::cargo_target_dir_subdir", + // FIXME: I think this exercises cargo somehow? + "tests::smoke_test_real_sysroot_cargo", + // FIXME: config generation + "config::tests::generate_config_documentation", + "config::tests::generate_package_json_config", + ]; + skip_tests.extend(if self.host.starts_with("aarch64-apple") { + vec![ + // FIXME: fails on `aarch64-apple` due to `cfg` differences + "item_tree::tests::generics_with_attributes", + "hover::tests::generic_params_disabled_by_cfg", + ] + } else if self.host == "i686-pc-windows-gnu" || self.host == "i686-pc-windows-msvc" { + // FIXME: note that I didn't bother separately investigating if what fails on 32-bit + // windows-gnu also fails on 32-bit windows-msvc, just ignore these tests for both + // 32-bit windows targets. + + // FIXME: fails on `i686-mingw` due to multiple reasons. E.g. unsupport op on 32-bit + // windows-gnu target but on a 64-bit host, i.e. ptr width being different is + // unsupported. + vec![ + // FIXME: failed to const eval on 32-bit windows-gnu running on 64-bit host maybe? + "consteval::tests::add", + "consteval::tests::anonymous_const_block", + "consteval::tests::alignment", + "consteval::tests::bit_op", + "consteval::tests::associated_types", + "consteval::tests::boxes", + "consteval::tests::array_and_index", + "consteval::tests::builtin_derive_macro", + "consteval::tests::casts", + "consteval::tests::const_generic_subst_assoc_const_impl", + "consteval::tests::c_string", + "consteval::tests::const_generic_subst_fn", + "consteval::tests::const_impl_assoc", + "consteval::tests::closure_clone", + "consteval::tests::byte_string", + "consteval::tests::closures", + "consteval::tests::const_trait_assoc", + "consteval::tests::coerce_unsized", + "consteval::tests::consts", + "consteval::tests::enums", + "consteval::tests::floating_point", + "consteval::tests::destructing_assignment", + "consteval::tests::floating_point_casts", + "consteval::tests::closure_and_impl_fn", + "consteval::tests::extern_weak_statics", + "consteval::tests::function_call", + "consteval::tests::function_param_patterns", + "consteval::tests::closure_capture_unsized_type", + "consteval::tests::function_pointer", + "consteval::tests::from_ne_bytes", + "consteval::tests::function_pointer_in_constants", + "consteval::tests::from_trait", + "consteval::tests::ifs", + "consteval::tests::generic_fn", + "consteval::tests::dyn_trait", + "consteval::tests::impl_trait", + "consteval::tests::enum_variant_as_function", + "consteval::tests::const_transfer_memory", + "consteval::tests::intrinsics::allocator", + "consteval::tests::function_traits", + "consteval::tests::intrinsics::copy_nonoverlapping", + "consteval::tests::intrinsics::ctlz", + "consteval::tests::intrinsics::ctpop", + "consteval::tests::intrinsics::cttz", + "consteval::tests::intrinsics::const_eval_select", + "consteval::tests::intrinsics::floating_point", + "consteval::tests::for_loops", + "consteval::tests::function_pointer_and_niche_optimization", + "consteval::tests::intrinsics::likely", + "consteval::tests::intrinsics::arith_offset", + "consteval::tests::intrinsics::overflowing_add", + "consteval::tests::intrinsics::atomic", + "consteval::tests::intrinsics::rotate", + "consteval::tests::intrinsics::copy", + "consteval::tests::intrinsics::read_via_copy", + "consteval::tests::intrinsics::saturating", + "consteval::tests::intrinsics::needs_drop", + "consteval::tests::intrinsics::size_of", + "consteval::tests::intrinsics::simd", + "consteval::tests::intrinsics::min_align_of_val", + "consteval::tests::intrinsics::transmute", + "consteval::tests::intrinsics::type_name", + "consteval::tests::intrinsics::wrapping_add", + "consteval::tests::intrinsics::write_bytes", + "consteval::tests::intrinsics::write_via_move", + "consteval::tests::let_else", + "consteval::tests::layout_of_type_with_associated_type_field_defined_inside_body", + "consteval::tests::loops", + "consteval::tests::locals", + "consteval::tests::intrinsics::offset", + "consteval::tests::intrinsics::size_of_val", + "consteval::tests::or_pattern", + "consteval::tests::memory_limit", + "consteval::tests::intrinsics::ptr_offset_from", + "consteval::tests::intrinsics::discriminant_value", + "consteval::tests::path_pattern_matching", + "consteval::tests::overloaded_binop", + "consteval::tests::overloaded_deref", + "consteval::tests::overloaded_index", + "consteval::tests::overloaded_deref_autoref", + "consteval::tests::pattern_matching_ergonomics", + "consteval::tests::pattern_matching_literal", + "consteval::tests::pattern_matching_range", + "consteval::tests::manual_fn_trait_impl", + "consteval::tests::recursion", + "consteval::tests::reference_autoderef", + "consteval::tests::references", + "consteval::tests::ranges", + "consteval::tests::raw_pointer_equality", + "consteval::tests::match_guards", + "consteval::tests::structs", + "consteval::tests::options", + "consteval::tests::trait_method", + "consteval::tests::trait_basic", + "consteval::tests::pattern_matching_slice", + "consteval::tests::string", + "consteval::tests::trait_method_inside_block", + "consteval::tests::statics", + "consteval::tests::tuples", + "consteval::tests::unions", + "consteval::tests::result_layout_niche_optimization", + "consteval::tests::unsized_field", + "consteval::tests::try_block", + "consteval::tests::try_operator", + "mir::eval::tests::closure_capture_array_const_generic", + "mir::eval::tests::closure_layout_in_rpit", + "mir::eval::tests::drop_basic", + "mir::eval::tests::closure_state", + "mir::eval::tests::drop_in_place", + "mir::eval::tests::field_with_associated_type", + "mir::eval::tests::function_with_extern_c_abi", + "mir::eval::tests::generic_impl_for_trait_with_generic_method", + "mir::eval::tests::drop_if_let", + "mir::eval::tests::drop_struct_field", + "mir::eval::tests::index_of_slice_should_preserve_len", + "mir::eval::tests::for_loop", + "mir::eval::tests::manually_drop", + "mir::eval::tests::from_fn", + "mir::eval::tests::long_str_eq_same_prefix", + "mir::eval::tests::posix_getenv", + "mir::eval::tests::memcmp", + "mir::eval::tests::panic_display", + "mir::eval::tests::self_with_capital_s", + "mir::eval::tests::short_circuit_operator", + "mir::eval::tests::panic_fmt", + "mir::eval::tests::regression_14966", + "mir::eval::tests::posix_tls", + "mir::eval::tests::specialization_array_clone", + "mir::eval::tests::unix_write_stdout", + "mir::eval::tests::syscalls", + "tests::regression::regression_14456", + "tests::simple::const_eval_array_repeat_expr", + "tests::simple::const_eval_in_function_signature", + "tests::simple::issue_14275", + "tests::traits::array_length", + "tests::traits::const_generics", + // FIXME: annotation order seems to be different on `i686-mingw` + "annotations::tests::runnable_annotation", + "annotations::tests::struct_references_annotations", + "annotations::tests::struct_and_trait_impls_annotations", + "annotations::tests::method_annotations", + // FIXME: const eval on hover not working, either shows infer `_` or unevaluated. + "hover::tests::array_repeat_exp", + "hover::tests::const_generic_negative_i8_literal", + "hover::tests::hover_const_eval", + "hover::tests::hover_const_eval_discriminant", + "hover::tests::hover_const_eval_enum", + "hover::tests::hover_const_eval_floating_point", + "hover::tests::hover_const_static", + "hover::tests::hover_const_pat", + "hover::tests::hover_const_eval_slice", + "hover::tests::hover_eval_complex_constants", + "hover::tests::hover_unsigned_max_const", + "hover::tests::i128_max", + // FIXME: failed to const eval, formatting difference in const struct + // (extra comma / reformatted?) + "hover::tests::hover_const_eval_str", + // FIXME: failed to const eval, extra path segment + "hover::tests::hover_const_value", + "hover::tests::hover_dollar_crate", + "hover::tests::hover_dollar_crate stdout", + // FIXME: failed to const eval, shows explicit `i32` on literal + "hover::tests::hover_const_eval_dyn_trait", + // FIXME: discriminant `= ?` problems + "inlay_hints::discriminant::tests::datacarrying_mixed", + "inlay_hints::discriminant::tests::fieldless", + // FIXME: list order non-deterministic or different on `i686-mingw`? + "runnables::tests::tests_are_unique", + // FIXME: HTML element attribute order maybe non-deterministic or different on + // `i686-mingw`? + "syntax_highlighting::tests::test_rainbow_highlighting", + // FIXME: enum discrim not evaluated? + "handlers::explicit_enum_discriminant::tests::non_primitive_repr_non_data_bearing_add_discriminant", + "tests::generated::doctest_explicit_enum_discriminant", + // FIXME: import is different + "handlers::add_explicit_type::tests::regression_issue_2922", + "handlers::bool_to_enum::tests::field_enum_cross_file", + // FIXME: assist no source changes + "handlers::explicit_enum_discriminant::tests::primitive_repr_non_data_bearing_add_discriminant", + // FIXME: code action not applicable + "handlers::inline_const_as_literal::tests::inline_const_as_literal_block_array", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_block_recursive", + "handlers::explicit_enum_discriminant::tests::primitive_repr_non_data_bearing_add_discriminant", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_block_array", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_block_recursive", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_block_scalar_calculate_expr", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_block_scalar_calculate_param_expr", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_block_slice_single", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_block_tuple", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_const_block_eval_block_expr", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_block_tuple_scalar_calculate_block_expr", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_const_block_eval_expr", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_const_block_expr", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_const_expr", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_const_fn_call_block_nested_builtin", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_const_fn_call_builtin", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_const_fn_call_tuple", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_eval_const_block_expr_to_str_lit", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_eval_const_if_expr_to_str_lit", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_eval_const_call_expr_to_str_lit", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_eval_const_block_macro_expr_to_str_lit", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_eval_const_macro_expr_to_str_lit", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_eval_const_match_expr_to_str_lit", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_expr_as_str_lit", + "handlers::inline_const_as_literal::tests::inline_const_as_literal_scalar_operators", + // FIXME: assist is not applicable + "tests::generated::doctest_inline_const_as_literal", + // FIXME: order of `ex fn` are different? + "render::tests::score_fn_type_and_name_match", + // FIXME: false negatives in diagnostic tests + "handlers::type_mismatch::tests::evaluate_const_generics_in_types", + "handlers::mutability_errors::tests::or_pattern", + ] + } else if self.host == "x86_64-apple-darwin" { + vec![ + // FIXME: missing `#[cfg(never)]` on struct generic param + "item_tree::tests::generics_with_attributes", + // FIXME: `{unknown}` in generic param position + "hover::tests::generic_params_disabled_by_cfg", + ] + } else { + vec![] + }); + + let skip_tests = skip_tests.iter().map(|name| format!("--skip={name}")).collect::>(); + let skip_tests = skip_tests.iter().map(|s| s.as_str()).collect::>(); + + run_cargo_test( + cargo, + skip_tests.as_slice(), + &[], + "rust-analyzer", + "rust-analyzer", + self.host, + builder, + ); + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct RustAnalyzerProcMacroSrv { + stage: u32, + host: TargetSelection, +} + +impl Step for RustAnalyzerProcMacroSrv { + type Output = (); + const ONLY_HOSTS: bool = true; + const DEFAULT: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/rust-analyzer/crates/proc-macro-srv").alias("rust-analyzer") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(Self { stage: run.builder.top_stage, host: run.target }); + } + + #[cfg_attr( + feature = "tracing", + instrument( + level = "debug", + name = "RustAnalyzerProcMacroSrv::run", + skip_all, + fields(stage = self.stage, host = ?self.host), + ), + )] fn run(self, builder: &Builder<'_>) { let stage = self.stage; let host = self.host; + + debug!(stage, ?host, "ensuring compiler"); let compiler = builder.compiler(stage, host); // We don't need to build the whole Rust Analyzer for the proc-macro-srv test suite, // but we do need the standard library to be present. + debug!(stage, ?compiler, "ensuring std"); builder.ensure(compile::Rustc::new(compiler, host)); - let workspace_path = "src/tools/rust-analyzer"; - // until the whole RA test suite runs on `i686`, we only run - // `proc-macro-srv` tests - let crate_path = "src/tools/rust-analyzer/crates/proc-macro-srv"; + debug!("running `cargo test` on `src/tools/rust-analyzer/crates/proc-macro-srv`"); + let mut cargo = tool::prepare_tool_cargo( builder, compiler, Mode::ToolRustc, host, Kind::Test, - crate_path, + "src/tools/rust-analyzer/crates/proc-macro-srv", SourceType::InTree, &["in-rust-tree".to_owned()], ); cargo.allow_features(tool::RustAnalyzer::ALLOW_FEATURES); - let dir = builder.src.join(workspace_path); - // needed by rust-analyzer to find its own text fixtures, cf. - // https://github.com/rust-analyzer/expect-test/issues/33 + let dir = builder.src.join("src/tools/rust-analyzer"); + // Needed by rust-analyzer to find its own text fixtures, cf. + // https://github.com/rust-analyzer/expect-test/issues/33. cargo.env("CARGO_WORKSPACE_DIR", &dir); - // RA's test suite tries to write to the source directory, that can't - // work in Rust CI + // RA's test suite tries to write to the source directory, that can't work in Rust CI. cargo.env("SKIP_SLOW_TESTS", "1"); cargo.add_rustc_lib_path(builder); - run_cargo_test(cargo, &[], &[], "rust-analyzer", "rust-analyzer", host, builder); + run_cargo_test( + cargo, + &[], + &[], + "rust-analyzer/crates/proc-macro-srv", + "rust-analyzer proc-macro-srv", + host, + builder, + ); } } @@ -2623,14 +2970,14 @@ fn prepare_cargo_test( cargo.arg("--quiet"); } - // The tests are going to run with the *target* libraries, so we need to - // ensure that those libraries show up in the LD_LIBRARY_PATH equivalent. + // The tests are going to run with the *target* libraries, so we need to ensure that those + // libraries show up in the LD_LIBRARY_PATH equivalent. // - // Note that to run the compiler we need to run with the *host* libraries, - // but our wrapper scripts arrange for that to be the case anyway. + // Note that to run the compiler we need to run with the *host* libraries, but our wrapper + // scripts arrange for that to be the case anyway. // - // We skip everything on Miri as then this overwrites the libdir set up - // by `Cargo::new` and that actually makes things go wrong. + // We skip everything on Miri as then this overwrites the libdir set up by `Cargo::new` and that + // actually makes things go wrong. if builder.kind != Kind::Miri { let mut dylib_path = dylib_path(); dylib_path.insert(0, PathBuf::from(&*builder.sysroot_target_libdir(compiler, target))); diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index ecec589fc32eb..4fa6ec42900e4 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -21,7 +21,7 @@ use crate::core::config::{DryRun, TargetSelection}; use crate::utils::cache::Cache; use crate::utils::exec::{BootstrapCommand, command}; use crate::utils::helpers::{self, LldThreads, add_dylib_path, exe, libdir, linker_args, t}; -use crate::{Build, Crate}; +use crate::{Build, Crate, trace}; mod cargo; @@ -971,6 +971,7 @@ impl<'a> Builder<'a> { test::Cargotest, test::Cargo, test::RustAnalyzer, + test::RustAnalyzerProcMacroSrv, test::ErrorIndex, test::Distcheck, test::Nomicon, @@ -1215,7 +1216,7 @@ impl<'a> Builder<'a> { /// `Compiler` since all `Compiler` instances are meant to be obtained through this function, /// since it ensures that they are valid (i.e., built and assembled). pub fn compiler(&self, stage: u32, host: TargetSelection) -> Compiler { - self.ensure(compile::Assemble { target_compiler: Compiler { stage, host } }) + self.ensure(compile::Assemble { output_compiler: Compiler { stage, host } }) } /// Similar to `compiler`, except handles the full-bootstrap option to @@ -1331,6 +1332,8 @@ impl<'a> Builder<'a> { return; } + trace!(rustc_lib_paths = ?self.rustc_lib_paths(compiler)); + add_dylib_path(self.rustc_lib_paths(compiler), cmd); } diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index a0be474ca3e39..7210d41d2fa8e 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -352,9 +352,9 @@ mod defaults { assert_eq!( first(cache.all::()), &[ - compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, - compile::Assemble { target_compiler: Compiler { host: b, stage: 1 } }, + compile::Assemble { output_compiler: Compiler { host: a, stage: 0 } }, + compile::Assemble { output_compiler: Compiler { host: a, stage: 1 } }, + compile::Assemble { output_compiler: Compiler { host: b, stage: 1 } }, ] ); assert_eq!( @@ -632,10 +632,10 @@ mod dist { assert_eq!( first(cache.all::()), &[ - compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } }, - compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } }, + compile::Assemble { output_compiler: Compiler { host: a, stage: 0 } }, + compile::Assemble { output_compiler: Compiler { host: a, stage: 1 } }, + compile::Assemble { output_compiler: Compiler { host: a, stage: 2 } }, + compile::Assemble { output_compiler: Compiler { host: b, stage: 2 } }, ] ); } @@ -713,9 +713,9 @@ mod dist { assert_eq!( first(builder.cache.all::()), &[ - compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } }, + compile::Assemble { output_compiler: Compiler { host: a, stage: 0 } }, + compile::Assemble { output_compiler: Compiler { host: a, stage: 1 } }, + compile::Assemble { output_compiler: Compiler { host: a, stage: 2 } }, ] ); assert_eq!( diff --git a/src/tools/rust-analyzer/crates/base-db/Cargo.toml b/src/tools/rust-analyzer/crates/base-db/Cargo.toml index 788ceb8857e97..cdff5578554a8 100644 --- a/src/tools/rust-analyzer/crates/base-db/Cargo.toml +++ b/src/tools/rust-analyzer/crates/base-db/Cargo.toml @@ -30,5 +30,8 @@ vfs.workspace = true span.workspace = true intern.workspace = true +[features] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs index c7e4168f6bc8b..004f915ff3c98 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs @@ -1,4 +1,9 @@ //! base_db defines basic database traits. The concrete DB is defined by ide. + +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; + // FIXME: Rename this crate, base db is non descriptive mod change; mod input; diff --git a/src/tools/rust-analyzer/crates/cfg/Cargo.toml b/src/tools/rust-analyzer/crates/cfg/Cargo.toml index 040bddbd7fd3a..8ea0a820a635a 100644 --- a/src/tools/rust-analyzer/crates/cfg/Cargo.toml +++ b/src/tools/rust-analyzer/crates/cfg/Cargo.toml @@ -33,5 +33,9 @@ derive_arbitrary = "1.3.2" syntax-bridge.workspace = true syntax.workspace = true +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/cfg/src/lib.rs b/src/tools/rust-analyzer/crates/cfg/src/lib.rs index 6a6213a871fda..2945ec8059015 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/lib.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/lib.rs @@ -1,5 +1,9 @@ //! cfg defines conditional compiling options, `cfg` attribute parser and evaluator +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; + mod cfg_expr; mod dnf; #[cfg(test)] diff --git a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml index 375f18d9fe1f8..9de8f6457334b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml @@ -54,6 +54,7 @@ expect-test.workspace = true test-utils.workspace = true test-fixture.workspace = true syntax-bridge.workspace = true + [features] in-rust-tree = ["hir-expand/in-rust-tree"] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index c8efd9043203b..45c59764937c6 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -8,6 +8,8 @@ //! actually true. #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; #[cfg(feature = "in-rust-tree")] extern crate rustc_parse_format; diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs index 2c664029f615c..31e55615c43d2 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs @@ -3,8 +3,13 @@ //! Specifically, it implements a concept of `MacroFile` -- a file whose syntax //! tree originates not from the text of some `FileId`, but from some macro //! expansion. + #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg_attr(all(feature = "in-rust-tree", test), allow(unused_extern_crates))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver; + pub mod attrs; pub mod builtin; pub mod change; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 55d81875a2be4..1ae23f6f7cc46 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -2,6 +2,8 @@ //! information and various assists. #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; #[cfg(feature = "in-rust-tree")] extern crate rustc_index; diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 56090bc6b6057..f4686f3fe9b23 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -17,9 +17,12 @@ //! from the ide with completions, hovers, etc. It is a (soft, internal) boundary: //! . -#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] #![recursion_limit = "512"] +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; + mod attrs; mod from_id; mod has_source; diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs index 5c95b25f28ddf..eb7319594644e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs @@ -59,6 +59,8 @@ //! #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; mod assist_config; mod assist_context; diff --git a/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml b/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml index 1bef82af5ac9e..00a7f69d4c460 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml @@ -36,5 +36,9 @@ expect-test = "1.4.0" test-utils.workspace = true test-fixture.workspace = true +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs index a1f2eaeb1b6d6..eee2d2fa2b2ad 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs @@ -1,5 +1,9 @@ //! `completions` crate provides utilities for generating completions of user input. +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; + mod completions; mod config; mod context; diff --git a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml index 17f0e69bde4f1..d558772ba7245 100644 --- a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml @@ -49,5 +49,9 @@ expect-test = "1.4.0" test-utils.workspace = true test-fixture.workspace = true +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs index 3a29232d331fc..1ac33b525f360 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs @@ -2,6 +2,10 @@ //! //! It is mainly a `HirDatabase` for semantic analysis, plus a `SymbolsDatabase`, for fuzzy search. +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; + mod apply_change; pub mod active_parameter; diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml b/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml index 281a08e5429f6..1d8dbbb4a3e64 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml @@ -34,5 +34,9 @@ expect-test = "1.4.0" test-utils.workspace = true test-fixture.workspace = true +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs index 50c91a69602c1..7e2bbf29fd696 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs @@ -23,6 +23,10 @@ //! There are also a couple of ad-hoc diagnostics implemented directly here, we //! don't yet have a great pattern for how to do them properly. +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; + mod handlers { pub(crate) mod await_outside_of_async; pub(crate) mod break_outside_of_loop; diff --git a/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml b/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml index 256146762888d..fb12551853d2b 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml +++ b/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml @@ -32,5 +32,9 @@ expect-test = "1.4.0" test-utils.workspace = true test-fixture.workspace = true +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs index 889258c94c535..5e6d992ae9bce 100644 --- a/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide-ssr/src/lib.rs @@ -3,6 +3,10 @@ //! Allows searching the AST for code that matches one or more patterns and then replacing that code //! based on a template. +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; + // Feature: Structural Search and Replace // // Search and replace with named wildcards that will match any expression, type, path, pattern or item. diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index e942f5a6aac78..0950381900db4 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -9,9 +9,12 @@ // For proving that RootDatabase is RefUnwindSafe. -#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] #![recursion_limit = "128"] +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; + #[cfg(test)] mod fixture; diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index 5654c04a59287..49a857ed9806e 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -1,5 +1,10 @@ //! Loads a Cargo project into a static instance of analysis, without support //! for incorporating changes. + +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; + // Note, don't remove any public api from this. This API is consumed by external tools // to run rust-analyzer as a library. use std::{collections::hash_map::Entry, iter, mem, path::Path, sync}; diff --git a/src/tools/rust-analyzer/crates/mbe/src/lib.rs b/src/tools/rust-analyzer/crates/mbe/src/lib.rs index bebd29ef74700..4ef4d8c818ecd 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/lib.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/lib.rs @@ -7,6 +7,8 @@ //! `hir_def::macro_expansion_tests::mbe`. #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_lexer as rustc_lexer; diff --git a/src/tools/rust-analyzer/crates/parser/src/lib.rs b/src/tools/rust-analyzer/crates/parser/src/lib.rs index e461492cc6f95..00b033670210a 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lib.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lib.rs @@ -18,7 +18,10 @@ //! [`Parser`]: crate::parser::Parser #![allow(rustdoc::private_intra_doc_links)] + #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_lexer as rustc_lexer; diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml index dac8e09435762..bbe72e23642b0 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml @@ -29,5 +29,9 @@ span = { path = "../span", version = "0.0.0", default-features = false} intern.workspace = true +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index dc3328ebcda48..ddf182c34ff15 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -5,6 +5,10 @@ //! is used to provide basic infrastructure for communication between two //! processes: Client (RA itself), Server (the external program) +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; + pub mod legacy_protocol { pub mod json; pub mod msg; diff --git a/src/tools/rust-analyzer/crates/project-model/Cargo.toml b/src/tools/rust-analyzer/crates/project-model/Cargo.toml index ed647950e663c..b829da2a0abe1 100644 --- a/src/tools/rust-analyzer/crates/project-model/Cargo.toml +++ b/src/tools/rust-analyzer/crates/project-model/Cargo.toml @@ -37,5 +37,9 @@ toolchain.workspace = true [dev-dependencies] expect-test = "1.4.0" +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/project-model/src/lib.rs b/src/tools/rust-analyzer/crates/project-model/src/lib.rs index fc1fd7b877fcc..59e465382fcc1 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/lib.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/lib.rs @@ -15,6 +15,10 @@ //! procedural macros). //! * Lowering of concrete model to a [`base_db::CrateGraph`] +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; + pub mod project_json; pub mod toolchain_info { pub mod rustc_cfg; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs index 1221f7c7012e7..7f1bcec3d258c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs @@ -9,6 +9,10 @@ //! The `cli` submodule implements some batch-processing analysis, primarily as //! a debugging aid. +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; + pub mod cli; mod command; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs index 2b3c0a47a220d..0870c0b49c89b 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs @@ -10,6 +10,12 @@ #![allow(clippy::disallowed_types)] +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg_attr(all(feature = "in-rust-tree", test), allow(unused_extern_crates))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver; + mod cli; mod ratoml; mod support; diff --git a/src/tools/rust-analyzer/crates/span/Cargo.toml b/src/tools/rust-analyzer/crates/span/Cargo.toml index 097a056c99a45..0dbe65d1ba390 100644 --- a/src/tools/rust-analyzer/crates/span/Cargo.toml +++ b/src/tools/rust-analyzer/crates/span/Cargo.toml @@ -24,6 +24,7 @@ stdx.workspace = true [features] default = ["ra-salsa"] +in-rust-tree = [] [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/span/src/lib.rs b/src/tools/rust-analyzer/crates/span/src/lib.rs index 8dc957350381c..4170f75bfd527 100644 --- a/src/tools/rust-analyzer/crates/span/src/lib.rs +++ b/src/tools/rust-analyzer/crates/span/src/lib.rs @@ -1,4 +1,9 @@ //! File and span related types. + +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; + use std::fmt::{self, Write}; #[cfg(feature = "ra-salsa")] diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs index 19801c49e4341..39d5109559922 100644 --- a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs +++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs @@ -1,5 +1,9 @@ //! Conversions between [`SyntaxNode`] and [`tt::TokenTree`]. +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; + use std::{fmt, hash::Hash}; use intern::Symbol; diff --git a/src/tools/rust-analyzer/crates/syntax/src/lib.rs b/src/tools/rust-analyzer/crates/syntax/src/lib.rs index c9e9f468dca74..429417b11379f 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/lib.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/lib.rs @@ -20,6 +20,8 @@ //! [Swift]: #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_lexer as rustc_lexer; diff --git a/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml b/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml index 95f4cb9d67e25..af895ff82c9a5 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml +++ b/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml @@ -19,5 +19,9 @@ span.workspace = true stdx.workspace = true intern.workspace = true +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index ca596583590a6..0c51492d729be 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -1,4 +1,9 @@ //! A set of high-level utility fixture methods to use in tests. + +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; + use std::{iter, mem, str::FromStr, sync}; use base_db::{ diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs index 7705ba876e1ae..88d87bc432289 100644 --- a/src/tools/rust-analyzer/crates/tt/src/lib.rs +++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs @@ -4,6 +4,8 @@ //! The `TokenTree` is semantically a tree, but for performance reasons it is stored as a flat structure. #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(all(feature = "in-rust-tree", test))] +extern crate rustc_driver as _; #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_lexer as rustc_lexer;