From 2d7edf908d5767567d20bec2440099b317169d8d Mon Sep 17 00:00:00 2001 From: Diogo Sousa Date: Wed, 19 Sep 2018 01:09:36 +0100 Subject: [PATCH] Use full name to identify a macro in a `FileName`. Before this two macros with same name would be indistinguishable inside a `FileName`. This caused a bug in incremental compilation (see #53097) since two different macros would map out to the same `StableFilemapId`. Fixes #53097. --- src/librustc/hir/map/definitions.rs | 25 +++++++++++++++++++ src/librustc/ty/query/on_disk_cache.rs | 1 + src/librustc_metadata/creader.rs | 1 + src/librustc_metadata/cstore.rs | 5 ++++ src/librustc_metadata/cstore_impl.rs | 8 +++--- src/librustc_metadata/decoder.rs | 4 +-- src/libsyntax_pos/lib.rs | 2 +- .../edition-keywords-2018-2015-parsing.stderr | 2 +- .../edition-keywords-2018-2018-parsing.stderr | 2 +- .../local-modularized-tricky-fail-1.stderr | 2 +- src/test/ui/macro_backtrace/main.stderr | 10 ++++---- 11 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index c85cee7366055..fa4bf1511b874 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -287,6 +287,31 @@ impl DefPath { s } + /// Return filename friendly string of the DefPah with the + /// crate-prefix. + pub fn to_string_friendly(&self, crate_imported_name: F) -> String + where F: FnOnce(CrateNum) -> Symbol + { + let crate_name_str = crate_imported_name(self.krate).as_str(); + let mut s = String::with_capacity(crate_name_str.len() + self.data.len() * 16); + + write!(s, "::{}", crate_name_str).unwrap(); + + for component in &self.data { + if component.disambiguator == 0 { + write!(s, "::{}", component.data.as_interned_str()).unwrap(); + } else { + write!(s, + "{}[{}]", + component.data.as_interned_str(), + component.disambiguator) + .unwrap(); + } + } + + s + } + /// Return filename friendly string of the DefPah without /// the crate-prefix. This method is useful if you don't have /// a TyCtxt available. diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 0e4d2f1f64730..296602e21bad7 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -606,6 +606,7 @@ impl<'a, 'tcx, 'x> SpecializedDecoder for CacheDecoder<'a, ' alloc_decoding_session.decode_alloc_id(self) } } + impl<'a, 'tcx, 'x> SpecializedDecoder for CacheDecoder<'a, 'tcx, 'x> { fn specialized_decode(&mut self) -> Result { let tag: u8 = Decodable::decode(self)?; diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 6eef2397f9c6e..fa2debf2c0dc7 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -256,6 +256,7 @@ impl<'a> CrateLoader<'a> { let cmeta = cstore::CrateMetadata { name: crate_root.name, + imported_name: ident, extern_crate: Lock::new(None), def_path_table: Lrc::new(def_path_table), trait_impls, diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index aad632f89180d..ec48a4a4c6997 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -53,8 +53,13 @@ pub struct ImportedSourceFile { } pub struct CrateMetadata { + /// Original name of the crate. pub name: Symbol, + /// Name of the crate as imported. I.e. if imported with + /// `extern crate foo as bar;` this will be `bar`. + pub imported_name: Symbol, + /// Information about the extern crate that caused this crate to /// be loaded. If this is `None`, then the crate was injected /// (e.g., by the allocator) diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index d2285e8cbf1be..1236857826c1c 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -447,8 +447,7 @@ impl cstore::CStore { let data = self.get_crate_data(id.krate); if let Some(ref proc_macros) = data.proc_macros { return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone()); - } else if data.name == "proc_macro" && - self.get_crate_data(id.krate).item_name(id.index) == "quote" { + } else if data.name == "proc_macro" && data.item_name(id.index) == "quote" { use syntax::ext::base::SyntaxExtension; use syntax_ext::proc_macro_impl::BangProcMacro; @@ -460,8 +459,9 @@ impl cstore::CStore { return LoadedMacro::ProcMacro(Lrc::new(ext)); } - let (name, def) = data.get_macro(id.index); - let source_name = FileName::Macros(name.to_string()); + let def = data.get_macro(id.index); + let macro_full_name = data.def_path(id.index).to_string_friendly(|_| data.imported_name); + let source_name = FileName::Macros(macro_full_name); let source_file = sess.parse_sess.source_map().new_source_file(source_name, def.body); let local_span = Span::new(source_file.start_pos, source_file.end_pos, NO_EXPANSION); diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 9907df7ed0240..3f93bfcc3ae22 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -1069,10 +1069,10 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_macro(&self, id: DefIndex) -> (InternedString, MacroDef) { + pub fn get_macro(&self, id: DefIndex) -> MacroDef { let entry = self.entry(id); match entry.kind { - EntryKind::MacroDef(macro_def) => (self.item_name(id), macro_def.decode(self)), + EntryKind::MacroDef(macro_def) => macro_def.decode(self), _ => bug!(), } } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index bd70344b01812..67fd847a2ae91 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -87,7 +87,7 @@ scoped_thread_local!(pub static GLOBALS: Globals); #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, RustcDecodable, RustcEncodable)] pub enum FileName { Real(PathBuf), - /// e.g. "std" macros + /// A macro. This includes the full name of the macro, so that there are no clashes. Macros(String), /// call to `quote!` QuoteExpansion, diff --git a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr index 02e7d5b7cd01c..5955410aa106b 100644 --- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr @@ -23,7 +23,7 @@ LL | r#async = consumes_async_raw!(async); //~ ERROR no rules expected the t | ^^^^^ error: expected one of `move`, `|`, or `||`, found `` - --> :1:22 + --> <::edition_kw_macro_2015::passes_ident macros>:1:22 | LL | ( $ i : ident ) => ( $ i ) | ^^^ expected one of `move`, `|`, or `||` here diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr index 435e395c2910e..6ea736828f907 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr @@ -23,7 +23,7 @@ LL | r#async = consumes_async_raw!(async); //~ ERROR no rules expected the t | ^^^^^ error: expected one of `move`, `|`, or `||`, found `` - --> :1:22 + --> <::edition_kw_macro_2018::passes_ident macros>:1:22 | LL | ( $ i : ident ) => ( $ i ) | ^^^ expected one of `move`, `|`, or `||` here diff --git a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr index cce1fd30f1d6d..9c475451ce32f 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr +++ b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr @@ -60,7 +60,7 @@ LL | define_panic!(); = note: macro-expanded macros do not shadow error[E0659]: `panic` is ambiguous - --> :1:13 + --> <::std::macros::panic macros>:1:13 | LL | ( ) => ( { panic ! ( "explicit panic" ) } ) ; ( $ msg : expr ) => ( | ^^^^^ ambiguous name diff --git a/src/test/ui/macro_backtrace/main.stderr b/src/test/ui/macro_backtrace/main.stderr index 10eabca63538d..8cecef508a2b2 100644 --- a/src/test/ui/macro_backtrace/main.stderr +++ b/src/test/ui/macro_backtrace/main.stderr @@ -22,7 +22,7 @@ LL | | } LL | ping!(); | -------- in this macro invocation | - ::: :1:1 + ::: <::ping::ping macros>:1:1 | LL | ( ) => { pong ! ( ) ; } | ------------------------- @@ -42,7 +42,7 @@ LL | | } LL | deep!(); | -------- in this macro invocation (#1) | - ::: :1:1 + ::: <::ping::deep macros>:1:1 | LL | ( ) => { foo ! ( ) ; } | ------------------------ @@ -50,7 +50,7 @@ LL | ( ) => { foo ! ( ) ; } | | in this macro invocation (#2) | in this expansion of `deep!` (#1) | - ::: :1:1 + ::: <::ping::foo macros>:1:1 | LL | ( ) => { bar ! ( ) ; } | ------------------------ @@ -58,7 +58,7 @@ LL | ( ) => { bar ! ( ) ; } | | in this macro invocation (#3) | in this expansion of `foo!` (#2) | - ::: :1:1 + ::: <::ping::bar macros>:1:1 | LL | ( ) => { ping ! ( ) ; } | ------------------------- @@ -66,7 +66,7 @@ LL | ( ) => { ping ! ( ) ; } | | in this macro invocation (#4) | in this expansion of `bar!` (#3) | - ::: :1:1 + ::: <::ping::ping macros>:1:1 | LL | ( ) => { pong ! ( ) ; } | -------------------------