提交 0d244052 编写于 作者: T Takayuki Maeda

implement `MacroData`

上级 60a50d02
......@@ -10,7 +10,9 @@
use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
use crate::Namespace::{self, MacroNS, TypeNS, ValueNS};
use crate::{Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, ModuleOrUniformRoot};
use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError};
use crate::{
MacroData, NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError,
};
use crate::{Resolver, ResolverArenas, Segment, ToNameBinding, VisResolutionError};
use rustc_ast::visit::{self, AssocCtxt, Visitor};
......@@ -20,7 +22,6 @@
use rustc_attr as attr;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{struct_span_err, Applicability};
use rustc_expand::base::SyntaxExtension;
use rustc_expand::expand::AstFragment;
use rustc_hir::def::{self, *};
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
......@@ -180,26 +181,32 @@ pub(crate) fn macro_def_scope(&mut self, def_id: DefId) -> Module<'a> {
}
}
pub(crate) fn get_macro(&mut self, res: Res) -> Option<Lrc<SyntaxExtension>> {
pub(crate) fn get_macro(&mut self, res: Res) -> Option<MacroData> {
match res {
Res::Def(DefKind::Macro(..), def_id) => Some(self.get_macro_by_def_id(def_id)),
Res::NonMacroAttr(_) => Some(self.non_macro_attr.clone()),
Res::NonMacroAttr(_) => {
Some(MacroData { ext: self.non_macro_attr.clone(), macro_rules: false })
}
_ => None,
}
}
pub(crate) fn get_macro_by_def_id(&mut self, def_id: DefId) -> Lrc<SyntaxExtension> {
if let Some(ext) = self.macro_map.get(&def_id) {
return ext.clone();
pub(crate) fn get_macro_by_def_id(&mut self, def_id: DefId) -> MacroData {
if let Some(macro_data) = self.macro_map.get(&def_id) {
return macro_data.clone();
}
let ext = Lrc::new(match self.cstore().load_macro_untracked(def_id, &self.session) {
LoadedMacro::MacroDef(item, edition) => self.compile_macro(&item, edition).0,
LoadedMacro::ProcMacro(ext) => ext,
});
let (ext, macro_rules) = match self.cstore().load_macro_untracked(def_id, &self.session) {
LoadedMacro::MacroDef(item, edition) => (
Lrc::new(self.compile_macro(&item, edition).0),
matches!(item.kind, ItemKind::MacroDef(def) if def.macro_rules),
),
LoadedMacro::ProcMacro(extz) => (Lrc::new(extz), false),
};
self.macro_map.insert(def_id, ext.clone());
ext
let macro_data = MacroData { ext, macro_rules };
self.macro_map.insert(def_id, macro_data.clone());
macro_data
}
pub(crate) fn build_reduced_graph(
......@@ -1251,7 +1258,7 @@ fn define_macro(&mut self, item: &ast::Item) -> MacroRulesScopeRef<'a> {
};
let res = Res::Def(DefKind::Macro(ext.macro_kind()), def_id.to_def_id());
self.r.macro_map.insert(def_id.to_def_id(), ext);
self.r.macro_map.insert(def_id.to_def_id(), MacroData { ext, macro_rules });
self.r.local_macro_def_scopes.insert(def_id, parent_scope.module);
if macro_rules {
......
......@@ -241,7 +241,7 @@ fn hygienic_lexical_parent(
{
// The macro is a proc macro derive
if let Some(def_id) = module.expansion.expn_data().macro_def_id {
let ext = self.get_macro_by_def_id(def_id);
let ext = self.get_macro_by_def_id(def_id).ext;
if ext.builtin_name.is_none()
&& ext.macro_kind() == MacroKind::Derive
&& parent.expansion.outer_expn_is_descendant_of(*ctxt)
......
......@@ -925,16 +925,9 @@ fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImport
let mut err =
struct_span_err!(self.r.session, import.span, E0364, "{error_msg}");
match binding.kind {
NameBindingKind::Res(Res::Def(DefKind::Macro(_), _def_id), _)
NameBindingKind::Res(Res::Def(DefKind::Macro(_), def_id), _)
// exclude decl_macro
if !self.r.session.features_untracked().decl_macro
|| !self
.r
.session
.source_map()
.span_to_snippet(binding.span)
.map(|snippet| snippet.starts_with("macro "))
.unwrap_or(true) =>
if self.r.get_macro_by_def_id(def_id).macro_rules =>
{
err.span_help(
binding.span,
......
......@@ -866,6 +866,12 @@ struct DeriveData {
has_derive_copy: bool,
}
#[derive(Clone)]
struct MacroData {
ext: Lrc<SyntaxExtension>,
macro_rules: bool,
}
/// The main resolver class.
///
/// This is the visitor that walks the whole crate.
......@@ -965,7 +971,7 @@ pub struct Resolver<'a> {
registered_attrs: FxHashSet<Ident>,
registered_tools: RegisteredTools,
macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>,
macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
macro_map: FxHashMap<DefId, MacroData>,
dummy_ext_bang: Lrc<SyntaxExtension>,
dummy_ext_derive: Lrc<SyntaxExtension>,
non_macro_attr: Lrc<SyntaxExtension>,
......@@ -1522,7 +1528,7 @@ fn per_ns<F: FnMut(&mut Self, Namespace)>(&mut self, mut f: F) {
}
fn is_builtin_macro(&mut self, res: Res) -> bool {
self.get_macro(res).map_or(false, |ext| ext.builtin_name.is_some())
self.get_macro(res).map_or(false, |macro_data| macro_data.ext.builtin_name.is_some())
}
fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
......
......@@ -658,7 +658,7 @@ pub fn resolve_macro_path(
res
};
res.map(|res| (self.get_macro(res), res))
res.map(|res| (self.get_macro(res).map(|macro_data| macro_data.ext), res))
}
pub(crate) fn finalize_macro_resolutions(&mut self) {
......@@ -853,7 +853,7 @@ pub(crate) fn check_reserved_macro_name(&mut self, ident: Ident, res: Res) {
// Reserve some names that are not quite covered by the general check
// performed on `Resolver::builtin_attrs`.
if ident.name == sym::cfg || ident.name == sym::cfg_attr {
let macro_kind = self.get_macro(res).map(|ext| ext.macro_kind());
let macro_kind = self.get_macro(res).map(|macro_data| macro_data.ext.macro_kind());
if macro_kind.is_some() && sub_namespace_match(macro_kind, Some(MacroKind::Attr)) {
self.session.span_err(
ident.span,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册