From c27a82f19352f37a6b04d7733d28c84494c3afd4 Mon Sep 17 00:00:00 2001 From: Philip Craig Date: Sat, 30 Sep 2017 16:28:48 +1000 Subject: [PATCH 1/3] Don't use remapped path when loading modules and include files --- src/librustc/ich/impls_syntax.rs | 1 + src/librustc/session/mod.rs | 4 +--- src/libsyntax/codemap.rs | 16 ++++++++++++++-- src/libsyntax/ext/expand.rs | 6 ++---- src/libsyntax/ext/source_util.rs | 2 +- src/libsyntax/parse/parser.rs | 2 +- src/libsyntax_pos/lib.rs | 6 ++++++ src/test/codegen/remap_path_prefix/aux_mod.rs | 16 ++++++++++++++++ src/test/codegen/remap_path_prefix/main.rs | 7 +++++++ 9 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 src/test/codegen/remap_path_prefix/aux_mod.rs diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 669e1ba773e..87e41d30e5d 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -354,6 +354,7 @@ impl<'gcx> HashStable> for FileMap { let FileMap { ref name, name_was_remapped, + path: _, crate_of_origin, // Do not hash the source as it is not encoded src: _, diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index e87443619ec..bd6e5eb67c8 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -68,8 +68,7 @@ pub struct Session { pub derive_registrar_fn: Cell>, pub default_sysroot: Option, // The name of the root source file of the crate, in the local file system. - // The path is always expected to be absolute. `None` means that there is no - // source file. + // `None` means that there is no source file. pub local_crate_source_file: Option, // The directory the compiler has been executed in plus a flag indicating // if the value stored here has been affected by path remapping. @@ -722,7 +721,6 @@ pub fn build_session_(sopts: config::Options, let file_path_mapping = sopts.file_path_mapping(); - // Make the path absolute, if necessary let local_crate_source_file = local_crate_source_file.map(|path| { file_path_mapping.map_prefix(path.to_string_lossy().into_owned()).0 }); diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index cd4a6f921fe..79262580858 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -162,9 +162,16 @@ impl CodeMap { let start_pos = self.next_start_pos(); let mut files = self.files.borrow_mut(); + // The path is used to determine the directory for loading submodules and + // include files, so it must be before remapping. + // 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 path = PathBuf::from(filename.clone()); + let (filename, was_remapped) = self.path_mapping.map_prefix(filename); let filemap = - Rc::new(FileMap::new(filename, was_remapped, src, Pos::from_usize(start_pos))); + Rc::new(FileMap::new(filename, was_remapped, path, src, Pos::from_usize(start_pos))); files.push(filemap.clone()); @@ -216,6 +223,7 @@ impl CodeMap { let filemap = Rc::new(FileMap { name: filename, name_was_remapped, + path: PathBuf::new(), crate_of_origin, src: None, src_hash, @@ -342,7 +350,11 @@ impl CodeMap { } pub fn span_to_filename(&self, sp: Span) -> FileName { - self.lookup_char_pos(sp.lo()).file.name.to_string() + self.lookup_char_pos(sp.lo()).file.name.clone() + } + + pub fn span_to_path(&self, sp: Span) -> PathBuf { + self.lookup_char_pos(sp.lo()).file.path.clone() } pub fn span_to_lines(&self, sp: Span) -> FileLinesResult { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 6e7a8203b61..c4727b6eda5 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -35,7 +35,6 @@ use visit::Visitor; use std::collections::HashMap; use std::mem; -use std::path::PathBuf; use std::rc::Rc; macro_rules! expansions { @@ -200,7 +199,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.cx.crate_root = std_inject::injected_crate_name(&krate); let mut module = ModuleData { mod_path: vec![Ident::from_str(&self.cx.ecfg.crate_name)], - directory: PathBuf::from(self.cx.codemap().span_to_filename(krate.span)), + directory: self.cx.codemap().span_to_path(krate.span), }; module.directory.pop(); self.cx.current_expansion.module = Rc::new(module); @@ -952,8 +951,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { module.directory.push(&*item.ident.name.as_str()); } } else { - let mut path = - PathBuf::from(self.cx.parse_sess.codemap().span_to_filename(inner)); + let mut path = self.cx.parse_sess.codemap().span_to_path(inner); let directory_ownership = match path.file_name().unwrap().to_str() { Some("mod.rs") => DirectoryOwnership::Owned, _ => DirectoryOwnership::UnownedViaMod(false), diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 18a262d139a..8bc7f055676 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -197,7 +197,7 @@ fn res_rel_file(cx: &mut ExtCtxt, sp: syntax_pos::Span, arg: &Path) -> PathBuf { // after macro expansion (that is, they are unhygienic). if !arg.is_absolute() { let callsite = sp.source_callsite(); - let mut path = PathBuf::from(&cx.codemap().span_to_filename(callsite)); + let mut path = cx.codemap().span_to_path(callsite); path.pop(); path.push(arg); path diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d5ba4b54d90..bd1d4241be0 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -525,7 +525,7 @@ impl<'a> Parser<'a> { if let Some(directory) = directory { parser.directory = directory; } else if parser.span != syntax_pos::DUMMY_SP { - parser.directory.path = PathBuf::from(sess.codemap().span_to_filename(parser.span)); + parser.directory.path = sess.codemap().span_to_path(parser.span); parser.directory.path.pop(); } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 582f2798181..0d910cc04f6 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -32,6 +32,7 @@ use std::cmp::{self, Ordering}; use std::fmt; use std::hash::Hasher; use std::ops::{Add, Sub}; +use std::path::PathBuf; use std::rc::Rc; use rustc_data_structures::stable_hasher::StableHasher; @@ -501,6 +502,8 @@ pub struct FileMap { pub name: FileName, /// True if the `name` field above has been modified by -Zremap-path-prefix pub name_was_remapped: bool, + /// The path of the file that the source came from. + pub path: PathBuf, /// Indicates which crate this FileMap was imported from. pub crate_of_origin: u32, /// The complete source code @@ -626,6 +629,7 @@ impl Decodable for FileMap { Ok(FileMap { name, name_was_remapped, + path: PathBuf::new(), // `crate_of_origin` has to be set by the importer. // This value matches up with rustc::hir::def_id::INVALID_CRATE. // That constant is not available here unfortunately :( @@ -651,6 +655,7 @@ impl fmt::Debug for FileMap { impl FileMap { pub fn new(name: FileName, name_was_remapped: bool, + path: PathBuf, mut src: String, start_pos: BytePos) -> FileMap { remove_bom(&mut src); @@ -664,6 +669,7 @@ impl FileMap { FileMap { name, name_was_remapped, + path, crate_of_origin: 0, src: Some(Rc::new(src)), src_hash, diff --git a/src/test/codegen/remap_path_prefix/aux_mod.rs b/src/test/codegen/remap_path_prefix/aux_mod.rs new file mode 100644 index 00000000000..2a7019957af --- /dev/null +++ b/src/test/codegen/remap_path_prefix/aux_mod.rs @@ -0,0 +1,16 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-test: this is not a test + +#[inline] +pub fn some_aux_mod_function() -> i32 { + 1234 +} diff --git a/src/test/codegen/remap_path_prefix/main.rs b/src/test/codegen/remap_path_prefix/main.rs index eb00c91ba5f..c73739bb765 100644 --- a/src/test/codegen/remap_path_prefix/main.rs +++ b/src/test/codegen/remap_path_prefix/main.rs @@ -16,12 +16,19 @@ extern crate remap_path_prefix_aux; +// Here we check that submodules and include files are found using the path without +// remapping. This test requires that rustc is called with an absolute path. +mod aux_mod; +include!("aux_mod.rs"); + // Here we check that the expansion of the file!() macro is mapped. // CHECK: internal constant [34 x i8] c"/the/src/remap_path_prefix/main.rs" pub static FILE_PATH: &'static str = file!(); fn main() { remap_path_prefix_aux::some_aux_function(); + aux_mod::some_aux_mod_function(); + some_aux_mod_function(); } // Here we check that local debuginfo is mapped correctly. From 3a225c77bba8576333924e7435493cb4d4e0cbaf Mon Sep 17 00:00:00 2001 From: Philip Craig Date: Tue, 3 Oct 2017 19:44:58 +1000 Subject: [PATCH 2/3] Rename FileMap::path and change to an Option --- src/librustc/ich/impls_syntax.rs | 2 +- src/libsyntax/codemap.rs | 18 ++++++++++++------ src/libsyntax/ext/expand.rs | 4 ++-- src/libsyntax/ext/source_util.rs | 2 +- src/libsyntax/parse/parser.rs | 2 +- src/libsyntax_pos/lib.rs | 11 ++++++----- 6 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 87e41d30e5d..799e790b85f 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -354,7 +354,7 @@ impl<'gcx> HashStable> for FileMap { let FileMap { ref name, name_was_remapped, - path: _, + unmapped_path: _, crate_of_origin, // Do not hash the source as it is not encoded src: _, diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 79262580858..efaa5e5e3da 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -167,11 +167,16 @@ impl CodeMap { // 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 path = PathBuf::from(filename.clone()); + let unmapped_path = PathBuf::from(filename.clone()); let (filename, was_remapped) = self.path_mapping.map_prefix(filename); - let filemap = - Rc::new(FileMap::new(filename, was_remapped, path, src, Pos::from_usize(start_pos))); + let filemap = Rc::new(FileMap::new( + filename, + was_remapped, + unmapped_path, + src, + Pos::from_usize(start_pos), + )); files.push(filemap.clone()); @@ -223,7 +228,7 @@ impl CodeMap { let filemap = Rc::new(FileMap { name: filename, name_was_remapped, - path: PathBuf::new(), + unmapped_path: None, crate_of_origin, src: None, src_hash, @@ -353,8 +358,9 @@ impl CodeMap { self.lookup_char_pos(sp.lo()).file.name.clone() } - pub fn span_to_path(&self, sp: Span) -> PathBuf { - self.lookup_char_pos(sp.lo()).file.path.clone() + pub fn span_to_unmapped_path(&self, sp: Span) -> PathBuf { + self.lookup_char_pos(sp.lo()).file.unmapped_path.clone() + .expect("CodeMap::span_to_unmapped_path called for imported FileMap?") } pub fn span_to_lines(&self, sp: Span) -> FileLinesResult { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index c4727b6eda5..614c4a10e6d 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -199,7 +199,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.cx.crate_root = std_inject::injected_crate_name(&krate); let mut module = ModuleData { mod_path: vec![Ident::from_str(&self.cx.ecfg.crate_name)], - directory: self.cx.codemap().span_to_path(krate.span), + directory: self.cx.codemap().span_to_unmapped_path(krate.span), }; module.directory.pop(); self.cx.current_expansion.module = Rc::new(module); @@ -951,7 +951,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { module.directory.push(&*item.ident.name.as_str()); } } else { - let mut path = self.cx.parse_sess.codemap().span_to_path(inner); + let mut path = self.cx.parse_sess.codemap().span_to_unmapped_path(inner); let directory_ownership = match path.file_name().unwrap().to_str() { Some("mod.rs") => DirectoryOwnership::Owned, _ => DirectoryOwnership::UnownedViaMod(false), diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 8bc7f055676..86657e675b2 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -197,7 +197,7 @@ fn res_rel_file(cx: &mut ExtCtxt, sp: syntax_pos::Span, arg: &Path) -> PathBuf { // after macro expansion (that is, they are unhygienic). if !arg.is_absolute() { let callsite = sp.source_callsite(); - let mut path = cx.codemap().span_to_path(callsite); + let mut path = cx.codemap().span_to_unmapped_path(callsite); path.pop(); path.push(arg); path diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index bd1d4241be0..65dabe98a06 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -525,7 +525,7 @@ impl<'a> Parser<'a> { if let Some(directory) = directory { parser.directory = directory; } else if parser.span != syntax_pos::DUMMY_SP { - parser.directory.path = sess.codemap().span_to_path(parser.span); + parser.directory.path = sess.codemap().span_to_unmapped_path(parser.span); parser.directory.path.pop(); } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 0d910cc04f6..2000db9703c 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -502,8 +502,9 @@ pub struct FileMap { pub name: FileName, /// True if the `name` field above has been modified by -Zremap-path-prefix pub name_was_remapped: bool, - /// The path of the file that the source came from. - pub path: PathBuf, + /// The unmapped path of the file that the source came from. + /// Set to `None` if the FileMap was imported from an external crate. + pub unmapped_path: Option, /// Indicates which crate this FileMap was imported from. pub crate_of_origin: u32, /// The complete source code @@ -629,7 +630,7 @@ impl Decodable for FileMap { Ok(FileMap { name, name_was_remapped, - path: PathBuf::new(), + unmapped_path: None, // `crate_of_origin` has to be set by the importer. // This value matches up with rustc::hir::def_id::INVALID_CRATE. // That constant is not available here unfortunately :( @@ -655,7 +656,7 @@ impl fmt::Debug for FileMap { impl FileMap { pub fn new(name: FileName, name_was_remapped: bool, - path: PathBuf, + unmapped_path: PathBuf, mut src: String, start_pos: BytePos) -> FileMap { remove_bom(&mut src); @@ -669,7 +670,7 @@ impl FileMap { FileMap { name, name_was_remapped, - path, + unmapped_path: Some(unmapped_path), crate_of_origin: 0, src: Some(Rc::new(src)), src_hash, From 9bbd7a3b3f2f713220f429bd15466135efa7f3b7 Mon Sep 17 00:00:00 2001 From: Philip Craig Date: Tue, 3 Oct 2017 20:35:55 +1000 Subject: [PATCH 3/3] Add fixme regarding remapping paths for doctests --- src/librustdoc/test.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 7fa1b38bdad..5ce73d38fdf 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -184,6 +184,8 @@ fn run_test(test: &str, cratename: &str, filename: &str, cfgs: Vec, libs // the test harness wants its own `main` & top level functions, so // never wrap the test in `fn main() { ... }` let test = make_test(test, Some(cratename), as_test_harness, opts); + // FIXME(#44940): if doctests ever support path remapping, then this filename + // needs to be the result of CodeMap::span_to_unmapped_path let input = config::Input::Str { name: filename.to_owned(), input: test.to_owned(),