resolve: Fix incorrect results of opt_def_kind
query for some built-in macros
Previously it always returned `MacroKind::Bang` while some of those macros are actually attributes and derives
This commit is contained in:
parent
4b043faba3
commit
17b1afdbb2
17 changed files with 35 additions and 19 deletions
|
@ -444,8 +444,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
),
|
),
|
||||||
ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => {
|
ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => {
|
||||||
let body = P(self.lower_mac_args(body));
|
let body = P(self.lower_mac_args(body));
|
||||||
|
let macro_kind = self.resolver.decl_macro_kind(self.resolver.local_def_id(id));
|
||||||
hir::ItemKind::Macro(ast::MacroDef { body, macro_rules })
|
hir::ItemKind::Macro(ast::MacroDef { body, macro_rules }, macro_kind)
|
||||||
}
|
}
|
||||||
ItemKind::MacCall(..) => {
|
ItemKind::MacCall(..) => {
|
||||||
panic!("`TyMac` should have been expanded by now")
|
panic!("`TyMac` should have been expanded by now")
|
||||||
|
|
|
@ -61,7 +61,7 @@ use rustc_session::lint::LintBuffer;
|
||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_session::utils::{FlattenNonterminals, NtToTokenstream};
|
use rustc_session::utils::{FlattenNonterminals, NtToTokenstream};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::hygiene::ExpnId;
|
use rustc_span::hygiene::{ExpnId, MacroKind};
|
||||||
use rustc_span::source_map::{respan, DesugaringKind};
|
use rustc_span::source_map::{respan, DesugaringKind};
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
@ -210,6 +210,8 @@ pub trait ResolverAstLowering {
|
||||||
expn_id: ExpnId,
|
expn_id: ExpnId,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> LocalDefId;
|
) -> LocalDefId;
|
||||||
|
|
||||||
|
fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
|
/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
|
||||||
|
|
|
@ -15,6 +15,7 @@ use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::sorted_map::SortedMap;
|
use rustc_data_structures::sorted_map::SortedMap;
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_macros::HashStable_Generic;
|
use rustc_macros::HashStable_Generic;
|
||||||
|
use rustc_span::hygiene::MacroKind;
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||||
use rustc_span::{def_id::LocalDefId, BytePos, MultiSpan, Span, DUMMY_SP};
|
use rustc_span::{def_id::LocalDefId, BytePos, MultiSpan, Span, DUMMY_SP};
|
||||||
|
@ -2803,7 +2804,7 @@ pub enum ItemKind<'hir> {
|
||||||
/// A function declaration.
|
/// A function declaration.
|
||||||
Fn(FnSig<'hir>, Generics<'hir>, BodyId),
|
Fn(FnSig<'hir>, Generics<'hir>, BodyId),
|
||||||
/// A MBE macro definition (`macro_rules!` or `macro`).
|
/// A MBE macro definition (`macro_rules!` or `macro`).
|
||||||
Macro(ast::MacroDef),
|
Macro(ast::MacroDef, MacroKind),
|
||||||
/// A module.
|
/// A module.
|
||||||
Mod(Mod<'hir>),
|
Mod(Mod<'hir>),
|
||||||
/// An external module, e.g. `extern { .. }`.
|
/// An external module, e.g. `extern { .. }`.
|
||||||
|
|
|
@ -575,7 +575,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
|
||||||
item.span,
|
item.span,
|
||||||
item.hir_id(),
|
item.hir_id(),
|
||||||
),
|
),
|
||||||
ItemKind::Macro(_) => {
|
ItemKind::Macro(..) => {
|
||||||
visitor.visit_id(item.hir_id());
|
visitor.visit_id(item.hir_id());
|
||||||
}
|
}
|
||||||
ItemKind::Mod(ref module) => {
|
ItemKind::Mod(ref module) => {
|
||||||
|
|
|
@ -570,7 +570,7 @@ impl<'a> State<'a> {
|
||||||
self.end(); // need to close a box
|
self.end(); // need to close a box
|
||||||
self.ann.nested(self, Nested::Body(body));
|
self.ann.nested(self, Nested::Body(body));
|
||||||
}
|
}
|
||||||
hir::ItemKind::Macro(ref macro_def) => {
|
hir::ItemKind::Macro(ref macro_def, _) => {
|
||||||
self.print_mac_def(macro_def, &item.ident, item.span, |state| {
|
self.print_mac_def(macro_def, &item.ident, item.span, |state| {
|
||||||
state.print_visibility(&item.vis)
|
state.print_visibility(&item.vis)
|
||||||
});
|
});
|
||||||
|
|
|
@ -1406,7 +1406,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
|
|
||||||
EntryKind::Fn(self.lazy(data))
|
EntryKind::Fn(self.lazy(data))
|
||||||
}
|
}
|
||||||
hir::ItemKind::Macro(ref macro_def) => {
|
hir::ItemKind::Macro(ref macro_def, _) => {
|
||||||
EntryKind::MacroDef(self.lazy(macro_def.clone()))
|
EntryKind::MacroDef(self.lazy(macro_def.clone()))
|
||||||
}
|
}
|
||||||
hir::ItemKind::Mod(ref m) => {
|
hir::ItemKind::Mod(ref m) => {
|
||||||
|
|
|
@ -14,7 +14,6 @@ use rustc_hir::*;
|
||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
use rustc_span::def_id::StableCrateId;
|
use rustc_span::def_id::StableCrateId;
|
||||||
use rustc_span::hygiene::MacroKind;
|
|
||||||
use rustc_span::source_map::Spanned;
|
use rustc_span::source_map::Spanned;
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -232,7 +231,7 @@ impl<'hir> Map<'hir> {
|
||||||
ItemKind::Static(..) => DefKind::Static,
|
ItemKind::Static(..) => DefKind::Static,
|
||||||
ItemKind::Const(..) => DefKind::Const,
|
ItemKind::Const(..) => DefKind::Const,
|
||||||
ItemKind::Fn(..) => DefKind::Fn,
|
ItemKind::Fn(..) => DefKind::Fn,
|
||||||
ItemKind::Macro(..) => DefKind::Macro(MacroKind::Bang),
|
ItemKind::Macro(_, macro_kind) => DefKind::Macro(macro_kind),
|
||||||
ItemKind::Mod(..) => DefKind::Mod,
|
ItemKind::Mod(..) => DefKind::Mod,
|
||||||
ItemKind::OpaqueTy(..) => DefKind::OpaqueTy,
|
ItemKind::OpaqueTy(..) => DefKind::OpaqueTy,
|
||||||
ItemKind::TyAlias(..) => DefKind::TyAlias,
|
ItemKind::TyAlias(..) => DefKind::TyAlias,
|
||||||
|
|
|
@ -1951,7 +1951,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
|
||||||
// Historically we've run more checks on non-exported than exported macros,
|
// Historically we've run more checks on non-exported than exported macros,
|
||||||
// so this lets us continue to run them while maintaining backwards compatibility.
|
// so this lets us continue to run them while maintaining backwards compatibility.
|
||||||
// In the long run, the checks should be harmonized.
|
// In the long run, the checks should be harmonized.
|
||||||
if let ItemKind::Macro(ref macro_def) = item.kind {
|
if let ItemKind::Macro(ref macro_def, _) = item.kind {
|
||||||
let def_id = item.def_id.to_def_id();
|
let def_id = item.def_id.to_def_id();
|
||||||
if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) {
|
if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) {
|
||||||
check_non_exported_macro_for_invalid_attrs(self.tcx, item);
|
check_non_exported_macro_for_invalid_attrs(self.tcx, item);
|
||||||
|
|
|
@ -564,7 +564,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
|
||||||
// privacy and mark them reachable.
|
// privacy and mark them reachable.
|
||||||
DefKind::Macro(_) => {
|
DefKind::Macro(_) => {
|
||||||
let item = self.tcx.hir().expect_item(def_id);
|
let item = self.tcx.hir().expect_item(def_id);
|
||||||
if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }) = item.kind {
|
if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }, _) = item.kind {
|
||||||
if vis.is_accessible_from(module.to_def_id(), self.tcx) {
|
if vis.is_accessible_from(module.to_def_id(), self.tcx) {
|
||||||
self.update(def_id, level);
|
self.update(def_id, level);
|
||||||
}
|
}
|
||||||
|
@ -686,7 +686,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ItemKind::Macro(ref macro_def) => {
|
hir::ItemKind::Macro(ref macro_def, _) => {
|
||||||
self.update_reachability_from_macro(item.def_id, macro_def);
|
self.update_reachability_from_macro(item.def_id, macro_def);
|
||||||
}
|
}
|
||||||
hir::ItemKind::ForeignMod { items, .. } => {
|
hir::ItemKind::ForeignMod { items, .. } => {
|
||||||
|
|
|
@ -990,6 +990,9 @@ pub struct Resolver<'a> {
|
||||||
crate_loader: CrateLoader<'a>,
|
crate_loader: CrateLoader<'a>,
|
||||||
macro_names: FxHashSet<Ident>,
|
macro_names: FxHashSet<Ident>,
|
||||||
builtin_macros: FxHashMap<Symbol, BuiltinMacroState>,
|
builtin_macros: FxHashMap<Symbol, BuiltinMacroState>,
|
||||||
|
/// A small map keeping true kinds of built-in macros that appear to be fn-like on
|
||||||
|
/// the surface (`macro` items in libcore), but are actually attributes or derives.
|
||||||
|
builtin_macro_kinds: FxHashMap<LocalDefId, MacroKind>,
|
||||||
registered_attrs: FxHashSet<Ident>,
|
registered_attrs: FxHashSet<Ident>,
|
||||||
registered_tools: RegisteredTools,
|
registered_tools: RegisteredTools,
|
||||||
macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>,
|
macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>,
|
||||||
|
@ -1261,6 +1264,10 @@ impl ResolverAstLowering for Resolver<'_> {
|
||||||
|
|
||||||
def_id
|
def_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind {
|
||||||
|
self.builtin_macro_kinds.get(&def_id).copied().unwrap_or(MacroKind::Bang)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Resolver<'a> {
|
impl<'a> Resolver<'a> {
|
||||||
|
@ -1381,6 +1388,7 @@ impl<'a> Resolver<'a> {
|
||||||
crate_loader: CrateLoader::new(session, metadata_loader, crate_name),
|
crate_loader: CrateLoader::new(session, metadata_loader, crate_name),
|
||||||
macro_names: FxHashSet::default(),
|
macro_names: FxHashSet::default(),
|
||||||
builtin_macros: Default::default(),
|
builtin_macros: Default::default(),
|
||||||
|
builtin_macro_kinds: Default::default(),
|
||||||
registered_attrs,
|
registered_attrs,
|
||||||
registered_tools,
|
registered_tools,
|
||||||
macro_use_prelude: FxHashMap::default(),
|
macro_use_prelude: FxHashMap::default(),
|
||||||
|
|
|
@ -1209,7 +1209,13 @@ impl<'a> Resolver<'a> {
|
||||||
// while still taking everything else from the source code.
|
// while still taking everything else from the source code.
|
||||||
// If we already loaded this builtin macro, give a better error message than 'no such builtin macro'.
|
// If we already loaded this builtin macro, give a better error message than 'no such builtin macro'.
|
||||||
match mem::replace(builtin_macro, BuiltinMacroState::AlreadySeen(item.span)) {
|
match mem::replace(builtin_macro, BuiltinMacroState::AlreadySeen(item.span)) {
|
||||||
BuiltinMacroState::NotYetSeen(ext) => result.kind = ext,
|
BuiltinMacroState::NotYetSeen(ext) => {
|
||||||
|
result.kind = ext;
|
||||||
|
if item.id != ast::DUMMY_NODE_ID {
|
||||||
|
self.builtin_macro_kinds
|
||||||
|
.insert(self.local_def_id(item.id), result.macro_kind());
|
||||||
|
}
|
||||||
|
}
|
||||||
BuiltinMacroState::AlreadySeen(span) => {
|
BuiltinMacroState::AlreadySeen(span) => {
|
||||||
struct_span_err!(
|
struct_span_err!(
|
||||||
self.session,
|
self.session,
|
||||||
|
|
|
@ -416,7 +416,7 @@ impl<'hir> Sig for hir::Item<'hir> {
|
||||||
|
|
||||||
Ok(sig)
|
Ok(sig)
|
||||||
}
|
}
|
||||||
hir::ItemKind::Macro(_) => {
|
hir::ItemKind::Macro(..) => {
|
||||||
let mut text = "macro".to_owned();
|
let mut text = "macro".to_owned();
|
||||||
let name = self.ident.to_string();
|
let name = self.ident.to_string();
|
||||||
text.push_str(&name);
|
text.push_str(&name);
|
||||||
|
|
|
@ -730,7 +730,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
||||||
// These don't define types.
|
// These don't define types.
|
||||||
hir::ItemKind::ExternCrate(_)
|
hir::ItemKind::ExternCrate(_)
|
||||||
| hir::ItemKind::Use(..)
|
| hir::ItemKind::Use(..)
|
||||||
| hir::ItemKind::Macro(_)
|
| hir::ItemKind::Macro(..)
|
||||||
| hir::ItemKind::Mod(_)
|
| hir::ItemKind::Mod(_)
|
||||||
| hir::ItemKind::GlobalAsm(_) => {}
|
| hir::ItemKind::GlobalAsm(_) => {}
|
||||||
hir::ItemKind::ForeignMod { items, .. } => {
|
hir::ItemKind::ForeignMod { items, .. } => {
|
||||||
|
|
|
@ -1855,7 +1855,7 @@ fn clean_maybe_renamed_item(
|
||||||
ItemKind::Fn(ref sig, ref generics, body_id) => {
|
ItemKind::Fn(ref sig, ref generics, body_id) => {
|
||||||
clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
|
clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
|
||||||
}
|
}
|
||||||
ItemKind::Macro(ref macro_def) => {
|
ItemKind::Macro(ref macro_def, _) => {
|
||||||
let ty_vis = cx.tcx.visibility(def_id).clean(cx);
|
let ty_vis = cx.tcx.visibility(def_id).clean(cx);
|
||||||
MacroItem(Macro {
|
MacroItem(Macro {
|
||||||
source: display_macro_source(cx, name, macro_def, def_id, ty_vis),
|
source: display_macro_source(cx, name, macro_def, def_id, ty_vis),
|
||||||
|
|
|
@ -1164,7 +1164,7 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>
|
||||||
|
|
||||||
fn visit_item(&mut self, item: &'hir hir::Item<'_>) {
|
fn visit_item(&mut self, item: &'hir hir::Item<'_>) {
|
||||||
let name = match &item.kind {
|
let name = match &item.kind {
|
||||||
hir::ItemKind::Macro(ref macro_def) => {
|
hir::ItemKind::Macro(ref macro_def, _) => {
|
||||||
// FIXME(#88038): Non exported macros have historically not been tested,
|
// FIXME(#88038): Non exported macros have historically not been tested,
|
||||||
// but we really ought to start testing them.
|
// but we really ought to start testing them.
|
||||||
let def_id = item.def_id.to_def_id();
|
let def_id = item.def_id.to_def_id();
|
||||||
|
|
|
@ -325,7 +325,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
om.items.push((item, renamed))
|
om.items.push((item, renamed))
|
||||||
}
|
}
|
||||||
hir::ItemKind::Macro(ref macro_def) => {
|
hir::ItemKind::Macro(ref macro_def, _) => {
|
||||||
// `#[macro_export] macro_rules!` items are handled seperately in `visit()`,
|
// `#[macro_export] macro_rules!` items are handled seperately in `visit()`,
|
||||||
// above, since they need to be documented at the module top level. Accordingly,
|
// above, since they need to be documented at the module top level. Accordingly,
|
||||||
// we only want to handle macros if one of three conditions holds:
|
// we only want to handle macros if one of three conditions holds:
|
||||||
|
|
|
@ -373,7 +373,7 @@ fn print_item(cx: &LateContext<'_>, item: &hir::Item<'_>) {
|
||||||
let item_ty = cx.tcx.type_of(did);
|
let item_ty = cx.tcx.type_of(did);
|
||||||
println!("function of type {:#?}", item_ty);
|
println!("function of type {:#?}", item_ty);
|
||||||
},
|
},
|
||||||
hir::ItemKind::Macro(ref macro_def) => {
|
hir::ItemKind::Macro(ref macro_def, _) => {
|
||||||
if macro_def.macro_rules {
|
if macro_def.macro_rules {
|
||||||
println!("macro introduced by `macro_rules!`");
|
println!("macro introduced by `macro_rules!`");
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue