diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 2f1c78197275d..1d7971b8d5d9d 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -5,6 +5,7 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![feature(absolute_path)] #![feature(lazy_cell)] #![feature(decl_macro)] #![recursion_limit = "256"] @@ -303,7 +304,11 @@ fn run_compiler( registry: diagnostics_registry(), }; - match make_input(config.opts.error_format, &matches.free) { + match make_input( + config.opts.error_format, + &matches.free, + config.opts.unstable_opts.absolute_file_paths, + ) { Err(reported) => return Err(reported), Ok(Some(input)) => { config.input = input; @@ -476,6 +481,7 @@ fn make_output(matches: &getopts::Matches) -> (Option, Option Result, ErrorGuaranteed> { if free_matches.len() == 1 { let ifile = &free_matches[0]; @@ -503,7 +509,19 @@ fn make_input( Ok(Some(Input::Str { name: FileName::anon_source_code(&src), input: src })) } } else { - Ok(Some(Input::File(PathBuf::from(ifile)))) + let mut path = PathBuf::from(ifile); + if absolute_file_paths { + match std::path::absolute(path) { + Ok(p) => path = p, + Err(e) => { + return Err(early_error_no_abort( + error_format, + format!("failed to convert {ifile} to an absolute path: {e}"), + )); + } + } + } + Ok(Some(Input::File(path))) } } else { Ok(None) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 9d0c9ec974231..748abe7ef0e5e 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -657,6 +657,7 @@ fn test_unstable_options_tracking_hash() { // Make sure that changing an [UNTRACKED] option leaves the hash unchanged. // tidy-alphabetical-start + untracked!(absolute_file_paths, true); untracked!(assert_incr_state, Some(String::from("loaded"))); untracked!(deduplicate_diagnostics, false); untracked!(dep_tasks, true); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index edf95949d3234..175868cdc202c 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1352,6 +1352,8 @@ options! { // - src/doc/unstable-book/src/compiler-flags // tidy-alphabetical-start + absolute_file_paths: bool = (false, parse_bool, [UNTRACKED], + "use absolute file paths in diagnostics, not relative paths (default: no)"), allow_features: Option> = (None, parse_opt_comma_list, [TRACKED], "only allow the listed language features to be enabled in code (comma separated)"), always_encode_mir: bool = (false, parse_bool, [TRACKED], diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 473fdbe1edc27..95ecc3efdc656 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -474,6 +474,7 @@ def __init__(self): self.verbose = False self.git_version = None self.nix_deps_dir = None + self.local_rebuild = False self._should_fix_bins_and_dylibs = None def download_toolchain(self): @@ -894,6 +895,10 @@ def build_bootstrap(self, color, warnings, verbose_count): if target_linker is not None: env["RUSTFLAGS"] += " -C linker=" + target_linker env["RUSTFLAGS"] += " -Wrust_2018_idioms -Wunused_lifetimes" + # Make sure that rust-analyzer can map error diagnostics to the file. + # cfg(bootstrap) + if self.local_rebuild: + env["RUSTFLAGS"] += " -Zabsolute-file-paths" if warnings == "default": deny_warnings = self.get_toml("deny-warnings", "rust") != "false" else: @@ -1054,6 +1059,17 @@ def bootstrap(args): if not os.path.exists(build.build_dir): os.makedirs(build.build_dir) + build.local_rebuild = build.get_toml("local_rebuild", "build") + if build.local_rebuild is None and not build.rustc().startswith(build.bin_root()): + with open(os.path.join(build.rust_root, "src", "version")) as f: + expected_version = f.read().split(".")[:2] + output = require([build.rustc(), "--version"]).decode(sys.getdefaultencoding()) + actual_version = output.split(" ")[1].split(".")[:2] + if expected_version == actual_version: + if build.verbose: + print("auto-detected local-rebuild {}".format(actual_version)) + build.local_rebuild = True + # Fetch/build the bootstrap build.download_toolchain() sys.stdout.flush() diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 7c8e3536df588..913ab12ec4e9d 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1392,6 +1392,11 @@ impl<'a> Builder<'a> { // cargo would implicitly add it, it was discover that sometimes bootstrap only use // `rustflags` without `cargo` making it required. rustflags.arg("-Zunstable-options"); + // Make ctrl+click, etc. work with workspaces other than the root workspace. + // cfg(bootstrap) + if stage > 0 { + rustflags.arg("-Zabsolute-file-paths"); + } for (restricted_mode, name, values) in EXTRA_CHECK_CFGS { if *restricted_mode == None || *restricted_mode == Some(mode) { // Creating a string of the values by concatenating each value: diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index d7e77aeb338f6..4602daf256e26 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -36,7 +36,7 @@ use once_cell::sync::OnceCell; use crate::builder::Kind; use crate::config::{LlvmLibunwind, TargetSelection}; use crate::util::{ - exe, libdir, mtime, output, run, run_suppressed, symlink_dir, try_run_suppressed, + absolute, exe, libdir, mtime, output, run, run_suppressed, symlink_dir, try_run_suppressed, }; mod bolt; @@ -426,8 +426,9 @@ impl Build { } let mut build = Build { - initial_rustc: config.initial_rustc.clone(), - initial_cargo: config.initial_cargo.clone(), + // Use absolute paths for these to allow setting them to e.g. build/host/stage1 + initial_rustc: absolute(&config.initial_rustc), + initial_cargo: absolute(&config.initial_cargo), initial_lld, initial_libdir, initial_sysroot: initial_sysroot.into(), diff --git a/src/doc/unstable-book/src/compiler-flags/absolute-file-paths.md b/src/doc/unstable-book/src/compiler-flags/absolute-file-paths.md new file mode 100644 index 0000000000000..74e74f3662ca0 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/absolute-file-paths.md @@ -0,0 +1,9 @@ +# `absolute-file-paths` + +This features is currently perma-unstable, with no tracking issue. + +------------------------ + +This feature allows you to configure rustc to print diagnostics and other output using absolute file paths, not relative file paths. + +Set `-Zabsolute-file-paths` to enable this feature.