diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 354023cea9e07..67495461d69ca 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1726,6 +1726,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { // on `try_to_translate_virtual_to_real`). try_to_translate_virtual_to_real(&mut name); + // We may have had different remap-path-prefix flags at the time this file was loaded. + // Apply the remapping for the current session. + // NOTE: this does not "undo and redo" the mapping - any existing remapping from the old + // crate is retained unmodified. Only files which were never remapped are considered. + name = sess.source_map().path_mapping().map_filename_prefix(&name); + let local_version = sess.source_map().new_imported_source_file( name, src_hash, diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index dcf346acb334e..9af3351ad8b2e 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -320,7 +320,7 @@ impl SourceMap { // Note that filename may not be a valid path, eg it may be `` etc, // but this is okay because the directory determined by `path.pop()` will // be empty, so the working directory will be used. - let (filename, _) = self.path_mapping.map_filename_prefix(&filename); + let filename = self.path_mapping.map_filename_prefix(&filename); let file_id = StableSourceFileId::new_from_name(&filename, LOCAL_CRATE); match self.source_file_by_stable_id(file_id) { @@ -995,7 +995,7 @@ impl SourceMap { pub fn get_source_file(&self, filename: &FileName) -> Option> { // Remap filename before lookup - let filename = self.path_mapping().map_filename_prefix(filename).0; + let filename = self.path_mapping().map_filename_prefix(filename); for sf in self.files.borrow().source_files.iter() { if filename == sf.name { return Some(sf.clone()); @@ -1147,9 +1147,12 @@ impl FilePathMapping { } } - fn map_filename_prefix(&self, file: &FileName) -> (FileName, bool) { + /// Given a `file`, map it using the `remap-path-prefix` options for the current `Session`. + /// + /// Public for use in rustc_metadata::decoder + pub fn map_filename_prefix(&self, file: &FileName) -> FileName { match file { - FileName::Real(realfile) if let RealFileName::LocalPath(local_path) = realfile => { + FileName::Real(realfile @ RealFileName::LocalPath(local_path)) => { let (mapped_path, mapped) = self.map_prefix(local_path); let realfile = if mapped { RealFileName::Remapped { @@ -1159,10 +1162,16 @@ impl FilePathMapping { } else { realfile.clone() }; - (FileName::Real(realfile), mapped) + FileName::Real(realfile) + } + existing @ FileName::Real(RealFileName::Remapped { .. }) => { + // This can happen if we are remapping the name of file that was loaded in a + // different Session, and inconsistent `remap-path-prefix` flags were passed between + // sessions. It's unclear what to do here. For now, respect the original flag, not + // the flag from the current session. + existing.clone() } - FileName::Real(_) => unreachable!("attempted to remap an already remapped filename"), - other => (other.clone(), false), + other => other.clone(), } } diff --git a/tests/run-make/remap-path-prefix-inconsistent/Makefile b/tests/run-make/remap-path-prefix-inconsistent/Makefile new file mode 100644 index 0000000000000..47d10ea645bf0 --- /dev/null +++ b/tests/run-make/remap-path-prefix-inconsistent/Makefile @@ -0,0 +1,25 @@ + +include ../tools.mk + +all: inconsistent-mapping last-crate-only remap-scope + +last-crate-only: + $(RUSTC) is_true.rs --crate-type lib + $(RUSTC) main.rs --remap-path-prefix=$(CURDIR)=/TEST_DIR 2>$(TMPDIR)/last-crate.txt --extern is_true=$(TMPDIR)/libis_true.rlib || true + $(RUSTC_TEST_OP) $(TMPDIR)/last-crate.txt expected-last-crate.txt + $(CGREP) "/TEST_DIR" < $(TMPDIR)/last-crate.txt + +# exactly like `last-crate-only`, but also uses `-Z remap-path-scope=diagnostics` +remap-scope: + $(RUSTC) is_true.rs --crate-type lib + $(RUSTC) main.rs -Z remap-path-scope=diagnostics --remap-path-prefix=$(CURDIR)=/TEST_DIR 2>$(TMPDIR)/last-crate.txt --extern is_true=$(TMPDIR)/libis_true.rlib || true + $(RUSTC_TEST_OP) $(TMPDIR)/last-crate.txt expected-last-crate.txt + $(CGREP) "/TEST_DIR" < $(TMPDIR)/last-crate.txt + # Now again, but excluding diagnostics + $(RUSTC) main.rs -Z remap-path-scope=object --remap-path-prefix=$(CURDIR)=/TEST_DIR --extern is_true=$(TMPDIR)/libis_true.rlib 2>&1 | $(CGREP) tests/run-make/ + +inconsistent-mapping: + $(RUSTC) is_true.rs --remap-path-prefix=$(CURDIR)=/TEST_DIR1 --crate-type lib + $(RUSTC) main.rs --remap-path-prefix=$(CURDIR)=/TEST_DIR2 2>$(TMPDIR)/inconsistent.txt --extern is_true=$(TMPDIR)/libis_true.rlib || true + $(RUSTC_TEST_OP) $(TMPDIR)/inconsistent.txt expected-inconsistent.txt + $(CGREP) "/TEST_DIR1" < $(TMPDIR)/inconsistent.txt diff --git a/tests/run-make/remap-path-prefix-inconsistent/expected-inconsistent.txt b/tests/run-make/remap-path-prefix-inconsistent/expected-inconsistent.txt new file mode 100644 index 0000000000000..f88eede6320b3 --- /dev/null +++ b/tests/run-make/remap-path-prefix-inconsistent/expected-inconsistent.txt @@ -0,0 +1,16 @@ +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> main.rs:2:5 + | +2 | is_true::query(); + | ^^^^^^^^^^^^^^-- an argument of type `bool` is missing + | +note: function defined here + --> /TEST_DIR1/is_true.rs:1:8 +help: provide the argument + | +2 | is_true::query(/* bool */); + | ~~~~~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0061`. diff --git a/tests/run-make/remap-path-prefix-inconsistent/expected-last-crate.txt b/tests/run-make/remap-path-prefix-inconsistent/expected-last-crate.txt new file mode 100644 index 0000000000000..239b9297c5e9c --- /dev/null +++ b/tests/run-make/remap-path-prefix-inconsistent/expected-last-crate.txt @@ -0,0 +1,19 @@ +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> main.rs:2:5 + | +2 | is_true::query(); + | ^^^^^^^^^^^^^^-- an argument of type `bool` is missing + | +note: function defined here + --> /TEST_DIR/is_true.rs:1:8 + | +1 | pub fn query(_: bool) {} + | ^^^^^ +help: provide the argument + | +2 | is_true::query(/* bool */); + | ~~~~~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0061`. diff --git a/tests/run-make/remap-path-prefix-inconsistent/is_true.rs b/tests/run-make/remap-path-prefix-inconsistent/is_true.rs new file mode 100644 index 0000000000000..93153ce588232 --- /dev/null +++ b/tests/run-make/remap-path-prefix-inconsistent/is_true.rs @@ -0,0 +1 @@ +pub fn query(_: bool) {} diff --git a/tests/run-make/remap-path-prefix-inconsistent/main.rs b/tests/run-make/remap-path-prefix-inconsistent/main.rs new file mode 100644 index 0000000000000..169371a198413 --- /dev/null +++ b/tests/run-make/remap-path-prefix-inconsistent/main.rs @@ -0,0 +1,3 @@ +fn main() { + is_true::query(); +}