From 688c11216aca1d7449b07b3ebbcee3ba114d0d51 Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Wed, 17 Jul 2019 01:16:49 +0200 Subject: [PATCH 1/6] Override Cycle::try_fold --- src/libcore/iter/adapters/mod.rs | 30 ++++++++++++++++++++++++++++++ src/libcore/tests/iter.rs | 12 ++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index c2edcd22f953b..07526e58fd7ef 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -387,6 +387,36 @@ impl Iterator for Cycle where I: Clone + Iterator { _ => (usize::MAX, None) } } + + #[inline] + fn try_fold(&mut self, mut acc: Acc, mut f: F) -> R + where + F: FnMut(Acc, Self::Item) -> R, + R: Try, + { + // fully iterate the current iterator. this is necessary because + // `self.iter` may be empty even when `self.orig` isn't + acc = self.iter.try_fold(acc, &mut f)?; + self.iter = self.orig.clone(); + + // complete a full cycle, keeping track of whether the cycled + // iterator is empty or not. we need to return early in case + // of an empty iterator to prevent an infinite loop + let mut is_empty = true; + acc = self.iter.try_fold(acc, |acc, x| { + is_empty = false; + f(acc, x) + })?; + + if is_empty { + return Try::from_ok(acc); + } + + loop { + self.iter = self.orig.clone(); + acc = self.iter.try_fold(acc, &mut f)?; + } + } } #[stable(feature = "fused", since = "1.26.0")] diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index b7b0849e2129b..194975661067c 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1015,6 +1015,18 @@ fn test_cycle() { assert_eq!(empty::().cycle().fold(0, |acc, x| acc + x), 0); assert_eq!(once(1).cycle().skip(1).take(4).fold(0, |acc, x| acc + x), 4); + + assert_eq!((0..10).cycle().take(5).sum::(), 10); + assert_eq!((0..10).cycle().take(15).sum::(), 55); + assert_eq!((0..10).cycle().take(25).sum::(), 100); + + let mut iter = (0..10).cycle(); + iter.nth(14); + assert_eq!(iter.take(8).sum::(), 38); + + let mut iter = (0..10).cycle(); + iter.nth(9); + assert_eq!(iter.take(3).sum::(), 3); } #[test] From e9e45c59a7a5a1ea500fd667a56c0d0ab101365a Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 12 Aug 2019 09:34:41 -0700 Subject: [PATCH 2/6] Hash the remapped sysroot instead of the original. This will help reproducible builds, as the sysroot depends on the working directory. --- src/librustc/session/config.rs | 11 +++++++++-- .../run-make-fulldeps/reproducible-build-2/Makefile | 12 +++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 3536b2aa8fffe..0a0f72a72c00c 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -395,7 +395,8 @@ top_level_options!( output_types: OutputTypes [TRACKED], search_paths: Vec [UNTRACKED], libs: Vec<(String, Option, Option)> [TRACKED], - maybe_sysroot: Option [TRACKED], + maybe_sysroot: Option [UNTRACKED], + maybe_sysroot_remapped: Option [TRACKED], target_triple: TargetTriple [TRACKED], @@ -610,6 +611,7 @@ impl Default for Options { output_types: OutputTypes(BTreeMap::new()), search_paths: vec![], maybe_sysroot: None, + maybe_sysroot_remapped: None, target_triple: TargetTriple::from_triple(host_triple()), test: false, incremental: None, @@ -2453,7 +2455,7 @@ pub fn build_session_options_and_crate_config( let crate_name = matches.opt_str("crate-name"); - let remap_path_prefix = matches + let remap_path_prefix: Vec<(PathBuf, PathBuf)> = matches .opt_strs("remap-path-prefix") .into_iter() .map(|remap| { @@ -2470,6 +2472,10 @@ pub fn build_session_options_and_crate_config( }) .collect(); + let sysroot_remapped_opt = sysroot_opt + .clone() + .map(|sysroot| FilePathMapping::new(remap_path_prefix.clone()).map_prefix(sysroot).0); + ( Options { crate_types, @@ -2481,6 +2487,7 @@ pub fn build_session_options_and_crate_config( output_types: OutputTypes(output_types), search_paths, maybe_sysroot: sysroot_opt, + maybe_sysroot_remapped: sysroot_remapped_opt, target_triple, test, incremental, diff --git a/src/test/run-make-fulldeps/reproducible-build-2/Makefile b/src/test/run-make-fulldeps/reproducible-build-2/Makefile index b96954fea0d1e..45c9a7427230b 100644 --- a/src/test/run-make-fulldeps/reproducible-build-2/Makefile +++ b/src/test/run-make-fulldeps/reproducible-build-2/Makefile @@ -5,7 +5,8 @@ # Objects are reproducible but their path is not. all: \ - fat_lto + fat_lto \ + sysroot fat_lto: rm -rf $(TMPDIR) && mkdir $(TMPDIR) @@ -14,3 +15,12 @@ fat_lto: cp $(TMPDIR)/reproducible-build $(TMPDIR)/reproducible-build-a $(RUSTC) reproducible-build.rs -C lto=fat cmp "$(TMPDIR)/reproducible-build-a" "$(TMPDIR)/reproducible-build" || exit 1 + +sysroot: + rm -rf $(TMPDIR) && mkdir $(TMPDIR) + $(RUSTC) reproducible-build-aux.rs + $(RUSTC) reproducible-build.rs --crate-type rlib --sysroot $(shell $(RUSTC) --print sysroot) --remap-path-prefix=$(shell $(RUSTC) --print sysroot)=/sysroot + cp -r $(shell $(RUSTC) --print sysroot) $(TMPDIR)/sysroot + cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib + $(RUSTC) reproducible-build.rs --crate-type rlib --sysroot $(TMPDIR)/sysroot --remap-path-prefix=$(TMPDIR)/sysroot=/sysroot + cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1 From 692c0bf4ff8d1f551850962bd8d3af62033dee39 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 13 Aug 2019 09:12:06 -0700 Subject: [PATCH 3/6] Do not track the sysroot. As suggested by @alexcrichton, the sysroot only loads libraries that are themselves tracked. --- src/librustc/session/config.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 0a0f72a72c00c..8e3b910e0da3a 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -396,7 +396,6 @@ top_level_options!( search_paths: Vec [UNTRACKED], libs: Vec<(String, Option, Option)> [TRACKED], maybe_sysroot: Option [UNTRACKED], - maybe_sysroot_remapped: Option [TRACKED], target_triple: TargetTriple [TRACKED], @@ -611,7 +610,6 @@ impl Default for Options { output_types: OutputTypes(BTreeMap::new()), search_paths: vec![], maybe_sysroot: None, - maybe_sysroot_remapped: None, target_triple: TargetTriple::from_triple(host_triple()), test: false, incremental: None, @@ -2455,7 +2453,7 @@ pub fn build_session_options_and_crate_config( let crate_name = matches.opt_str("crate-name"); - let remap_path_prefix: Vec<(PathBuf, PathBuf)> = matches + let remap_path_prefix = matches .opt_strs("remap-path-prefix") .into_iter() .map(|remap| { @@ -2472,10 +2470,6 @@ pub fn build_session_options_and_crate_config( }) .collect(); - let sysroot_remapped_opt = sysroot_opt - .clone() - .map(|sysroot| FilePathMapping::new(remap_path_prefix.clone()).map_prefix(sysroot).0); - ( Options { crate_types, @@ -2487,7 +2481,6 @@ pub fn build_session_options_and_crate_config( output_types: OutputTypes(output_types), search_paths, maybe_sysroot: sysroot_opt, - maybe_sysroot_remapped: sysroot_remapped_opt, target_triple, test, incremental, From c1758d5918b8c5e99b34c83e83266dc5f79b0da7 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 14 Aug 2019 18:53:22 +0300 Subject: [PATCH 4/6] rustc_codegen_utils: account for 1-indexed anonymous lifetimes in v0 mangling. --- src/librustc_codegen_utils/symbol_names/v0.rs | 12 ++++++++++-- src/test/ui/symbol-names/impl1.rs | 6 +++--- src/test/ui/symbol-names/impl1.v0.stderr | 6 +++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/librustc_codegen_utils/symbol_names/v0.rs b/src/librustc_codegen_utils/symbol_names/v0.rs index 47601da8b7b23..8d6a1d757e014 100644 --- a/src/librustc_codegen_utils/symbol_names/v0.rs +++ b/src/librustc_codegen_utils/symbol_names/v0.rs @@ -198,10 +198,14 @@ impl SymbolMangler<'tcx> { let lifetimes = regions.into_iter().map(|br| { match br { - ty::BrAnon(i) => i + 1, + ty::BrAnon(i) => { + // FIXME(eddyb) for some reason, `anonymize_late_bound_regions` starts at `1`. + assert_ne!(i, 0); + i - 1 + }, _ => bug!("symbol_names: non-anonymized region `{:?}` in `{:?}`", br, value), } - }).max().unwrap_or(0); + }).max().map_or(0, |max| max + 1); self.push_opt_integer_62("G", lifetimes as u64); lifetime_depths.end += lifetimes; @@ -297,6 +301,10 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { // Late-bound lifetimes use indices starting at 1, // see `BinderLevel` for more details. ty::ReLateBound(debruijn, ty::BrAnon(i)) => { + // FIXME(eddyb) for some reason, `anonymize_late_bound_regions` starts at `1`. + assert_ne!(i, 0); + let i = i - 1; + let binder = &self.binders[self.binders.len() - 1 - debruijn.index()]; let depth = binder.lifetime_depths.start + i; diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index 52bb118fa23a0..137b72dcd9c44 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -64,9 +64,9 @@ fn main() { //[legacy]~^ ERROR symbol-name(_ZN198_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$RP$$u2b$impl1..AutoTrait$u3b$$u20$_$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method //[legacy]~| ERROR demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method //[legacy]~| ERROR demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method) - //[v0]~^^^^ ERROR symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG0_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) - //[v0]~| ERROR demangling(<[&dyn impl1[317d481089b8c8fe]::Foo extern "C" fn(&'b u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method) - //[v0]~| ERROR demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'b u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) + //[v0]~^^^^ ERROR symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) + //[v0]~| ERROR demangling(<[&dyn impl1[317d481089b8c8fe]::Foo extern "C" fn(&'a u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method) + //[v0]~| ERROR demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) #[rustc_def_path] //[legacy]~^ ERROR def-path(<[&dyn Foo extern "C" fn(&'r u8)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) //[v0]~^^ ERROR def-path(<[&dyn Foo extern "C" fn(&'r u8)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) diff --git a/src/test/ui/symbol-names/impl1.v0.stderr b/src/test/ui/symbol-names/impl1.v0.stderr index 1c4b256c9e933..e024799df867c 100644 --- a/src/test/ui/symbol-names/impl1.v0.stderr +++ b/src/test/ui/symbol-names/impl1.v0.stderr @@ -46,19 +46,19 @@ error: def-path(bar::::baz) LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ -error: symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG0_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) +error: symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) --> $DIR/impl1.rs:63:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(<[&dyn impl1[317d481089b8c8fe]::Foo extern "C" fn(&'b u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method) +error: demangling(<[&dyn impl1[317d481089b8c8fe]::Foo extern "C" fn(&'a u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method) --> $DIR/impl1.rs:63:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'b u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) +error: demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) --> $DIR/impl1.rs:63:13 | LL | #[rustc_symbol_name] From 191603653b90e25d8e0e67f125aec523412b51f9 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 15 Aug 2019 12:55:03 -0700 Subject: [PATCH 5/6] Modify librustc_llvm to pass -DNDEBUG while compiling. Currently, librustc_llvm builds are not reproducible because the LLVM files it compiles use the debug version of llvm_unreachable, which uses __FILE__. To fix this, we propagate NDEBUG from bootstrap if applicable and use it when compiling librustc_llvm. --- src/bootstrap/compile.rs | 3 +++ src/librustc_llvm/build.rs | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 4cd793adaf574..8bd14fbce35aa 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -795,6 +795,9 @@ pub fn build_codegen_backend(builder: &Builder<'_>, if builder.config.llvm_use_libcxx { cargo.env("LLVM_USE_LIBCXX", "1"); } + if builder.config.llvm_optimize && !builder.config.llvm_release_debuginfo { + cargo.env("LLVM_NDEBUG", "1"); + } } _ => panic!("unknown backend: {}", backend), } diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 16cdbb7dd4d39..c84ec4e560138 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -151,6 +151,10 @@ fn main() { cfg.define("LLVM_RUSTLLVM", None); } + if env::var_os("LLVM_NDEBUG").is_some() { + cfg.define("NDEBUG", None); + } + build_helper::rerun_if_changed_anything_in_dir(Path::new("../rustllvm")); cfg.file("../rustllvm/PassWrapper.cpp") .file("../rustllvm/RustWrapper.cpp") From 73d771902c1e0abbec1ef792dde9f4636726ed62 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 4 Aug 2019 16:41:01 -0400 Subject: [PATCH 6/6] Serialize additional data for procedural macros Split off from #62855 This PR deerializes the declaration `Span` and attributes for all procedural macros from their underlying function definitions. This allows Rustdoc to properly render doc comments and source links when inlining procedural macros across crates --- src/libproc_macro/bridge/client.rs | 8 + src/librustc/hir/def_id.rs | 26 --- src/librustc/hir/map/definitions.rs | 19 -- src/librustc_metadata/creader.rs | 91 +++------ src/librustc_metadata/cstore.rs | 17 +- src/librustc_metadata/cstore_impl.rs | 7 +- src/librustc_metadata/decoder.rs | 184 +++++++++++------- src/librustc_metadata/encoder.rs | 30 ++- src/librustc_metadata/locator.rs | 2 +- src/librustc_metadata/schema.rs | 4 + src/test/ui/macros/same-sequence-span.stderr | 10 +- src/test/ui/proc-macro/generate-mod.stderr | 10 +- .../proc-macro/invalid-punct-ident-4.stderr | 5 +- .../ui/proc-macro/lints_in_proc_macros.stderr | 5 +- src/test/ui/proc-macro/multispan.stderr | 14 +- src/test/ui/proc-macro/subspan.stderr | 16 +- src/test/ui/proc-macro/three-equals.stderr | 2 +- 17 files changed, 238 insertions(+), 212 deletions(-) diff --git a/src/libproc_macro/bridge/client.rs b/src/libproc_macro/bridge/client.rs index 6052b4a4d43f4..5c543165bc2b1 100644 --- a/src/libproc_macro/bridge/client.rs +++ b/src/libproc_macro/bridge/client.rs @@ -468,6 +468,14 @@ pub enum ProcMacro { } impl ProcMacro { + pub fn name(&self) -> &'static str { + match self { + ProcMacro::CustomDerive { trait_name, .. } => trait_name, + ProcMacro::Attr { name, .. } => name, + ProcMacro::Bang { name, ..} => name + } + } + pub const fn custom_derive( trait_name: &'static str, attributes: &'static [&'static str], diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs index c0a661908a654..c91ad7858d0bb 100644 --- a/src/librustc/hir/def_id.rs +++ b/src/librustc/hir/def_id.rs @@ -1,5 +1,4 @@ use crate::ty::{self, TyCtxt}; -use crate::hir::map::definitions::FIRST_FREE_DEF_INDEX; use rustc_data_structures::indexed_vec::Idx; use std::fmt; use std::u32; @@ -102,31 +101,6 @@ newtype_index! { } } -impl DefIndex { - // Proc macros from a proc-macro crate have a kind of virtual DefIndex. This - // function maps the index of the macro within the crate (which is also the - // index of the macro in the CrateMetadata::proc_macros array) to the - // corresponding DefIndex. - pub fn from_proc_macro_index(proc_macro_index: usize) -> DefIndex { - // DefIndex for proc macros start from FIRST_FREE_DEF_INDEX, - // because the first FIRST_FREE_DEF_INDEX indexes are reserved - // for internal use. - let def_index = DefIndex::from( - proc_macro_index.checked_add(FIRST_FREE_DEF_INDEX) - .expect("integer overflow adding `proc_macro_index`")); - assert!(def_index != CRATE_DEF_INDEX); - def_index - } - - // This function is the reverse of from_proc_macro_index() above. - pub fn to_proc_macro_index(self: DefIndex) -> usize { - self.index().checked_sub(FIRST_FREE_DEF_INDEX) - .unwrap_or_else(|| { - bug!("using local index {:?} as proc-macro index", self) - }) - } -} - impl rustc_serialize::UseSpecializedEncodable for DefIndex {} impl rustc_serialize::UseSpecializedDecodable for DefIndex {} diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 8ee8c6d0e8983..6dc3c7038f569 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -411,10 +411,6 @@ impl Definitions { } /// Adds a root definition (no parent) and a few other reserved definitions. - /// - /// After the initial definitions are created the first `FIRST_FREE_DEF_INDEX` indexes - /// are taken, so the "user" indexes will be allocated starting with `FIRST_FREE_DEF_INDEX` - /// in ascending order. pub fn create_root_def(&mut self, crate_name: &str, crate_disambiguator: CrateDisambiguator) @@ -589,19 +585,6 @@ impl DefPathData { } } -/// Evaluates to the number of tokens passed to it. -/// -/// Logarithmic counting: every one or two recursive expansions, the number of -/// tokens to count is divided by two, instead of being reduced by one. -/// Therefore, the recursion depth is the binary logarithm of the number of -/// tokens to count, and the expanded tree is likewise very small. -macro_rules! count { - () => (0usize); - ($one:tt) => (1usize); - ($($pairs:tt $_p:tt)*) => (count!($($pairs)*) << 1usize); - ($odd:tt $($rest:tt)*) => (count!($($rest)*) | 1usize); -} - // We define the GlobalMetaDataKind enum with this macro because we want to // make sure that we exhaustively iterate over all variants when registering // the corresponding DefIndices in the DefTable. @@ -614,8 +597,6 @@ macro_rules! define_global_metadata_kind { $($variant),* } - pub const FIRST_FREE_DEF_INDEX: usize = 1 + count!($($variant)*); - impl GlobalMetaDataKind { fn allocate_def_indices(definitions: &mut Definitions) { $({ diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index d5f1e715186f4..e4fca9682ec74 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -2,8 +2,7 @@ use crate::cstore::{self, CStore, CrateSource, MetadataBlob}; use crate::locator::{self, CratePaths}; -use crate::decoder::proc_macro_def_path_table; -use crate::schema::CrateRoot; +use crate::schema::{CrateRoot}; use rustc_data_structures::sync::{Lrc, RwLock, Lock}; use rustc::hir::def_id::CrateNum; @@ -26,11 +25,11 @@ use std::{cmp, fs}; use syntax::ast; use syntax::attr; use syntax::ext::allocator::{global_allocator_spans, AllocatorKind}; -use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind}; use syntax::symbol::{Symbol, sym}; use syntax::{span_err, span_fatal}; use syntax_pos::{Span, DUMMY_SP}; use log::{debug, info, log_enabled}; +use proc_macro::bridge::client::ProcMacro; pub struct Library { pub dylib: Option<(PathBuf, PathKind)>, @@ -230,24 +229,13 @@ impl<'a> CrateLoader<'a> { let dependencies: Vec = cnum_map.iter().cloned().collect(); - let proc_macros = crate_root.proc_macro_decls_static.map(|_| { + let raw_proc_macros = crate_root.proc_macro_data.map(|_| { if self.sess.opts.debugging_opts.dual_proc_macros { - let host_lib = host_lib.unwrap(); - self.load_derive_macros( - &host_lib.metadata.get_root(), - host_lib.dylib.map(|p| p.0), - span - ) + let host_lib = host_lib.as_ref().unwrap(); + self.dlsym_proc_macros(host_lib.dylib.as_ref().map(|p| p.0.clone()), + &host_lib.metadata.get_root(), span) } else { - self.load_derive_macros(&crate_root, dylib.clone().map(|p| p.0), span) - } - }); - - let def_path_table = record_time(&self.sess.perf_stats.decode_def_path_tables_time, || { - if let Some(proc_macros) = &proc_macros { - proc_macro_def_path_table(&crate_root, proc_macros) - } else { - crate_root.def_path_table.decode((&metadata, self.sess)) + self.dlsym_proc_macros(dylib.clone().map(|p| p.0), &crate_root, span) } }); @@ -260,13 +248,16 @@ impl<'a> CrateLoader<'a> { .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls)) .collect(); + let def_path_table = record_time(&self.sess.perf_stats.decode_def_path_tables_time, || { + crate_root.def_path_table.decode((&metadata, self.sess)) + }); + 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, - proc_macros, root: crate_root, blob: metadata, cnum_map, @@ -280,7 +271,10 @@ impl<'a> CrateLoader<'a> { rlib, rmeta, }, - private_dep + private_dep, + span, + host_lib, + raw_proc_macros }; let cmeta = Lrc::new(cmeta); @@ -300,8 +294,6 @@ impl<'a> CrateLoader<'a> { // message we emit let mut proc_macro_locator = locate_ctxt.clone(); - // Try to load a proc macro - proc_macro_locator.is_proc_macro = Some(true); // Load the proc macro crate for the target let (locator, target_result) = if self.sess.opts.debugging_opts.dual_proc_macros { @@ -389,7 +381,7 @@ impl<'a> CrateLoader<'a> { match result { (LoadResult::Previous(cnum), None) => { let data = self.cstore.get_crate_data(cnum); - if data.root.proc_macro_decls_static.is_some() { + if data.root.proc_macro_data.is_some() { dep_kind = DepKind::UnexportedMacrosOnly; } data.dep_kind.with_lock(|data_dep_kind| { @@ -482,7 +474,7 @@ impl<'a> CrateLoader<'a> { dep_kind: DepKind) -> cstore::CrateNumMap { debug!("resolving deps of external crate"); - if crate_root.proc_macro_decls_static.is_some() { + if crate_root.proc_macro_data.is_some() { return cstore::CrateNumMap::new(); } @@ -574,19 +566,13 @@ impl<'a> CrateLoader<'a> { } } - /// Loads custom derive macros. - /// - /// Note that this is intentionally similar to how we load plugins today, - /// but also intentionally separate. Plugins are likely always going to be - /// implemented as dynamic libraries, but we have a possible future where - /// custom derive (and other macro-1.1 style features) are implemented via - /// executables and custom IPC. - fn load_derive_macros(&mut self, root: &CrateRoot<'_>, dylib: Option, span: Span) - -> Vec<(ast::Name, Lrc)> { - use std::{env, mem}; + fn dlsym_proc_macros(&self, + dylib: Option, + root: &CrateRoot<'_>, + span: Span + ) -> &'static [ProcMacro] { + use std::env; use crate::dynamic_lib::DynamicLibrary; - use proc_macro::bridge::client::ProcMacro; - use syntax::ext::proc_macro::{BangProcMacro, AttrProcMacro, ProcMacroDerive}; let path = match dylib { Some(dylib) => dylib, @@ -608,38 +594,11 @@ impl<'a> CrateLoader<'a> { *(sym as *const &[ProcMacro]) }; - let extensions = decls.iter().map(|&decl| { - let (name, kind, helper_attrs) = match decl { - ProcMacro::CustomDerive { trait_name, attributes, client } => { - let helper_attrs = - attributes.iter().cloned().map(Symbol::intern).collect::>(); - ( - trait_name, - SyntaxExtensionKind::Derive(Box::new(ProcMacroDerive { - client, attrs: helper_attrs.clone() - })), - helper_attrs, - ) - } - ProcMacro::Attr { name, client } => ( - name, SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client })), Vec::new() - ), - ProcMacro::Bang { name, client } => ( - name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new() - ) - }; - - (Symbol::intern(name), Lrc::new(SyntaxExtension { - helper_attrs, - ..SyntaxExtension::default(kind, root.edition) - })) - }).collect(); - // Intentionally leak the dynamic library. We can't ever unload it // since the library can make things that will live arbitrarily long. - mem::forget(lib); + std::mem::forget(lib); - extensions + decls } /// Look for a plugin registrar. Returns library path, crate diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 4ac0a5b94c0d8..792922a183722 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -28,6 +28,9 @@ pub use crate::cstore_impl::{provide, provide_extern}; pub type CrateNumMap = IndexVec; pub use rustc_data_structures::sync::MetadataRef; +use crate::creader::Library; +use syntax_pos::Span; +use proc_macro::bridge::client::ProcMacro; pub struct MetadataBlob(pub MetadataRef); @@ -82,11 +85,19 @@ pub struct CrateMetadata { pub dep_kind: Lock, pub source: CrateSource, - pub proc_macros: Option)>>, - /// Whether or not this crate should be consider a private dependency /// for purposes of the 'exported_private_dependencies' lint - pub private_dep: bool + pub private_dep: bool, + + pub host_lib: Option, + pub span: Span, + + pub raw_proc_macros: Option<&'static [ProcMacro]>, +} + +pub struct FullProcMacro { + pub name: ast::Name, + pub ext: Lrc } pub struct CStore { diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index b46758abb5f2c..a66da32fa4d75 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -426,8 +426,8 @@ impl cstore::CStore { pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro { 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()); + if data.is_proc_macro_crate() { + return LoadedMacro::ProcMacro(data.get_proc_macro(id.index, sess).ext); } else if data.name == sym::proc_macro && data.item_name(id.index) == sym::quote { let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote); let kind = SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })); @@ -439,7 +439,8 @@ impl cstore::CStore { } let def = data.get_macro(id.index); - let macro_full_name = data.def_path(id.index).to_string_friendly(|_| data.imported_name); + 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); diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 0bec31d70765f..26f3a22ab1eaf 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -1,16 +1,15 @@ // Decoding metadata from a single crate's metadata -use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule}; +use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule, FullProcMacro}; use crate::schema::*; use rustc_data_structures::sync::{Lrc, ReadGuard}; -use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash, Definitions}; +use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash}; use rustc::hir; use rustc::middle::cstore::LinkagePreference; use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; use rustc::hir::def::{self, Res, DefKind, CtorOf, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; -use rustc::hir::map::definitions::DefPathTable; use rustc_data_structures::fingerprint::Fingerprint; use rustc::middle::lang_items; use rustc::mir::{self, interpret}; @@ -30,10 +29,11 @@ use syntax::attr; use syntax::ast::{self, Ident}; use syntax::source_map; use syntax::symbol::{Symbol, sym}; -use syntax::ext::base::{MacroKind, SyntaxExtension}; -use syntax::ext::hygiene::ExpnId; -use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP}; +use syntax::ext::base::{MacroKind, SyntaxExtensionKind, SyntaxExtension}; +use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, symbol::{InternedString}}; use log::debug; +use proc_macro::bridge::client::ProcMacro; +use syntax::ext::proc_macro::{AttrProcMacro, ProcMacroDerive, BangProcMacro}; pub struct DecodeContext<'a, 'tcx> { opaque: opaque::Decoder<'a>, @@ -138,7 +138,7 @@ impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> LazySeq { pub fn decode>( self, meta: M, - ) -> impl Iterator + Captures<'a> + Captures<'tcx> + 'x { + ) -> impl ExactSizeIterator + Captures<'a> + Captures<'tcx> + 'x { let mut dcx = meta.decoder(self.position); dcx.lazy_state = LazyState::NodeStart(self.position); (0..self.len).map(move |_| T::decode(&mut dcx).unwrap()) @@ -434,46 +434,16 @@ impl<'tcx> EntryKind<'tcx> { } } -/// Creates the "fake" DefPathTable for a given proc macro crate. -/// -/// The DefPathTable is as follows: -/// -/// CRATE_ROOT (DefIndex 0:0) -/// |- GlobalMetaDataKind data (DefIndex 1:0 .. DefIndex 1:N) -/// |- proc macro #0 (DefIndex 1:N) -/// |- proc macro #1 (DefIndex 1:N+1) -/// \- ... -crate fn proc_macro_def_path_table(crate_root: &CrateRoot<'_>, - proc_macros: &[(ast::Name, Lrc)]) - -> DefPathTable -{ - let mut definitions = Definitions::default(); - - let name = crate_root.name.as_str(); - let disambiguator = crate_root.disambiguator; - debug!("creating proc macro def path table for {:?}/{:?}", name, disambiguator); - let crate_root = definitions.create_root_def(&name, disambiguator); - for (index, (name, _)) in proc_macros.iter().enumerate() { - let def_index = definitions.create_def_with_parent( - crate_root, - ast::DUMMY_NODE_ID, - DefPathData::MacroNs(name.as_interned_str()), - ExpnId::root(), - DUMMY_SP); - debug!("definition for {:?} is {:?}", name, def_index); - assert_eq!(def_index, DefIndex::from_proc_macro_index(index)); - } - - definitions.def_path_table().clone() -} - impl<'a, 'tcx> CrateMetadata { + pub fn is_proc_macro_crate(&self) -> bool { + self.root.proc_macro_decls_static.is_some() + } fn is_proc_macro(&self, id: DefIndex) -> bool { - self.proc_macros.is_some() && id != CRATE_DEF_INDEX + self.is_proc_macro_crate() && + self.root.proc_macro_data.unwrap().decode(self).find(|x| *x == id).is_some() } fn maybe_entry(&self, item_id: DefIndex) -> Option>> { - assert!(!self.is_proc_macro(item_id)); self.root.entries_index.lookup(self.blob.raw_bytes(), item_id) } @@ -496,13 +466,24 @@ impl<'a, 'tcx> CrateMetadata { } } + fn raw_proc_macro(&self, id: DefIndex) -> &ProcMacro { + // DefIndex's in root.proc_macro_data have a one-to-one correspondence + // with items in 'raw_proc_macros' + let pos = self.root.proc_macro_data.unwrap().decode(self).position(|i| i == id).unwrap(); + &self.raw_proc_macros.unwrap()[pos] + } + pub fn item_name(&self, item_index: DefIndex) -> Symbol { - self.def_key(item_index) - .disambiguated_data - .data - .get_opt_name() - .expect("no name in item_name") - .as_symbol() + if !self.is_proc_macro(item_index) { + self.def_key(item_index) + .disambiguated_data + .data + .get_opt_name() + .expect("no name in item_name") + .as_symbol() + } else { + Symbol::intern(self.raw_proc_macro(item_index).name()) + } } pub fn def_kind(&self, index: DefIndex) -> Option { @@ -510,15 +491,64 @@ impl<'a, 'tcx> CrateMetadata { self.entry(index).kind.def_kind() } else { Some(DefKind::Macro( - self.proc_macros.as_ref().unwrap()[index.to_proc_macro_index()].1.macro_kind() + macro_kind(self.raw_proc_macro(index)) )) } } pub fn get_span(&self, index: DefIndex, sess: &Session) -> Span { - match self.is_proc_macro(index) { - true => DUMMY_SP, - false => self.entry(index).span.decode((self, sess)), + self.entry(index).span.decode((self, sess)) + } + + + pub fn get_proc_macro(&self, id: DefIndex, sess: &Session) -> FullProcMacro { + if sess.opts.debugging_opts.dual_proc_macros { + let host_lib = self.host_lib.as_ref().unwrap(); + self.load_proc_macro( + &host_lib.metadata.get_root(), + id, + sess + ) + } else { + self.load_proc_macro(&self.root, id, sess) + } + } + + fn load_proc_macro(&self, root: &CrateRoot<'_>, + id: DefIndex, + sess: &Session) + -> FullProcMacro { + + let raw_macro = self.raw_proc_macro(id); + let (name, kind, helper_attrs) = match *raw_macro { + ProcMacro::CustomDerive { trait_name, attributes, client } => { + let helper_attrs = + attributes.iter().cloned().map(Symbol::intern).collect::>(); + ( + trait_name, + SyntaxExtensionKind::Derive(Box::new(ProcMacroDerive { + client, attrs: helper_attrs.clone() + })), + helper_attrs, + ) + } + ProcMacro::Attr { name, client } => ( + name, SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client })), Vec::new() + ), + ProcMacro::Bang { name, client } => ( + name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new() + ) + }; + + let span = self.get_span(id, sess); + + FullProcMacro { + name: Symbol::intern(name), + ext: Lrc::new(SyntaxExtension { + span, + helper_attrs, + ..SyntaxExtension::default(kind, root.edition) + }) } } @@ -715,7 +745,7 @@ impl<'a, 'tcx> CrateMetadata { /// Iterates over the language items in the given crate. pub fn get_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] { - if self.proc_macros.is_some() { + if self.is_proc_macro_crate() { // Proc macro crates do not export any lang-items to the target. &[] } else { @@ -730,18 +760,18 @@ impl<'a, 'tcx> CrateMetadata { pub fn each_child_of_item(&self, id: DefIndex, mut callback: F, sess: &Session) where F: FnMut(def::Export) { - if let Some(ref proc_macros) = self.proc_macros { + if let Some(proc_macros_ids) = self.root.proc_macro_data.map(|d| d.decode(self)) { /* If we are loading as a proc macro, we want to return the view of this crate - * as a proc macro crate, not as a Rust crate. See `proc_macro_def_path_table` - * for the DefPathTable we are corresponding to. + * as a proc macro crate. */ if id == CRATE_DEF_INDEX { - for (id, &(name, ref ext)) in proc_macros.iter().enumerate() { + for def_index in proc_macros_ids { + let raw_macro = self.raw_proc_macro(def_index); let res = Res::Def( - DefKind::Macro(ext.macro_kind()), - self.local_def_id(DefIndex::from_proc_macro_index(id)), + DefKind::Macro(macro_kind(raw_macro)), + self.local_def_id(def_index), ); - let ident = Ident::with_dummy_span(name); + let ident = Ident::from_str(raw_macro.name()); callback(def::Export { ident: ident, res: res, @@ -952,11 +982,8 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Lrc<[ast::Attribute]> { - if self.is_proc_macro(node_id) { - return Lrc::new([]); - } + pub fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Lrc<[ast::Attribute]> { // The attributes for a tuple struct/variant are attached to the definition, not the ctor; // we assume that someone passing in a tuple struct ctor is actually wanting to // look at the definition @@ -1014,7 +1041,7 @@ impl<'a, 'tcx> CrateMetadata { tcx: TyCtxt<'tcx>, filter: Option, ) -> &'tcx [DefId] { - if self.proc_macros.is_some() { + if self.is_proc_macro_crate() { // proc-macro crates export no trait impls. return &[] } @@ -1058,7 +1085,7 @@ impl<'a, 'tcx> CrateMetadata { pub fn get_native_libraries(&self, sess: &Session) -> Vec { - if self.proc_macros.is_some() { + if self.is_proc_macro_crate() { // Proc macro crates do not have any *target* native libraries. vec![] } else { @@ -1067,7 +1094,7 @@ impl<'a, 'tcx> CrateMetadata { } pub fn get_foreign_modules(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ForeignModule] { - if self.proc_macros.is_some() { + if self.is_proc_macro_crate() { // Proc macro crates do not have any *target* foreign modules. &[] } else { @@ -1090,7 +1117,7 @@ impl<'a, 'tcx> CrateMetadata { } pub fn get_missing_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] { - if self.proc_macros.is_some() { + if self.is_proc_macro_crate() { // Proc macro crates do not depend on any target weak lang-items. &[] } else { @@ -1114,7 +1141,7 @@ impl<'a, 'tcx> CrateMetadata { &self, tcx: TyCtxt<'tcx>, ) -> Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)> { - if self.proc_macros.is_some() { + if self.is_proc_macro_crate() { // If this crate is a custom derive crate, then we're not even going to // link those in so we skip those crates. vec![] @@ -1183,13 +1210,18 @@ impl<'a, 'tcx> CrateMetadata { #[inline] pub fn def_key(&self, index: DefIndex) -> DefKey { - self.def_path_table.def_key(index) + let mut key = self.def_path_table.def_key(index); + if self.is_proc_macro(index) { + let name = self.raw_proc_macro(index).name(); + key.disambiguated_data.data = DefPathData::MacroNs(InternedString::intern(name)); + } + key } // Returns the path leading to the thing with this `id`. pub fn def_path(&self, id: DefIndex) -> DefPath { debug!("def_path(cnum={:?}, id={:?})", self.cnum, id); - DefPath::make(self.cnum, id, |parent| self.def_path_table.def_key(parent)) + DefPath::make(self.cnum, id, |parent| self.def_key(parent)) } #[inline] @@ -1302,3 +1334,13 @@ impl<'a, 'tcx> CrateMetadata { self.source_map_import_info.borrow() } } + +// Cannot be implemented on 'ProcMacro', as libproc_macro +// does not depend on libsyntax +fn macro_kind(raw: &ProcMacro) -> MacroKind { + match raw { + ProcMacro::CustomDerive { .. } => MacroKind::Derive, + ProcMacro::Attr { .. } => MacroKind::Attr, + ProcMacro::Bang { .. } => MacroKind::Bang + } +} diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index fb675d7d841e1..094f1a6ac330c 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -30,6 +30,7 @@ use rustc_data_structures::sync::Lrc; use std::u32; use syntax::ast; use syntax::attr; +use syntax::ext::proc_macro::is_proc_macro_attr; use syntax::source_map::Spanned; use syntax::symbol::{kw, sym}; use syntax_pos::{self, FileName, SourceFile, Span}; @@ -376,6 +377,8 @@ impl<'tcx> EncodeContext<'tcx> { } fn encode_crate_root(&mut self) -> Lazy> { + let is_proc_macro = self.tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro); + let mut i = self.position(); let crate_deps = self.encode_crate_deps(); @@ -456,16 +459,23 @@ impl<'tcx> EncodeContext<'tcx> { self.lazy_seq(interpret_alloc_index) }; + i = self.position(); let entries_index = self.entries_index.write_index(&mut self.opaque); let entries_index_bytes = self.position() - i; + // Encode the proc macro data + i = self.position(); + let proc_macro_data = self.encode_proc_macros(); + let proc_macro_data_bytes = self.position() - i; + + let attrs = tcx.hir().krate_attrs(); - let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro); let has_default_lib_allocator = attr::contains_name(&attrs, sym::default_lib_allocator); let has_global_allocator = *tcx.sess.has_global_allocator.get(); let has_panic_handler = *tcx.sess.has_panic_handler.try_get().unwrap_or(&false); + let root = self.lazy(&CrateRoot { name: tcx.crate_name(LOCAL_CRATE), extra_filename: tcx.sess.opts.cg.extra_filename.clone(), @@ -484,6 +494,7 @@ impl<'tcx> EncodeContext<'tcx> { } else { None }, + proc_macro_data, proc_macro_stability: if is_proc_macro { tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX)).map(|stab| stab.clone()) } else { @@ -532,6 +543,7 @@ impl<'tcx> EncodeContext<'tcx> { println!(" impl bytes: {}", impl_bytes); println!(" exp. symbols bytes: {}", exported_symbols_bytes); println!(" def-path table bytes: {}", def_path_table_bytes); + println!(" proc-macro-data-bytes: {}", proc_macro_data_bytes); println!(" item bytes: {}", item_bytes); println!(" entries index bytes: {}", entries_index_bytes); println!(" zero bytes: {}", zero_bytes); @@ -1463,6 +1475,22 @@ impl EncodeContext<'tcx> { self.lazy_seq(foreign_modules.iter().cloned()) } + fn encode_proc_macros(&mut self) -> Option> { + let is_proc_macro = self.tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro); + if is_proc_macro { + let proc_macros: Vec<_> = self.tcx.hir().krate().items.values().filter_map(|item| { + if item.attrs.iter().any(|attr| is_proc_macro_attr(attr)) { + Some(item.hir_id.owner) + } else { + None + } + }).collect(); + Some(self.lazy_seq(proc_macros)) + } else { + None + } + } + fn encode_crate_deps(&mut self) -> LazySeq { let crates = self.tcx.crates(); diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 3832c8ee227de..dfb783c75895e 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -716,7 +716,7 @@ impl<'a> Context<'a> { let root = metadata.get_root(); if let Some(is_proc_macro) = self.is_proc_macro { - if root.proc_macro_decls_static.is_some() != is_proc_macro { + if root.proc_macro_data.is_some() != is_proc_macro { return None; } } diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index c0ac69159330e..13c599cf997b6 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -182,6 +182,10 @@ pub struct CrateRoot<'tcx> { pub entries_index: LazySeq>, + /// The DefIndex's of any proc macros delcared by + /// this crate + pub proc_macro_data: Option>, + pub compiler_builtins: bool, pub needs_allocator: bool, pub needs_panic_runtime: bool, diff --git a/src/test/ui/macros/same-sequence-span.stderr b/src/test/ui/macros/same-sequence-span.stderr index aee1b4c9c5d99..250773a1853ec 100644 --- a/src/test/ui/macros/same-sequence-span.stderr +++ b/src/test/ui/macros/same-sequence-span.stderr @@ -18,7 +18,10 @@ error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fra --> $DIR/same-sequence-span.rs:20:1 | LL | proc_macro_sequence::make_foo!(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | not allowed after `expr` fragments + | in this macro invocation | = note: allowed there are: `=>`, `,` or `;` @@ -26,7 +29,10 @@ error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragmen --> $DIR/same-sequence-span.rs:20:1 | LL | proc_macro_sequence::make_foo!(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | not allowed after `expr` fragments + | in this macro invocation | = note: allowed there are: `=>`, `,` or `;` diff --git a/src/test/ui/proc-macro/generate-mod.stderr b/src/test/ui/proc-macro/generate-mod.stderr index 51bbb23da7540..829d8bf4c81da 100644 --- a/src/test/ui/proc-macro/generate-mod.stderr +++ b/src/test/ui/proc-macro/generate-mod.stderr @@ -2,13 +2,19 @@ error[E0412]: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:9:1 | LL | generate_mod::check!(); - | ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | not found in this scope + | in this macro invocation error[E0412]: cannot find type `Outer` in this scope --> $DIR/generate-mod.rs:9:1 | LL | generate_mod::check!(); - | ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | not found in this scope + | in this macro invocation error[E0412]: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:12:1 diff --git a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr index da2bf07a1a3ad..65e40172ef539 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr +++ b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr @@ -2,7 +2,10 @@ error: unexpected close delimiter: `)` --> $DIR/invalid-punct-ident-4.rs:6:1 | LL | lexer_failure!(); - | ^^^^^^^^^^^^^^^^^ unexpected close delimiter + | ^^^^^^^^^^^^^^^^^ + | | + | unexpected close delimiter + | in this macro invocation error: proc macro panicked --> $DIR/invalid-punct-ident-4.rs:6:1 diff --git a/src/test/ui/proc-macro/lints_in_proc_macros.stderr b/src/test/ui/proc-macro/lints_in_proc_macros.stderr index 2d97cd700be9f..f28b8c9fb73e9 100644 --- a/src/test/ui/proc-macro/lints_in_proc_macros.stderr +++ b/src/test/ui/proc-macro/lints_in_proc_macros.stderr @@ -2,7 +2,10 @@ error[E0425]: cannot find value `foobar2` in this scope --> $DIR/lints_in_proc_macros.rs:12:5 | LL | bang_proc_macro2!(); - | ^^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `foobar` + | ^^^^^^^^^^^^^^^^^^^^ + | | + | help: a local variable with a similar name exists: `foobar` + | in this macro invocation error: aborting due to previous error diff --git a/src/test/ui/proc-macro/multispan.stderr b/src/test/ui/proc-macro/multispan.stderr index 44af07a794234..a0c1f9cd5c05f 100644 --- a/src/test/ui/proc-macro/multispan.stderr +++ b/src/test/ui/proc-macro/multispan.stderr @@ -2,7 +2,7 @@ error: hello to you, too! --> $DIR/multispan.rs:14:5 | LL | hello!(hi); - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ in this macro invocation | note: found these 'hi's --> $DIR/multispan.rs:14:12 @@ -14,7 +14,7 @@ error: hello to you, too! --> $DIR/multispan.rs:17:5 | LL | hello!(hi hi); - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ in this macro invocation | note: found these 'hi's --> $DIR/multispan.rs:17:12 @@ -26,7 +26,7 @@ error: hello to you, too! --> $DIR/multispan.rs:20:5 | LL | hello!(hi hi hi); - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ in this macro invocation | note: found these 'hi's --> $DIR/multispan.rs:20:12 @@ -38,7 +38,7 @@ error: hello to you, too! --> $DIR/multispan.rs:23:5 | LL | hello!(hi hey hi yo hi beep beep hi hi); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation | note: found these 'hi's --> $DIR/multispan.rs:23:12 @@ -50,7 +50,7 @@ error: hello to you, too! --> $DIR/multispan.rs:24:5 | LL | hello!(hi there, hi how are you? hi... hi.); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation | note: found these 'hi's --> $DIR/multispan.rs:24:12 @@ -62,7 +62,7 @@ error: hello to you, too! --> $DIR/multispan.rs:25:5 | LL | hello!(whoah. hi di hi di ho); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation | note: found these 'hi's --> $DIR/multispan.rs:25:19 @@ -74,7 +74,7 @@ error: hello to you, too! --> $DIR/multispan.rs:26:5 | LL | hello!(hi good hi and good bye); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation | note: found these 'hi's --> $DIR/multispan.rs:26:12 diff --git a/src/test/ui/proc-macro/subspan.stderr b/src/test/ui/proc-macro/subspan.stderr index 5117dd6d32d49..06715c197bc59 100644 --- a/src/test/ui/proc-macro/subspan.stderr +++ b/src/test/ui/proc-macro/subspan.stderr @@ -2,7 +2,7 @@ error: found 'hi's --> $DIR/subspan.rs:11:1 | LL | subspan!("hi"); - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ in this macro invocation | note: here --> $DIR/subspan.rs:11:11 @@ -14,7 +14,7 @@ error: found 'hi's --> $DIR/subspan.rs:14:1 | LL | subspan!("hihi"); - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ in this macro invocation | note: here --> $DIR/subspan.rs:14:11 @@ -26,7 +26,7 @@ error: found 'hi's --> $DIR/subspan.rs:17:1 | LL | subspan!("hihihi"); - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ in this macro invocation | note: here --> $DIR/subspan.rs:17:11 @@ -38,7 +38,7 @@ error: found 'hi's --> $DIR/subspan.rs:20:1 | LL | subspan!("why I hide? hi!"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation | note: here --> $DIR/subspan.rs:20:17 @@ -50,7 +50,7 @@ error: found 'hi's --> $DIR/subspan.rs:21:1 | LL | subspan!("hey, hi, hidy, hidy, hi hi"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation | note: here --> $DIR/subspan.rs:21:16 @@ -62,7 +62,7 @@ error: found 'hi's --> $DIR/subspan.rs:22:1 | LL | subspan!("this is a hi, and this is another hi"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation | note: here --> $DIR/subspan.rs:22:12 @@ -74,7 +74,7 @@ error: found 'hi's --> $DIR/subspan.rs:23:1 | LL | subspan!("how are you this evening"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation | note: here --> $DIR/subspan.rs:23:24 @@ -86,7 +86,7 @@ error: found 'hi's --> $DIR/subspan.rs:24:1 | LL | subspan!("this is highly eradic"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation | note: here --> $DIR/subspan.rs:24:12 diff --git a/src/test/ui/proc-macro/three-equals.stderr b/src/test/ui/proc-macro/three-equals.stderr index f8dfa841d4f3b..0a6cbe13098a8 100644 --- a/src/test/ui/proc-macro/three-equals.stderr +++ b/src/test/ui/proc-macro/three-equals.stderr @@ -2,7 +2,7 @@ error: found 2 equal signs, need exactly 3 --> $DIR/three-equals.rs:15:5 | LL | three_equals!(==); - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ in this macro invocation | = help: input must be: `===`