diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index f942a0fb857..0b7dacf8383 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -704,7 +704,7 @@ impl<'a> LoweringContext<'a> { span: Span, allow_internal_unstable: Option>, ) -> Span { - span.fresh_expansion(ExpnId::root(), ExpnInfo { + span.fresh_expansion(ExpnInfo { def_site: span, allow_internal_unstable, ..ExpnInfo::default(ExpnKind::Desugaring(reason), span, self.sess.edition()) diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 5cc8324b316..22e2cff3595 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -398,8 +398,9 @@ impl_stable_hash_for!(enum ::syntax_pos::hygiene::Transparency { }); impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo { - call_site, kind, + parent -> _, + call_site, def_site, default_transparency, allow_internal_unstable, diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 2286271b9eb..351b9988bb2 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -588,13 +588,13 @@ impl<'a, 'tcx> SpecializedDecoder for CacheDecoder<'a, 'tcx> { let expn_info_tag = u8::decode(self)?; - // FIXME(mw): This method does not restore `InternalExpnData::parent` or + // FIXME(mw): This method does not restore `ExpnInfo::parent` or // `SyntaxContextData::prev_ctxt` or `SyntaxContextData::opaque`. These things // don't seem to be used after HIR lowering, so everything should be fine // as long as incremental compilation does not kick in before that. let location = || Span::with_root_ctxt(lo, hi); let recover_from_expn_info = |this: &Self, expn_info, pos| { - let span = location().fresh_expansion(ExpnId::root(), expn_info); + let span = location().fresh_expansion(expn_info); this.synthetic_expansion_infos.borrow_mut().insert(pos, span.ctxt()); span }; diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 2f9bee74908..58e785ab8c2 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -97,7 +97,7 @@ impl<'a> base::Resolver for Resolver<'a> { } fn get_module_scope(&mut self, id: ast::NodeId) -> ExpnId { - let expn_id = ExpnId::fresh(ExpnId::root(), Some(ExpnInfo::default( + let expn_id = ExpnId::fresh(Some(ExpnInfo::default( ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition() ))); let module = self.module_map[&self.definitions.local_def_id(id)]; @@ -120,7 +120,8 @@ impl<'a> base::Resolver for Resolver<'a> { &mut self, expansion: ExpnId, fragment: &AstFragment, derives: &[ExpnId] ) { // Fill in some data for derives if the fragment is from a derive container. - let parent_scope = self.invocation_parent_scopes[&expansion]; + // We are inside the `expansion` now, but other parent scope components are still the same. + let parent_scope = ParentScope { expansion, ..self.invocation_parent_scopes[&expansion] }; let parent_def = self.definitions.invocation_parent(expansion); self.invocation_parent_scopes.extend(derives.iter().map(|&derive| (derive, parent_scope))); for &derive_invoc_id in derives { @@ -130,9 +131,7 @@ impl<'a> base::Resolver for Resolver<'a> { parent_scope.module.unresolved_invocations.borrow_mut().extend(derives); // Integrate the new AST fragment into all the definition and module structures. - // We are inside the `expansion` new, but other parent scope components are still the same. fragment.visit_with(&mut DefCollector::new(&mut self.definitions, expansion)); - let parent_scope = ParentScope { expansion, ..parent_scope }; let output_legacy_scope = self.build_reduced_graph(fragment, parent_scope); self.output_legacy_scopes.insert(expansion, output_legacy_scope); } @@ -186,7 +185,9 @@ impl<'a> base::Resolver for Resolver<'a> { let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?; let span = invoc.span(); - invoc.expansion_data.id.set_expn_info(ext.expn_info(span, fast_print_path(path))); + invoc.expansion_data.id.set_expn_info( + ext.expn_info(parent_scope.expansion, span, fast_print_path(path)) + ); if let Res::Def(_, def_id) = res { if after_derive { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 8eacb96e3ff..734b566b3ad 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -640,10 +640,11 @@ impl SyntaxExtension { SyntaxExtension::default(SyntaxExtensionKind::NonMacroAttr { mark_used }, edition) } - pub fn expn_info(&self, call_site: Span, descr: Symbol) -> ExpnInfo { + pub fn expn_info(&self, parent: ExpnId, call_site: Span, descr: Symbol) -> ExpnInfo { ExpnInfo { - call_site, kind: ExpnKind::Macro(self.macro_kind(), descr), + parent, + call_site, def_site: self.span, default_transparency: self.default_transparency, allow_internal_unstable: self.allow_internal_unstable.clone(), diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 6f3e8f14b0b..4233d5c0a22 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -353,7 +353,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { derives.reserve(traits.len()); invocations.reserve(traits.len()); for path in traits { - let expn_id = ExpnId::fresh(self.cx.current_expansion.id, None); + let expn_id = ExpnId::fresh(None); derives.push(expn_id); invocations.push(Invocation { kind: InvocationKind::Derive { path, item: item.clone() }, @@ -800,13 +800,16 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { // with exception of the derive container case which is not resolved and can get // its expansion info immediately. let expn_info = match &kind { - InvocationKind::DeriveContainer { item, .. } => Some(ExpnInfo::default( - ExpnKind::Macro(MacroKind::Attr, sym::derive), - item.span(), self.cx.parse_sess.edition, - )), + InvocationKind::DeriveContainer { item, .. } => Some(ExpnInfo { + parent: self.cx.current_expansion.id, + ..ExpnInfo::default( + ExpnKind::Macro(MacroKind::Attr, sym::derive), + item.span(), self.cx.parse_sess.edition, + ) + }), _ => None, }; - let expn_id = ExpnId::fresh(self.cx.current_expansion.id, expn_info); + let expn_id = ExpnId::fresh(expn_info); self.invocations.push(Invocation { kind, fragment_kind, diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs index 5a02ae0afb9..73df625d5ee 100644 --- a/src/libsyntax_ext/deriving/clone.rs +++ b/src/libsyntax_ext/deriving/clone.rs @@ -35,7 +35,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>, match annitem.node { ItemKind::Struct(_, Generics { ref params, .. }) | ItemKind::Enum(_, Generics { ref params, .. }) => { - let container_id = cx.current_expansion.id.parent(); + let container_id = cx.current_expansion.id.expn_info().parent; if cx.resolver.has_derives(container_id, SpecialDerives::COPY) && !params.iter().any(|param| match param.kind { ast::GenericParamKind::Type { .. } => true, diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs index 5d7c4a84389..1ef34a68004 100644 --- a/src/libsyntax_ext/deriving/cmp/eq.rs +++ b/src/libsyntax_ext/deriving/cmp/eq.rs @@ -13,7 +13,7 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt<'_>, mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable)) { - cx.resolver.add_derives(cx.current_expansion.id.parent(), SpecialDerives::EQ); + cx.resolver.add_derives(cx.current_expansion.id.expn_info().parent, SpecialDerives::EQ); let inline = cx.meta_word(span, sym::inline); let hidden = cx.meta_list_item_word(span, sym::hidden); diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs index 7d7c4ae22a8..76befc98591 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs @@ -13,7 +13,7 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt<'_>, mitem: &MetaItem, item: &Annotatable, push: &mut dyn FnMut(Annotatable)) { - cx.resolver.add_derives(cx.current_expansion.id.parent(), SpecialDerives::PARTIAL_EQ); + cx.resolver.add_derives(cx.current_expansion.id.expn_info().parent, SpecialDerives::PARTIAL_EQ); // structures are equal if all fields are equal, and non equal, if // any fields are not equal or if the enum variants are different diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 4bf004a71e4..6b739e27eee 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -425,7 +425,7 @@ impl<'a> TraitDef<'a> { return; } }; - let container_id = cx.current_expansion.id.parent(); + let container_id = cx.current_expansion.id.expn_info().parent; let is_always_copy = cx.resolver.has_derives(container_id, SpecialDerives::COPY) && has_no_type_params; diff --git a/src/libsyntax_ext/plugin_macro_defs.rs b/src/libsyntax_ext/plugin_macro_defs.rs index 15737314b22..b34a250881a 100644 --- a/src/libsyntax_ext/plugin_macro_defs.rs +++ b/src/libsyntax_ext/plugin_macro_defs.rs @@ -11,7 +11,7 @@ use syntax::source_map::respan; use syntax::symbol::sym; use syntax::tokenstream::*; use syntax_pos::{Span, DUMMY_SP}; -use syntax_pos::hygiene::{ExpnId, ExpnInfo, ExpnKind, MacroKind}; +use syntax_pos::hygiene::{ExpnInfo, ExpnKind, MacroKind}; use std::mem; @@ -43,7 +43,7 @@ pub fn inject( ) { if !named_exts.is_empty() { let mut extra_items = Vec::new(); - let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable( + let span = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable( ExpnKind::Macro(MacroKind::Attr, sym::plugin), DUMMY_SP, edition, [sym::rustc_attrs][..].into(), )); diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs index 62c74b2b9c6..9d8a8c17ba2 100644 --- a/src/libsyntax_ext/proc_macro_harness.rs +++ b/src/libsyntax_ext/proc_macro_harness.rs @@ -6,7 +6,6 @@ use syntax::attr; use syntax::source_map::{ExpnInfo, ExpnKind, respan}; use syntax::ext::base::{ExtCtxt, MacroKind}; use syntax::ext::expand::{AstFragment, ExpansionConfig}; -use syntax::ext::hygiene::ExpnId; use syntax::ext::proc_macro::is_proc_macro_attr; use syntax::parse::ParseSess; use syntax::ptr::P; @@ -328,7 +327,7 @@ fn mk_decls( custom_attrs: &[ProcMacroDef], custom_macros: &[ProcMacroDef], ) -> P { - let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable( + let span = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable( ExpnKind::Macro(MacroKind::Attr, sym::proc_macro), DUMMY_SP, cx.parse_sess.edition, [sym::rustc_attrs, sym::proc_macro_internals][..].into(), )); diff --git a/src/libsyntax_ext/standard_library_imports.rs b/src/libsyntax_ext/standard_library_imports.rs index 4382fb8af85..c0041248652 100644 --- a/src/libsyntax_ext/standard_library_imports.rs +++ b/src/libsyntax_ext/standard_library_imports.rs @@ -1,6 +1,6 @@ use syntax::{ast, attr}; use syntax::edition::Edition; -use syntax::ext::hygiene::{ExpnId, MacroKind}; +use syntax::ext::hygiene::MacroKind; use syntax::ptr::P; use syntax::source_map::{ExpnInfo, ExpnKind, dummy_spanned, respan}; use syntax::symbol::{Ident, Symbol, kw, sym}; @@ -55,7 +55,7 @@ pub fn inject( // the prelude. let name = names[0]; - let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable( + let span = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable( ExpnKind::Macro(MacroKind::Attr, sym::std_inject), DUMMY_SP, edition, [sym::prelude_import][..].into(), )); diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs index ab108290a93..3fb1c1bd022 100644 --- a/src/libsyntax_ext/test_harness.rs +++ b/src/libsyntax_ext/test_harness.rs @@ -5,9 +5,8 @@ use smallvec::{smallvec, SmallVec}; use syntax::ast::{self, Ident}; use syntax::attr; use syntax::entry::{self, EntryPointType}; -use syntax::ext::base::{ExtCtxt, Resolver}; +use syntax::ext::base::{ExtCtxt, MacroKind, Resolver}; use syntax::ext::expand::{AstFragment, ExpansionConfig}; -use syntax::ext::hygiene::{ExpnId, MacroKind}; use syntax::feature_gate::Features; use syntax::mut_visit::{*, ExpectOne}; use syntax::parse::ParseSess; @@ -269,7 +268,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P { // #![main] // test::test_main_static(&[..tests]); // } - let sp = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable( + let sp = DUMMY_SP.fresh_expansion(ExpnInfo::allow_unstable( ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, cx.ext_cx.parse_sess.edition, [sym::main, sym::test, sym::rustc_attrs][..].into(), )); diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 743bd437ee5..1dba466625a 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -56,16 +56,6 @@ struct SyntaxContextData { #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] pub struct ExpnId(u32); -// FIXME: Find a way to merge this with `ExpnInfo`. -#[derive(Debug)] -struct InternalExpnData { - parent: ExpnId, - /// Each expansion should have an associated expansion info, but sometimes there's a delay - /// between creation of an expansion ID and obtaining its info (e.g. macros are collected - /// first and then resolved later), so we use an `Option` here. - expn_info: Option, -} - /// A property of a macro expansion that determines how identifiers /// produced by that expansion are resolved. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Hash, Debug, RustcEncodable, RustcDecodable)] @@ -86,8 +76,8 @@ pub enum Transparency { } impl ExpnId { - pub fn fresh(parent: ExpnId, expn_info: Option) -> Self { - HygieneData::with(|data| data.fresh_expn(parent, expn_info)) + pub fn fresh(expn_info: Option) -> Self { + HygieneData::with(|data| data.fresh_expn(expn_info)) } /// The ID of the theoretical expansion that generates freshly parsed, unexpanded AST. @@ -106,11 +96,6 @@ impl ExpnId { ExpnId(raw) } - #[inline] - pub fn parent(self) -> ExpnId { - HygieneData::with(|data| data.parent_expn(self)) - } - #[inline] pub fn expn_info(self) -> ExpnInfo { HygieneData::with(|data| data.expn_info(self).clone()) @@ -119,7 +104,7 @@ impl ExpnId { #[inline] pub fn set_expn_info(self, info: ExpnInfo) { HygieneData::with(|data| { - let old_info = &mut data.expn_data[self.0 as usize].expn_info; + let old_info = &mut data.expn_data[self.0 as usize]; assert!(old_info.is_none(), "expansion info is reset for an expansion ID"); *old_info = Some(info); }) @@ -150,7 +135,10 @@ impl ExpnId { #[derive(Debug)] crate struct HygieneData { - expn_data: Vec, + /// Each expansion should have an associated expansion info, but sometimes there's a delay + /// between creation of an expansion ID and obtaining its info (e.g. macros are collected + /// first and then resolved later), so we use an `Option` here. + expn_data: Vec>, syntax_context_data: Vec, syntax_context_map: FxHashMap<(SyntaxContext, ExpnId, Transparency), SyntaxContext>, } @@ -158,10 +146,7 @@ crate struct HygieneData { impl HygieneData { crate fn new(edition: Edition) -> Self { HygieneData { - expn_data: vec![InternalExpnData { - parent: ExpnId::root(), - expn_info: Some(ExpnInfo::default(ExpnKind::Root, DUMMY_SP, edition)), - }], + expn_data: vec![Some(ExpnInfo::default(ExpnKind::Root, DUMMY_SP, edition))], syntax_context_data: vec![SyntaxContextData { outer_expn: ExpnId::root(), outer_transparency: Transparency::Opaque, @@ -178,17 +163,13 @@ impl HygieneData { GLOBALS.with(|globals| f(&mut *globals.hygiene_data.borrow_mut())) } - fn fresh_expn(&mut self, parent: ExpnId, expn_info: Option) -> ExpnId { - self.expn_data.push(InternalExpnData { parent, expn_info }); + fn fresh_expn(&mut self, expn_info: Option) -> ExpnId { + self.expn_data.push(expn_info); ExpnId(self.expn_data.len() as u32 - 1) } - fn parent_expn(&self, expn_id: ExpnId) -> ExpnId { - self.expn_data[expn_id.0 as usize].parent - } - fn expn_info(&self, expn_id: ExpnId) -> &ExpnInfo { - self.expn_data[expn_id.0 as usize].expn_info.as_ref() + self.expn_data[expn_id.0 as usize].as_ref() .expect("no expansion info for an expansion ID") } @@ -197,7 +178,7 @@ impl HygieneData { if expn_id == ExpnId::root() { return false; } - expn_id = self.parent_expn(expn_id); + expn_id = self.expn_info(expn_id).parent; } true } @@ -593,9 +574,9 @@ impl Span { /// other compiler-generated code to set per-span properties like allowed unstable features. /// The returned span belongs to the created expansion and has the new properties, /// but its location is inherited from the current span. - pub fn fresh_expansion(self, parent: ExpnId, expn_info: ExpnInfo) -> Span { + pub fn fresh_expansion(self, expn_info: ExpnInfo) -> Span { HygieneData::with(|data| { - let expn_id = data.fresh_expn(parent, Some(expn_info)); + let expn_id = data.fresh_expn(Some(expn_info)); self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id)) }) } @@ -606,6 +587,10 @@ impl Span { #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub struct ExpnInfo { // --- The part unique to each expansion. + /// The kind of this expansion - macro or compiler desugaring. + pub kind: ExpnKind, + /// The expansion that produced this expansion. + pub parent: ExpnId, /// The location of the actual macro invocation or syntax sugar , e.g. /// `let x = foo!();` or `if let Some(y) = x {}` /// @@ -616,8 +601,6 @@ pub struct ExpnInfo { /// call_site span would have its own ExpnInfo, with the call_site /// pointing to the `foo!` invocation. pub call_site: Span, - /// The kind of this expansion - macro or compiler desugaring. - pub kind: ExpnKind, // --- The part specific to the macro/desugaring definition. // --- FIXME: Share it between expansions with the same definition. @@ -644,8 +627,9 @@ impl ExpnInfo { /// Constructs an expansion info with default properties. pub fn default(kind: ExpnKind, call_site: Span, edition: Edition) -> ExpnInfo { ExpnInfo { - call_site, kind, + parent: ExpnId::root(), + call_site, def_site: DUMMY_SP, default_transparency: Transparency::SemiTransparent, allow_internal_unstable: None, @@ -753,6 +737,18 @@ impl DesugaringKind { } } +impl Encodable for ExpnId { + fn encode(&self, _: &mut E) -> Result<(), E::Error> { + Ok(()) // FIXME(jseyfried) intercrate hygiene + } +} + +impl Decodable for ExpnId { + fn decode(_: &mut D) -> Result { + Ok(ExpnId::root()) // FIXME(jseyfried) intercrate hygiene + } +} + impl Encodable for SyntaxContext { fn encode(&self, _: &mut E) -> Result<(), E::Error> { Ok(()) // FIXME(jseyfried) intercrate hygiene @@ -760,7 +756,7 @@ impl Encodable for SyntaxContext { } impl Decodable for SyntaxContext { - fn decode(_: &mut D) -> Result { + fn decode(_: &mut D) -> Result { Ok(SyntaxContext::root()) // FIXME(jseyfried) intercrate hygiene } }