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 {}`
#[derive(Default)]
pub struct HygieneEncodeContext {
- /// All `SyntaxContexts` for which we have writen `SyntaxContextData` into crate metadata.
+ /// All `SyntaxContexts` for which we have written `SyntaxContextData` into crate metadata.
/// This is `None` after we finish encoding `SyntaxContexts`, to ensure
/// that we don't accidentally try to encode any more `SyntaxContexts`
serialized_ctxts: Lock<FxHashSet<SyntaxContext>>,
// Maps serialized `SyntaxContext` ids to a `SyntaxContext` in the current
// global `HygieneData`. When we deserialize a `SyntaxContext`, we need to create
// a new id in the global `HygieneData`. This map tracks the ID we end up picking,
- // so that multiple occurences of the same serialized id are decoded to the same
+ // so that multiple occurrences of the same serialized id are decoded to the same
// `SyntaxContext`
remapped_ctxts: Lock<Vec<Option<SyntaxContext>>>,
// The same as `remapepd_ctxts`, but for `ExpnId`s
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)
}