hygiene: Merge ExpnInfo and InternalExpnData

This commit is contained in:
Vadim Petrochenkov 2019-08-13 03:34:46 +03:00
parent aca1353240
commit 1a447738b8
15 changed files with 67 additions and 67 deletions

View File

@ -704,7 +704,7 @@ impl<'a> LoweringContext<'a> {
span: Span,
allow_internal_unstable: Option<Lrc<[Symbol]>>,
) -> 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())

View File

@ -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,

View File

@ -588,13 +588,13 @@ impl<'a, 'tcx> SpecializedDecoder<Span> 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
};

View File

@ -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 {

View File

@ -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(),

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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(),
));

View File

@ -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<ast::Item> {
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(),
));

View File

@ -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(),
));

View File

@ -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<ast::Item> {
// #![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(),
));

View File

@ -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<ExpnInfo>,
}
/// 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<ExpnInfo>) -> Self {
HygieneData::with(|data| data.fresh_expn(parent, expn_info))
pub fn fresh(expn_info: Option<ExpnInfo>) -> 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<InternalExpnData>,
/// 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<Option<ExpnInfo>>,
syntax_context_data: Vec<SyntaxContextData>,
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<ExpnInfo>) -> ExpnId {
self.expn_data.push(InternalExpnData { parent, expn_info });
fn fresh_expn(&mut self, expn_info: Option<ExpnInfo>) -> 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<E: Encoder>(&self, _: &mut E) -> Result<(), E::Error> {
Ok(()) // FIXME(jseyfried) intercrate hygiene
}
}
impl Decodable for ExpnId {
fn decode<D: Decoder>(_: &mut D) -> Result<Self, D::Error> {
Ok(ExpnId::root()) // FIXME(jseyfried) intercrate hygiene
}
}
impl Encodable for SyntaxContext {
fn encode<E: Encoder>(&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<D: Decoder>(_: &mut D) -> Result<SyntaxContext, D::Error> {
fn decode<D: Decoder>(_: &mut D) -> Result<Self, D::Error> {
Ok(SyntaxContext::root()) // FIXME(jseyfried) intercrate hygiene
}
}