use log::{debug, trace};
use rustc_ast::ast;
-use rustc_ast::attr;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::StableHasher;
fn specialized_encode(&mut self, expn: &ExpnId) -> Result<(), Self::Error> {
rustc_span::hygiene::raw_encode_expn_id(
*expn,
- &mut self.hygiene_ctxt,
+ &self.hygiene_ctxt,
ExpnDataEncodeMode::Metadata,
self,
)
// cross-crate inconsistencies (getting one behavior in the same
// crate, and a different behavior in another crate) due to the
// limited surface that proc-macros can expose.
+ //
+ // IMPORTANT: If this is ever changed, be sure to update
+ // `rustc_span::hygiene::raw_encode_expn_id` to handle
+ // encoding `ExpnData` for proc-macro crates.
if self.is_proc_macro {
SyntaxContext::root().encode(self)?;
} else {
let source_map_bytes = self.position() - i;
let attrs = tcx.hir().krate_attrs();
- let has_default_lib_allocator = attr::contains_name(&attrs, sym::default_lib_allocator);
+ let has_default_lib_allocator = tcx.sess.contains_name(&attrs, sym::default_lib_allocator);
let root = self.lazy(CrateRoot {
name: tcx.crate_name(LOCAL_CRATE),
} else {
None
},
- compiler_builtins: attr::contains_name(&attrs, sym::compiler_builtins),
- needs_allocator: attr::contains_name(&attrs, sym::needs_allocator),
- needs_panic_runtime: attr::contains_name(&attrs, sym::needs_panic_runtime),
- no_builtins: attr::contains_name(&attrs, sym::no_builtins),
- panic_runtime: attr::contains_name(&attrs, sym::panic_runtime),
- profiler_runtime: attr::contains_name(&attrs, sym::profiler_runtime),
+ compiler_builtins: tcx.sess.contains_name(&attrs, sym::compiler_builtins),
+ needs_allocator: tcx.sess.contains_name(&attrs, sym::needs_allocator),
+ needs_panic_runtime: tcx.sess.contains_name(&attrs, sym::needs_panic_runtime),
+ no_builtins: tcx.sess.contains_name(&attrs, sym::no_builtins),
+ panic_runtime: tcx.sess.contains_name(&attrs, sym::panic_runtime),
+ profiler_runtime: tcx.sess.contains_name(&attrs, sym::profiler_runtime),
symbol_mangling_version: tcx.sess.opts.debugging_opts.symbol_mangling_version,
crate_deps,
debug!("EntryBuilder::encode_mir({:?})", def_id);
if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) {
record!(self.tables.mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id));
- record!(self.tables.unused_generic_params[def_id.to_def_id()] <-
- self.tcx.unused_generic_params(def_id));
+
+ let unused = self.tcx.unused_generic_params(def_id);
+ if !unused.is_empty() {
+ record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused);
+ }
}
}
.into_iter()
.map(|(trait_def_id, mut impls)| {
// Bring everything into deterministic order for hashing
- impls.sort_by_cached_key(|&index| {
+ impls.sort_by_cached_key(|&(index, _)| {
tcx.hir().definitions().def_path_hash(LocalDefId { local_def_index: index })
});
struct ImplVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
- impls: FxHashMap<DefId, Vec<DefIndex>>,
+ impls: FxHashMap<DefId, Vec<(DefIndex, Option<ty::fast_reject::SimplifiedType>)>>,
}
impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> {
if let hir::ItemKind::Impl { .. } = item.kind {
let impl_id = self.tcx.hir().local_def_id(item.hir_id);
if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id.to_def_id()) {
- self.impls.entry(trait_ref.def_id).or_default().push(impl_id.local_def_index);
+ let simplified_self_ty =
+ ty::fast_reject::simplify_type(self.tcx, trait_ref.self_ty(), false);
+
+ self.impls
+ .entry(trait_ref.def_id)
+ .or_default()
+ .push((impl_id.local_def_index, simplified_self_ty));
}
}
}
Opaque,
}
-pub(crate) const NUM_TRANSPARENCIES: usize = 3;
-
impl ExpnId {
pub fn fresh(expn_data: Option<ExpnData>) -> Self {
HygieneData::with(|data| data.fresh_expn(expn_data))
HygieneData::with(|data| data.expn_data(data.outer_expn(self)).clone())
}
+ #[inline]
+ pub fn outer_mark(self) -> (ExpnId, Transparency) {
+ HygieneData::with(|data| data.outer_mark(self))
+ }
+
#[inline]
pub fn outer_mark_with_data(self) -> (ExpnId, Transparency, ExpnData) {
HygieneData::with(|data| {
/// The kind of this expansion - macro or compiler desugaring.
pub kind: ExpnKind,
/// The expansion that produced this expansion.
- #[stable_hasher(ignore)]
pub parent: ExpnId,
/// The location of the actual macro invocation or syntax sugar , e.g.
/// `let x = foo!();` or `if let Some(y) = x {}`
drop(expns);
expn_id
});
- return Ok(expn_id);
+ Ok(expn_id)
}
// Decodes `SyntaxContext`, using the provided `HygieneDecodeContext`
assert_eq!(dummy.dollar_crate_name, kw::Invalid);
});
- return Ok(new_ctxt);
+ Ok(new_ctxt)
}
pub fn num_syntax_ctxts() -> usize {
mode: ExpnDataEncodeMode,
e: &mut E,
) -> Result<(), E::Error> {
- if !context.serialized_expns.lock().contains(&expn) {
- context.latest_expns.lock().insert(expn);
- }
+ // Record the fact that we need to serialize the corresponding
+ // `ExpnData`
+ let needs_data = || {
+ if !context.serialized_expns.lock().contains(&expn) {
+ context.latest_expns.lock().insert(expn);
+ }
+ };
+
match mode {
- ExpnDataEncodeMode::IncrComp => expn.0.encode(e),
+ ExpnDataEncodeMode::IncrComp => {
+ // Always serialize the `ExpnData` in incr comp mode
+ needs_data();
+ expn.0.encode(e)
+ }
ExpnDataEncodeMode::Metadata => {
let data = expn.expn_data();
+ // We only need to serialize the ExpnData
+ // if it comes from this crate.
+ // We currently don't serialize any hygiene information data for
+ // proc-macro crates: see the `SpecializedEncoder<Span>` impl
+ // for crate metadata.
+ if data.krate == LOCAL_CRATE {
+ needs_data();
+ }
data.orig_id.expect("Missing orig_id").encode(e)?;
data.krate.encode(e)
}