mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 02:03:53 +00:00
hygiene: Merge ExpnInfo
and InternalExpnData
This commit is contained in:
parent
aca1353240
commit
1a447738b8
@ -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())
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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 {
|
||||
|
@ -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(),
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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(),
|
||||
));
|
||||
|
@ -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(),
|
||||
));
|
||||
|
@ -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(),
|
||||
));
|
||||
|
@ -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(),
|
||||
));
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user