mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
Treat macros as HIR items
This commit is contained in:
parent
ac50a53359
commit
8c62fa0575
@ -4146,6 +4146,7 @@ dependencies = [
|
|||||||
name = "rustc_privacy"
|
name = "rustc_privacy"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"rustc_ast",
|
||||||
"rustc_attr",
|
"rustc_attr",
|
||||||
"rustc_data_structures",
|
"rustc_data_structures",
|
||||||
"rustc_errors",
|
"rustc_errors",
|
||||||
|
@ -170,7 +170,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
self.lower_item_id_use_tree(use_tree, i.id, &mut vec);
|
self.lower_item_id_use_tree(use_tree, i.id, &mut vec);
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
ItemKind::MacroDef(..) => SmallVec::new(),
|
|
||||||
ItemKind::Fn(..) | ItemKind::Impl(box ImplKind { of_trait: None, .. }) => {
|
ItemKind::Fn(..) | ItemKind::Impl(box ImplKind { of_trait: None, .. }) => {
|
||||||
smallvec![i.id]
|
smallvec![i.id]
|
||||||
}
|
}
|
||||||
@ -212,28 +211,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item<'hir>> {
|
pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item<'hir>> {
|
||||||
let mut ident = i.ident;
|
let mut ident = i.ident;
|
||||||
let mut vis = self.lower_visibility(&i.vis, None);
|
let mut vis = self.lower_visibility(&i.vis, None);
|
||||||
|
|
||||||
if let ItemKind::MacroDef(MacroDef { ref body, macro_rules }) = i.kind {
|
|
||||||
if !macro_rules || self.sess.contains_name(&i.attrs, sym::macro_export) {
|
|
||||||
let hir_id = self.lower_node_id(i.id);
|
|
||||||
self.lower_attrs(hir_id, &i.attrs);
|
|
||||||
let body = P(self.lower_mac_args(body));
|
|
||||||
self.insert_macro_def(hir::MacroDef {
|
|
||||||
ident,
|
|
||||||
vis,
|
|
||||||
def_id: hir_id.expect_owner(),
|
|
||||||
span: i.span,
|
|
||||||
ast: MacroDef { body, macro_rules },
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
for a in i.attrs.iter() {
|
|
||||||
let a = self.lower_attr(a);
|
|
||||||
self.non_exported_macro_attrs.push(a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let hir_id = self.lower_node_id(i.id);
|
let hir_id = self.lower_node_id(i.id);
|
||||||
let attrs = self.lower_attrs(hir_id, &i.attrs);
|
let attrs = self.lower_attrs(hir_id, &i.attrs);
|
||||||
let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, &mut vis, &i.kind);
|
let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, &mut vis, &i.kind);
|
||||||
@ -465,7 +442,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
self.lower_generics(generics, ImplTraitContext::disallowed()),
|
self.lower_generics(generics, ImplTraitContext::disallowed()),
|
||||||
self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
|
self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
|
||||||
),
|
),
|
||||||
ItemKind::MacroDef(..) | ItemKind::MacCall(..) => {
|
ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => {
|
||||||
|
let body = P(self.lower_mac_args(body));
|
||||||
|
|
||||||
|
hir::ItemKind::Macro(ast::MacroDef { body, macro_rules })
|
||||||
|
}
|
||||||
|
ItemKind::MacCall(..) => {
|
||||||
panic!("`TyMac` should have been expanded by now")
|
panic!("`TyMac` should have been expanded by now")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,6 @@ struct LoweringContext<'a, 'hir: 'a> {
|
|||||||
/// The items being lowered are collected here.
|
/// The items being lowered are collected here.
|
||||||
owners: IndexVec<LocalDefId, Option<hir::OwnerNode<'hir>>>,
|
owners: IndexVec<LocalDefId, Option<hir::OwnerNode<'hir>>>,
|
||||||
bodies: BTreeMap<hir::BodyId, hir::Body<'hir>>,
|
bodies: BTreeMap<hir::BodyId, hir::Body<'hir>>,
|
||||||
non_exported_macro_attrs: Vec<ast::Attribute>,
|
|
||||||
|
|
||||||
trait_impls: BTreeMap<DefId, Vec<LocalDefId>>,
|
trait_impls: BTreeMap<DefId, Vec<LocalDefId>>,
|
||||||
|
|
||||||
@ -330,7 +329,6 @@ pub fn lower_crate<'a, 'hir>(
|
|||||||
trait_impls: BTreeMap::new(),
|
trait_impls: BTreeMap::new(),
|
||||||
modules: BTreeMap::new(),
|
modules: BTreeMap::new(),
|
||||||
attrs: BTreeMap::default(),
|
attrs: BTreeMap::default(),
|
||||||
non_exported_macro_attrs: Vec::new(),
|
|
||||||
catch_scopes: Vec::new(),
|
catch_scopes: Vec::new(),
|
||||||
loop_scopes: Vec::new(),
|
loop_scopes: Vec::new(),
|
||||||
is_in_loop_condition: false,
|
is_in_loop_condition: false,
|
||||||
@ -551,7 +549,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let krate = hir::Crate {
|
let krate = hir::Crate {
|
||||||
non_exported_macro_attrs: self.arena.alloc_from_iter(self.non_exported_macro_attrs),
|
|
||||||
owners: self.owners,
|
owners: self.owners,
|
||||||
bodies: self.bodies,
|
bodies: self.bodies,
|
||||||
body_ids,
|
body_ids,
|
||||||
@ -600,13 +597,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_macro_def(&mut self, item: hir::MacroDef<'hir>) {
|
|
||||||
let def_id = item.def_id;
|
|
||||||
let item = self.arena.alloc(item);
|
|
||||||
self.owners.ensure_contains_elem(def_id, || None);
|
|
||||||
self.owners[def_id] = Some(hir::OwnerNode::MacroDef(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn allocate_hir_id_counter(&mut self, owner: NodeId) -> hir::HirId {
|
fn allocate_hir_id_counter(&mut self, owner: NodeId) -> hir::HirId {
|
||||||
// Set up the counter if needed.
|
// Set up the counter if needed.
|
||||||
self.item_local_id_counters.entry(owner).or_insert(0);
|
self.item_local_id_counters.entry(owner).or_insert(0);
|
||||||
|
@ -578,6 +578,33 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_mac_def(
|
||||||
|
&mut self,
|
||||||
|
macro_def: &ast::MacroDef,
|
||||||
|
ident: &Ident,
|
||||||
|
sp: &Span,
|
||||||
|
print_visibility: impl FnOnce(&mut Self),
|
||||||
|
) {
|
||||||
|
let (kw, has_bang) = if macro_def.macro_rules {
|
||||||
|
("macro_rules", true)
|
||||||
|
} else {
|
||||||
|
print_visibility(self);
|
||||||
|
("macro", false)
|
||||||
|
};
|
||||||
|
self.print_mac_common(
|
||||||
|
Some(MacHeader::Keyword(kw)),
|
||||||
|
has_bang,
|
||||||
|
Some(*ident),
|
||||||
|
macro_def.body.delim(),
|
||||||
|
¯o_def.body.inner_tokens(),
|
||||||
|
true,
|
||||||
|
*sp,
|
||||||
|
);
|
||||||
|
if macro_def.body.need_semicolon() {
|
||||||
|
self.word(";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn print_path(&mut self, path: &ast::Path, colons_before_params: bool, depth: usize) {
|
fn print_path(&mut self, path: &ast::Path, colons_before_params: bool, depth: usize) {
|
||||||
self.maybe_print_comment(path.span.lo());
|
self.maybe_print_comment(path.span.lo());
|
||||||
|
|
||||||
@ -1305,24 +1332,9 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ItemKind::MacroDef(ref macro_def) => {
|
ast::ItemKind::MacroDef(ref macro_def) => {
|
||||||
let (kw, has_bang) = if macro_def.macro_rules {
|
self.print_mac_def(macro_def, &item.ident, &item.span, |state| {
|
||||||
("macro_rules", true)
|
state.print_visibility(&item.vis)
|
||||||
} else {
|
});
|
||||||
self.print_visibility(&item.vis);
|
|
||||||
("macro", false)
|
|
||||||
};
|
|
||||||
self.print_mac_common(
|
|
||||||
Some(MacHeader::Keyword(kw)),
|
|
||||||
has_bang,
|
|
||||||
Some(item.ident),
|
|
||||||
macro_def.body.delim(),
|
|
||||||
¯o_def.body.inner_tokens(),
|
|
||||||
true,
|
|
||||||
item.span,
|
|
||||||
);
|
|
||||||
if macro_def.body.need_semicolon() {
|
|
||||||
self.word(";");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.ann.post(self, AnnNode::Item(item))
|
self.ann.post(self, AnnNode::Item(item))
|
||||||
|
@ -35,7 +35,6 @@ macro_rules! arena_types {
|
|||||||
[few] inline_asm: rustc_hir::InlineAsm<$tcx>,
|
[few] inline_asm: rustc_hir::InlineAsm<$tcx>,
|
||||||
[few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>,
|
[few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>,
|
||||||
[] local: rustc_hir::Local<$tcx>,
|
[] local: rustc_hir::Local<$tcx>,
|
||||||
[few] macro_def: rustc_hir::MacroDef<$tcx>,
|
|
||||||
[few] mod_: rustc_hir::Mod<$tcx>,
|
[few] mod_: rustc_hir::Mod<$tcx>,
|
||||||
[] param: rustc_hir::Param<$tcx>,
|
[] param: rustc_hir::Param<$tcx>,
|
||||||
[] pat: rustc_hir::Pat<$tcx>,
|
[] pat: rustc_hir::Pat<$tcx>,
|
||||||
|
@ -670,9 +670,6 @@ pub struct ModuleItems {
|
|||||||
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
|
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Crate<'hir> {
|
pub struct Crate<'hir> {
|
||||||
// Attributes from non-exported macros, kept only for collecting the library feature list.
|
|
||||||
pub non_exported_macro_attrs: &'hir [Attribute],
|
|
||||||
|
|
||||||
pub owners: IndexVec<LocalDefId, Option<OwnerNode<'hir>>>,
|
pub owners: IndexVec<LocalDefId, Option<OwnerNode<'hir>>>,
|
||||||
pub bodies: BTreeMap<BodyId, Body<'hir>>,
|
pub bodies: BTreeMap<BodyId, Body<'hir>>,
|
||||||
pub trait_impls: BTreeMap<DefId, Vec<LocalDefId>>,
|
pub trait_impls: BTreeMap<DefId, Vec<LocalDefId>>,
|
||||||
@ -768,32 +765,6 @@ impl Crate<'_> {
|
|||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exported_macros<'hir>(&'hir self) -> impl Iterator<Item = &'hir MacroDef<'hir>> + 'hir {
|
|
||||||
self.owners.iter().filter_map(|owner| match owner {
|
|
||||||
Some(OwnerNode::MacroDef(macro_def)) => Some(*macro_def),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A macro definition, in this crate or imported from another.
|
|
||||||
///
|
|
||||||
/// Not parsed directly, but created on macro import or `macro_rules!` expansion.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct MacroDef<'hir> {
|
|
||||||
pub ident: Ident,
|
|
||||||
pub vis: Visibility<'hir>,
|
|
||||||
pub def_id: LocalDefId,
|
|
||||||
pub span: Span,
|
|
||||||
pub ast: ast::MacroDef,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MacroDef<'_> {
|
|
||||||
#[inline]
|
|
||||||
pub fn hir_id(&self) -> HirId {
|
|
||||||
HirId::make_owner(self.def_id)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A block of statements `{ .. }`, which may have a label (in this case the
|
/// A block of statements `{ .. }`, which may have a label (in this case the
|
||||||
@ -2602,7 +2573,7 @@ pub struct PolyTraitRef<'hir> {
|
|||||||
|
|
||||||
pub type Visibility<'hir> = Spanned<VisibilityKind<'hir>>;
|
pub type Visibility<'hir> = Spanned<VisibilityKind<'hir>>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum VisibilityKind<'hir> {
|
pub enum VisibilityKind<'hir> {
|
||||||
Public,
|
Public,
|
||||||
Crate(CrateSugar),
|
Crate(CrateSugar),
|
||||||
@ -2791,6 +2762,8 @@ pub enum ItemKind<'hir> {
|
|||||||
Const(&'hir Ty<'hir>, BodyId),
|
Const(&'hir Ty<'hir>, BodyId),
|
||||||
/// 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`).
|
||||||
|
Macro(ast::MacroDef),
|
||||||
/// A module.
|
/// A module.
|
||||||
Mod(Mod<'hir>),
|
Mod(Mod<'hir>),
|
||||||
/// An external module, e.g. `extern { .. }`.
|
/// An external module, e.g. `extern { .. }`.
|
||||||
@ -2856,6 +2829,7 @@ impl ItemKind<'_> {
|
|||||||
ItemKind::Static(..) => "static item",
|
ItemKind::Static(..) => "static item",
|
||||||
ItemKind::Const(..) => "constant item",
|
ItemKind::Const(..) => "constant item",
|
||||||
ItemKind::Fn(..) => "function",
|
ItemKind::Fn(..) => "function",
|
||||||
|
ItemKind::Macro(..) => "macro",
|
||||||
ItemKind::Mod(..) => "module",
|
ItemKind::Mod(..) => "module",
|
||||||
ItemKind::ForeignMod { .. } => "extern block",
|
ItemKind::ForeignMod { .. } => "extern block",
|
||||||
ItemKind::GlobalAsm(..) => "global asm item",
|
ItemKind::GlobalAsm(..) => "global asm item",
|
||||||
|
@ -466,9 +466,6 @@ pub trait Visitor<'v>: Sized {
|
|||||||
walk_assoc_type_binding(self, type_binding)
|
walk_assoc_type_binding(self, type_binding)
|
||||||
}
|
}
|
||||||
fn visit_attribute(&mut self, _id: HirId, _attr: &'v Attribute) {}
|
fn visit_attribute(&mut self, _id: HirId, _attr: &'v Attribute) {}
|
||||||
fn visit_macro_def(&mut self, macro_def: &'v MacroDef<'v>) {
|
|
||||||
walk_macro_def(self, macro_def)
|
|
||||||
}
|
|
||||||
fn visit_vis(&mut self, vis: &'v Visibility<'v>) {
|
fn visit_vis(&mut self, vis: &'v Visibility<'v>) {
|
||||||
walk_vis(self, vis)
|
walk_vis(self, vis)
|
||||||
}
|
}
|
||||||
@ -484,7 +481,6 @@ pub trait Visitor<'v>: Sized {
|
|||||||
pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate<'v>) {
|
pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate<'v>) {
|
||||||
let top_mod = krate.module();
|
let top_mod = krate.module();
|
||||||
visitor.visit_mod(top_mod, top_mod.inner, CRATE_HIR_ID);
|
visitor.visit_mod(top_mod, top_mod.inner, CRATE_HIR_ID);
|
||||||
walk_list!(visitor, visit_macro_def, krate.exported_macros());
|
|
||||||
for (&id, attrs) in krate.attrs.iter() {
|
for (&id, attrs) in krate.attrs.iter() {
|
||||||
for a in *attrs {
|
for a in *attrs {
|
||||||
visitor.visit_attribute(id, a)
|
visitor.visit_attribute(id, a)
|
||||||
@ -492,11 +488,6 @@ pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate<'v>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroDef<'v>) {
|
|
||||||
visitor.visit_id(macro_def.hir_id());
|
|
||||||
visitor.visit_ident(macro_def.ident);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod<'v>, mod_hir_id: HirId) {
|
pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod<'v>, mod_hir_id: HirId) {
|
||||||
visitor.visit_id(mod_hir_id);
|
visitor.visit_id(mod_hir_id);
|
||||||
for &item_id in module.item_ids {
|
for &item_id in module.item_ids {
|
||||||
@ -586,6 +577,9 @@ 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(_) => {
|
||||||
|
visitor.visit_id(item.hir_id());
|
||||||
|
}
|
||||||
ItemKind::Mod(ref module) => {
|
ItemKind::Mod(ref module) => {
|
||||||
// `visit_mod()` takes care of visiting the `Item`'s `HirId`.
|
// `visit_mod()` takes care of visiting the `Item`'s `HirId`.
|
||||||
visitor.visit_mod(module, item.span, item.hir_id())
|
visitor.visit_mod(module, item.span, item.hir_id())
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
|
||||||
|
|
||||||
use crate::hir::{
|
use crate::hir::{
|
||||||
BodyId, Expr, ForeignItem, ForeignItemId, ImplItem, ImplItemId, Item, ItemId, MacroDef, Mod,
|
BodyId, Expr, ForeignItem, ForeignItemId, ImplItem, ImplItemId, Item, ItemId, Mod, TraitItem,
|
||||||
TraitItem, TraitItemId, Ty, VisibilityKind,
|
TraitItemId, Ty, VisibilityKind,
|
||||||
};
|
};
|
||||||
use crate::hir_id::{HirId, ItemLocalId};
|
use crate::hir_id::{HirId, ItemLocalId};
|
||||||
use rustc_span::def_id::DefPathHash;
|
use rustc_span::def_id::DefPathHash;
|
||||||
@ -190,16 +190,3 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Item<'_> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for MacroDef<'_> {
|
|
||||||
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
|
||||||
let MacroDef { ident, def_id: _, ref ast, ref vis, span } = *self;
|
|
||||||
|
|
||||||
hcx.hash_hir_item_like(|hcx| {
|
|
||||||
ident.name.hash_stable(hcx, hasher);
|
|
||||||
ast.hash_stable(hcx, hasher);
|
|
||||||
vis.hash_stable(hcx, hasher);
|
|
||||||
span.hash_stable(hcx, hasher);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -111,6 +111,7 @@ impl Target {
|
|||||||
ItemKind::Static(..) => Target::Static,
|
ItemKind::Static(..) => Target::Static,
|
||||||
ItemKind::Const(..) => Target::Const,
|
ItemKind::Const(..) => Target::Const,
|
||||||
ItemKind::Fn(..) => Target::Fn,
|
ItemKind::Fn(..) => Target::Fn,
|
||||||
|
ItemKind::Macro(..) => Target::MacroDef,
|
||||||
ItemKind::Mod(..) => Target::Mod,
|
ItemKind::Mod(..) => Target::Mod,
|
||||||
ItemKind::ForeignMod { .. } => Target::ForeignMod,
|
ItemKind::ForeignMod { .. } => Target::ForeignMod,
|
||||||
ItemKind::GlobalAsm(..) => Target::GlobalAsm,
|
ItemKind::GlobalAsm(..) => Target::GlobalAsm,
|
||||||
|
@ -642,6 +642,11 @@ 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) => {
|
||||||
|
self.print_mac_def(macro_def, &item.ident, &item.span, |state| {
|
||||||
|
state.print_visibility(&item.vis)
|
||||||
|
});
|
||||||
|
}
|
||||||
hir::ItemKind::Mod(ref _mod) => {
|
hir::ItemKind::Mod(ref _mod) => {
|
||||||
self.head(visibility_qualified(&item.vis, "mod"));
|
self.head(visibility_qualified(&item.vis, "mod"));
|
||||||
self.print_ident(item.ident);
|
self.print_ident(item.ident);
|
||||||
|
@ -585,24 +585,6 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
|||||||
|
|
||||||
fn check_crate(&mut self, cx: &LateContext<'_>, krate: &hir::Crate<'_>) {
|
fn check_crate(&mut self, cx: &LateContext<'_>, krate: &hir::Crate<'_>) {
|
||||||
self.check_missing_docs_attrs(cx, CRATE_DEF_ID, krate.module().inner, "the", "crate");
|
self.check_missing_docs_attrs(cx, CRATE_DEF_ID, krate.module().inner, "the", "crate");
|
||||||
|
|
||||||
for macro_def in krate.exported_macros() {
|
|
||||||
// Non exported macros should be skipped, since `missing_docs` only
|
|
||||||
// applies to externally visible items.
|
|
||||||
if !cx.access_levels.is_exported(macro_def.def_id) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let attrs = cx.tcx.hir().attrs(macro_def.hir_id());
|
|
||||||
let has_doc = attrs.iter().any(has_doc);
|
|
||||||
if !has_doc {
|
|
||||||
cx.struct_span_lint(
|
|
||||||
MISSING_DOCS,
|
|
||||||
cx.tcx.sess.source_map().guess_head_span(macro_def.span),
|
|
||||||
|lint| lint.build("missing documentation for macro").emit(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
|
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
|
||||||
@ -636,6 +618,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
|||||||
|
|
||||||
hir::ItemKind::TyAlias(..)
|
hir::ItemKind::TyAlias(..)
|
||||||
| hir::ItemKind::Fn(..)
|
| hir::ItemKind::Fn(..)
|
||||||
|
| hir::ItemKind::Macro(..)
|
||||||
| hir::ItemKind::Mod(..)
|
| hir::ItemKind::Mod(..)
|
||||||
| hir::ItemKind::Enum(..)
|
| hir::ItemKind::Enum(..)
|
||||||
| hir::ItemKind::Struct(..)
|
| hir::ItemKind::Struct(..)
|
||||||
|
@ -453,10 +453,6 @@ fn late_lint_pass_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, pass: T)
|
|||||||
lint_callback!(cx, check_crate, krate);
|
lint_callback!(cx, check_crate, krate);
|
||||||
|
|
||||||
hir_visit::walk_crate(cx, krate);
|
hir_visit::walk_crate(cx, krate);
|
||||||
for attr in krate.non_exported_macro_attrs {
|
|
||||||
// This HIR ID is a lie, since the macro ID isn't available.
|
|
||||||
cx.visit_attribute(hir::CRATE_HIR_ID, attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
lint_callback!(cx, check_crate_post, krate);
|
lint_callback!(cx, check_crate_post, krate);
|
||||||
})
|
})
|
||||||
|
@ -37,9 +37,6 @@ fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap {
|
|||||||
|
|
||||||
let push = builder.levels.push(tcx.hir().attrs(hir::CRATE_HIR_ID), &store, true);
|
let push = builder.levels.push(tcx.hir().attrs(hir::CRATE_HIR_ID), &store, true);
|
||||||
builder.levels.register_id(hir::CRATE_HIR_ID);
|
builder.levels.register_id(hir::CRATE_HIR_ID);
|
||||||
for macro_def in krate.exported_macros() {
|
|
||||||
builder.levels.register_id(macro_def.hir_id());
|
|
||||||
}
|
|
||||||
intravisit::walk_crate(&mut builder, krate);
|
intravisit::walk_crate(&mut builder, krate);
|
||||||
builder.levels.pop(push);
|
builder.levels.pop(push);
|
||||||
|
|
||||||
|
@ -1100,7 +1100,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
let vis = self.get_visibility(child_index);
|
let vis = self.get_visibility(child_index);
|
||||||
let def_id = self.local_def_id(child_index);
|
let def_id = self.local_def_id(child_index);
|
||||||
let res = Res::Def(kind, def_id);
|
let res = Res::Def(kind, def_id);
|
||||||
callback(Export { res, ident, vis, span });
|
|
||||||
|
// FIXME: Macros are currently encoded twice, once as items and once as
|
||||||
|
// reexports. We ignore the items here and only use the reexports.
|
||||||
|
if !matches!(kind, DefKind::Macro(..)) {
|
||||||
|
callback(Export { res, ident, vis, span });
|
||||||
|
}
|
||||||
|
|
||||||
// For non-re-export structs and variants add their constructors to children.
|
// For non-re-export structs and variants add their constructors to children.
|
||||||
// Re-export lists automatically contain constructors when necessary.
|
// Re-export lists automatically contain constructors when necessary.
|
||||||
match kind {
|
match kind {
|
||||||
|
@ -448,9 +448,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
krate.visit_all_item_likes(&mut self.as_deep_visitor());
|
krate.visit_all_item_likes(&mut self.as_deep_visitor());
|
||||||
for macro_def in krate.exported_macros() {
|
|
||||||
self.visit_macro_def(macro_def);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_def_path_table(&mut self) {
|
fn encode_def_path_table(&mut self) {
|
||||||
@ -1385,6 +1382,9 @@ impl EncodeContext<'a, 'tcx> {
|
|||||||
|
|
||||||
EntryKind::Fn(self.lazy(data))
|
EntryKind::Fn(self.lazy(data))
|
||||||
}
|
}
|
||||||
|
hir::ItemKind::Macro(ref macro_def) => {
|
||||||
|
EntryKind::MacroDef(self.lazy(macro_def.clone()))
|
||||||
|
}
|
||||||
hir::ItemKind::Mod(ref m) => {
|
hir::ItemKind::Mod(ref m) => {
|
||||||
return self.encode_info_for_mod(item.def_id, m);
|
return self.encode_info_for_mod(item.def_id, m);
|
||||||
}
|
}
|
||||||
@ -1539,13 +1539,6 @@ impl EncodeContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serialize the text of exported macros
|
|
||||||
fn encode_info_for_macro_def(&mut self, macro_def: &hir::MacroDef<'_>) {
|
|
||||||
let def_id = macro_def.def_id.to_def_id();
|
|
||||||
record!(self.tables.kind[def_id] <- EntryKind::MacroDef(self.lazy(macro_def.ast.clone())));
|
|
||||||
self.encode_ident_span(def_id, macro_def.ident);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn encode_info_for_generic_param(&mut self, def_id: DefId, kind: EntryKind, encode_type: bool) {
|
fn encode_info_for_generic_param(&mut self, def_id: DefId, kind: EntryKind, encode_type: bool) {
|
||||||
record!(self.tables.kind[def_id] <- kind);
|
record!(self.tables.kind[def_id] <- kind);
|
||||||
if encode_type {
|
if encode_type {
|
||||||
@ -1915,9 +1908,6 @@ impl Visitor<'tcx> for EncodeContext<'a, 'tcx> {
|
|||||||
intravisit::walk_generics(self, generics);
|
intravisit::walk_generics(self, generics);
|
||||||
self.encode_info_for_generics(generics);
|
self.encode_info_for_generics(generics);
|
||||||
}
|
}
|
||||||
fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef<'tcx>) {
|
|
||||||
self.encode_info_for_macro_def(macro_def);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EncodeContext<'a, 'tcx> {
|
impl EncodeContext<'a, 'tcx> {
|
||||||
@ -1972,6 +1962,7 @@ impl EncodeContext<'a, 'tcx> {
|
|||||||
hir::ItemKind::Static(..)
|
hir::ItemKind::Static(..)
|
||||||
| hir::ItemKind::Const(..)
|
| hir::ItemKind::Const(..)
|
||||||
| hir::ItemKind::Fn(..)
|
| hir::ItemKind::Fn(..)
|
||||||
|
| hir::ItemKind::Macro(..)
|
||||||
| hir::ItemKind::Mod(..)
|
| hir::ItemKind::Mod(..)
|
||||||
| hir::ItemKind::ForeignMod { .. }
|
| hir::ItemKind::ForeignMod { .. }
|
||||||
| hir::ItemKind::GlobalAsm(..)
|
| hir::ItemKind::GlobalAsm(..)
|
||||||
|
@ -394,20 +394,6 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_macro_def(&mut self, macro_def: &'hir MacroDef<'hir>) {
|
|
||||||
// Exported macros are visited directly from the crate root,
|
|
||||||
// so they do not have `parent_node` set.
|
|
||||||
// Find the correct enclosing module from their DefKey.
|
|
||||||
let def_key = self.definitions.def_key(macro_def.def_id);
|
|
||||||
let parent = def_key.parent.map_or(hir::CRATE_HIR_ID, |local_def_index| {
|
|
||||||
self.definitions.local_def_id_to_hir_id(LocalDefId { local_def_index })
|
|
||||||
});
|
|
||||||
self.insert_owner(macro_def.def_id, OwnerNode::MacroDef(macro_def));
|
|
||||||
self.with_parent(parent, |this| {
|
|
||||||
this.insert_nested(macro_def.def_id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_variant(&mut self, v: &'hir Variant<'hir>, g: &'hir Generics<'hir>, item_id: HirId) {
|
fn visit_variant(&mut self, v: &'hir Variant<'hir>, g: &'hir Generics<'hir>, item_id: HirId) {
|
||||||
self.insert(v.span, v.id, Node::Variant(v));
|
self.insert(v.span, v.id, Node::Variant(v));
|
||||||
self.with_parent(v.id, |this| {
|
self.with_parent(v.id, |this| {
|
||||||
|
@ -10,7 +10,6 @@ use rustc_hir::def::{DefKind, Res};
|
|||||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||||
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
|
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
|
||||||
use rustc_hir::intravisit;
|
use rustc_hir::intravisit;
|
||||||
use rustc_hir::intravisit::Visitor;
|
|
||||||
use rustc_hir::itemlikevisit::ItemLikeVisitor;
|
use rustc_hir::itemlikevisit::ItemLikeVisitor;
|
||||||
use rustc_hir::*;
|
use rustc_hir::*;
|
||||||
use rustc_index::vec::Idx;
|
use rustc_index::vec::Idx;
|
||||||
@ -218,6 +217,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::Mod(..) => DefKind::Mod,
|
ItemKind::Mod(..) => DefKind::Mod,
|
||||||
ItemKind::OpaqueTy(..) => DefKind::OpaqueTy,
|
ItemKind::OpaqueTy(..) => DefKind::OpaqueTy,
|
||||||
ItemKind::TyAlias(..) => DefKind::TyAlias,
|
ItemKind::TyAlias(..) => DefKind::TyAlias,
|
||||||
@ -543,15 +543,6 @@ impl<'hir> Map<'hir> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn visit_exported_macros_in_krate<V>(&self, visitor: &mut V)
|
|
||||||
where
|
|
||||||
V: Visitor<'hir>,
|
|
||||||
{
|
|
||||||
for macro_def in self.krate().exported_macros() {
|
|
||||||
visitor.visit_macro_def(macro_def);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns an iterator for the nodes in the ancestor tree of the `current_id`
|
/// Returns an iterator for the nodes in the ancestor tree of the `current_id`
|
||||||
/// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
|
/// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
|
||||||
pub fn parent_iter(&self, current_id: HirId) -> ParentHirIterator<'_, 'hir> {
|
pub fn parent_iter(&self, current_id: HirId) -> ParentHirIterator<'_, 'hir> {
|
||||||
@ -1013,7 +1004,6 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
|
|||||||
source_file_names.hash_stable(&mut hcx, &mut stable_hasher);
|
source_file_names.hash_stable(&mut hcx, &mut stable_hasher);
|
||||||
tcx.sess.opts.dep_tracking_hash(true).hash_stable(&mut hcx, &mut stable_hasher);
|
tcx.sess.opts.dep_tracking_hash(true).hash_stable(&mut hcx, &mut stable_hasher);
|
||||||
tcx.sess.local_stable_crate_id().hash_stable(&mut hcx, &mut stable_hasher);
|
tcx.sess.local_stable_crate_id().hash_stable(&mut hcx, &mut stable_hasher);
|
||||||
tcx.untracked_crate.non_exported_macro_attrs.hash_stable(&mut hcx, &mut stable_hasher);
|
|
||||||
|
|
||||||
let crate_hash: Fingerprint = stable_hasher.finish();
|
let crate_hash: Fingerprint = stable_hasher.finish();
|
||||||
Svh::new(crate_hash.to_smaller_hash())
|
Svh::new(crate_hash.to_smaller_hash())
|
||||||
@ -1062,6 +1052,7 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId) -> String {
|
|||||||
ItemKind::Static(..) => "static",
|
ItemKind::Static(..) => "static",
|
||||||
ItemKind::Const(..) => "const",
|
ItemKind::Const(..) => "const",
|
||||||
ItemKind::Fn(..) => "fn",
|
ItemKind::Fn(..) => "fn",
|
||||||
|
ItemKind::Macro(..) => "macro",
|
||||||
ItemKind::Mod(..) => "mod",
|
ItemKind::Mod(..) => "mod",
|
||||||
ItemKind::ForeignMod { .. } => "foreign mod",
|
ItemKind::ForeignMod { .. } => "foreign mod",
|
||||||
ItemKind::GlobalAsm(..) => "global asm",
|
ItemKind::GlobalAsm(..) => "global asm",
|
||||||
|
@ -1149,6 +1149,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> {
|
|||||||
match item.kind {
|
match item.kind {
|
||||||
hir::ItemKind::ExternCrate(..)
|
hir::ItemKind::ExternCrate(..)
|
||||||
| hir::ItemKind::Use(..)
|
| hir::ItemKind::Use(..)
|
||||||
|
| hir::ItemKind::Macro(..)
|
||||||
| hir::ItemKind::ForeignMod { .. }
|
| hir::ItemKind::ForeignMod { .. }
|
||||||
| hir::ItemKind::TyAlias(..)
|
| hir::ItemKind::TyAlias(..)
|
||||||
| hir::ItemKind::Trait(..)
|
| hir::ItemKind::Trait(..)
|
||||||
|
@ -1723,6 +1723,16 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_item(&mut self, item: &'tcx Item<'tcx>) {
|
fn visit_item(&mut self, item: &'tcx Item<'tcx>) {
|
||||||
|
// Historically we've run more checks on non-exported than exported macros,
|
||||||
|
// so this lets us continue to run them while maintaining backwards compatibility.
|
||||||
|
// In the long run, the checks should be harmonized.
|
||||||
|
if let ItemKind::Macro(ref macro_def) = item.kind {
|
||||||
|
let def_id = item.def_id.to_def_id();
|
||||||
|
if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) {
|
||||||
|
check_non_exported_macro_for_invalid_attrs(self.tcx, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let target = Target::from_item(item);
|
let target = Target::from_item(item);
|
||||||
self.check_attributes(item.hir_id(), &item.span, target, Some(ItemLike::Item(item)));
|
self.check_attributes(item.hir_id(), &item.span, target, Some(ItemLike::Item(item)));
|
||||||
intravisit::walk_item(self, item)
|
intravisit::walk_item(self, item)
|
||||||
@ -1795,11 +1805,6 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
|
|||||||
intravisit::walk_variant(self, variant, generics, item_id)
|
intravisit::walk_variant(self, variant, generics, item_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef<'tcx>) {
|
|
||||||
self.check_attributes(macro_def.hir_id(), ¯o_def.span, Target::MacroDef, None);
|
|
||||||
intravisit::walk_macro_def(self, macro_def);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
|
fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
|
||||||
self.check_attributes(param.hir_id, ¶m.span, Target::Param, None);
|
self.check_attributes(param.hir_id, ¶m.span, Target::Param, None);
|
||||||
|
|
||||||
@ -1848,7 +1853,9 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_invalid_macro_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
|
fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) {
|
||||||
|
let attrs = tcx.hir().attrs(item.hir_id());
|
||||||
|
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
if attr.has_name(sym::inline) {
|
if attr.has_name(sym::inline) {
|
||||||
struct_span_err!(
|
struct_span_err!(
|
||||||
@ -1869,8 +1876,6 @@ fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
|
|||||||
if module_def_id.is_top_level_module() {
|
if module_def_id.is_top_level_module() {
|
||||||
check_attr_visitor.check_attributes(CRATE_HIR_ID, &DUMMY_SP, Target::Mod, None);
|
check_attr_visitor.check_attributes(CRATE_HIR_ID, &DUMMY_SP, Target::Mod, None);
|
||||||
check_invalid_crate_level_attr(tcx, tcx.hir().krate_attrs());
|
check_invalid_crate_level_attr(tcx, tcx.hir().krate_attrs());
|
||||||
tcx.hir().visit_exported_macros_in_krate(check_attr_visitor);
|
|
||||||
check_invalid_macro_level_attr(tcx, tcx.hir().krate().non_exported_macro_attrs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,10 +107,6 @@ fn diagnostic_items<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> FxHashMap<Symbol
|
|||||||
// Collect diagnostic items in this crate.
|
// Collect diagnostic items in this crate.
|
||||||
tcx.hir().krate().visit_all_item_likes(&mut collector);
|
tcx.hir().krate().visit_all_item_likes(&mut collector);
|
||||||
|
|
||||||
for m in tcx.hir().krate().exported_macros() {
|
|
||||||
collector.observe_item(m.def_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
collector.items
|
collector.items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,11 +244,6 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
|
|||||||
fn visit_attribute(&mut self, _: hir::HirId, attr: &'v ast::Attribute) {
|
fn visit_attribute(&mut self, _: hir::HirId, attr: &'v ast::Attribute) {
|
||||||
self.record("Attribute", Id::Attr(attr.id), attr);
|
self.record("Attribute", Id::Attr(attr.id), attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_macro_def(&mut self, macro_def: &'v hir::MacroDef<'v>) {
|
|
||||||
self.record("MacroDef", Id::Node(macro_def.hir_id()), macro_def);
|
|
||||||
hir_visit::walk_macro_def(self, macro_def)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
|
impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
|
||||||
|
@ -127,9 +127,7 @@ impl Visitor<'tcx> for LibFeatureCollector<'tcx> {
|
|||||||
fn get_lib_features(tcx: TyCtxt<'_>, (): ()) -> LibFeatures {
|
fn get_lib_features(tcx: TyCtxt<'_>, (): ()) -> LibFeatures {
|
||||||
let mut collector = LibFeatureCollector::new(tcx);
|
let mut collector = LibFeatureCollector::new(tcx);
|
||||||
let krate = tcx.hir().krate();
|
let krate = tcx.hir().krate();
|
||||||
for attr in krate.non_exported_macro_attrs {
|
|
||||||
collector.visit_attribute(rustc_hir::CRATE_HIR_ID, attr);
|
|
||||||
}
|
|
||||||
intravisit::walk_crate(&mut collector, krate);
|
intravisit::walk_crate(&mut collector, krate);
|
||||||
collector.lib_features
|
collector.lib_features
|
||||||
}
|
}
|
||||||
|
@ -263,6 +263,7 @@ impl<'tcx> ReachableContext<'tcx> {
|
|||||||
| hir::ItemKind::Use(..)
|
| hir::ItemKind::Use(..)
|
||||||
| hir::ItemKind::OpaqueTy(..)
|
| hir::ItemKind::OpaqueTy(..)
|
||||||
| hir::ItemKind::TyAlias(..)
|
| hir::ItemKind::TyAlias(..)
|
||||||
|
| hir::ItemKind::Macro(..)
|
||||||
| hir::ItemKind::Mod(..)
|
| hir::ItemKind::Mod(..)
|
||||||
| hir::ItemKind::ForeignMod { .. }
|
| hir::ItemKind::ForeignMod { .. }
|
||||||
| hir::ItemKind::Impl { .. }
|
| hir::ItemKind::Impl { .. }
|
||||||
|
@ -538,19 +538,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) {
|
|
||||||
self.annotate(
|
|
||||||
md.def_id,
|
|
||||||
md.span,
|
|
||||||
None,
|
|
||||||
AnnotationKind::Required,
|
|
||||||
InheritDeprecation::Yes,
|
|
||||||
InheritConstStability::No,
|
|
||||||
InheritStability::No,
|
|
||||||
|_| {},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
|
fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
|
||||||
let kind = match &p.kind {
|
let kind = match &p.kind {
|
||||||
// Allow stability attributes on default generic arguments.
|
// Allow stability attributes on default generic arguments.
|
||||||
@ -662,11 +649,6 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
|
|||||||
self.check_missing_stability(i.def_id, i.span);
|
self.check_missing_stability(i.def_id, i.span);
|
||||||
intravisit::walk_foreign_item(self, i);
|
intravisit::walk_foreign_item(self, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) {
|
|
||||||
self.check_missing_stability(md.def_id, md.span);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note that we don't need to `check_missing_stability` for default generic parameters,
|
// Note that we don't need to `check_missing_stability` for default generic parameters,
|
||||||
// as we assume that any default generic parameters without attributes are automatically
|
// as we assume that any default generic parameters without attributes are automatically
|
||||||
// stable (assuming they have not inherited instability from their parent).
|
// stable (assuming they have not inherited instability from their parent).
|
||||||
|
@ -5,6 +5,7 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rustc_middle = { path = "../rustc_middle" }
|
rustc_middle = { path = "../rustc_middle" }
|
||||||
|
rustc_ast = { path = "../rustc_ast" }
|
||||||
rustc_attr = { path = "../rustc_attr" }
|
rustc_attr = { path = "../rustc_attr" }
|
||||||
rustc_errors = { path = "../rustc_errors" }
|
rustc_errors = { path = "../rustc_errors" }
|
||||||
rustc_hir = { path = "../rustc_hir" }
|
rustc_hir = { path = "../rustc_hir" }
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#![feature(associated_type_defaults)]
|
#![feature(associated_type_defaults)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
|
use rustc_ast::MacroDef;
|
||||||
use rustc_attr as attr;
|
use rustc_attr as attr;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::struct_span_err;
|
use rustc_errors::struct_span_err;
|
||||||
@ -26,7 +27,7 @@ use rustc_middle::ty::subst::{InternalSubsts, Subst};
|
|||||||
use rustc_middle::ty::{self, Const, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, Const, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable};
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
use rustc_span::hygiene::Transparency;
|
use rustc_span::hygiene::Transparency;
|
||||||
use rustc_span::symbol::{kw, Ident};
|
use rustc_span::symbol::{kw, sym, Ident};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits::const_evaluatable::{self, AbstractConst};
|
use rustc_trait_selection::traits::const_evaluatable::{self, AbstractConst};
|
||||||
|
|
||||||
@ -462,6 +463,43 @@ impl EmbargoVisitor<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We have to make sure that the items that macros might reference
|
||||||
|
// are reachable, since they might be exported transitively.
|
||||||
|
fn update_reachability_from_macro(&mut self, local_def_id: LocalDefId, md: &MacroDef) {
|
||||||
|
// Non-opaque macros cannot make other items more accessible than they already are.
|
||||||
|
|
||||||
|
let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id);
|
||||||
|
let attrs = self.tcx.hir().attrs(hir_id);
|
||||||
|
if attr::find_transparency(&attrs, md.macro_rules).0 != Transparency::Opaque {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let item_def_id = local_def_id.to_def_id();
|
||||||
|
let macro_module_def_id =
|
||||||
|
ty::DefIdTree::parent(self.tcx, item_def_id).unwrap().expect_local();
|
||||||
|
if self.tcx.hir().opt_def_kind(macro_module_def_id) != Some(DefKind::Mod) {
|
||||||
|
// The macro's parent doesn't correspond to a `mod`, return early (#63164, #65252).
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.get(local_def_id).is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since we are starting from an externally visible module,
|
||||||
|
// all the parents in the loop below are also guaranteed to be modules.
|
||||||
|
let mut module_def_id = macro_module_def_id;
|
||||||
|
loop {
|
||||||
|
let changed_reachability =
|
||||||
|
self.update_macro_reachable(module_def_id, macro_module_def_id);
|
||||||
|
if changed_reachability || module_def_id == CRATE_DEF_ID {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
module_def_id =
|
||||||
|
ty::DefIdTree::parent(self.tcx, module_def_id.to_def_id()).unwrap().expect_local();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Updates the item as being reachable through a macro defined in the given
|
/// Updates the item as being reachable through a macro defined in the given
|
||||||
/// module. Returns `true` if the level has changed.
|
/// module. Returns `true` if the level has changed.
|
||||||
fn update_macro_reachable(
|
fn update_macro_reachable(
|
||||||
@ -511,16 +549,26 @@ impl EmbargoVisitor<'tcx> {
|
|||||||
}
|
}
|
||||||
match def_kind {
|
match def_kind {
|
||||||
// No type privacy, so can be directly marked as reachable.
|
// No type privacy, so can be directly marked as reachable.
|
||||||
DefKind::Const
|
DefKind::Const | DefKind::Static | DefKind::TraitAlias | DefKind::TyAlias => {
|
||||||
| DefKind::Macro(_)
|
|
||||||
| DefKind::Static
|
|
||||||
| DefKind::TraitAlias
|
|
||||||
| DefKind::TyAlias => {
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hygine isn't really implemented for `macro_rules!` macros at the
|
||||||
|
// moment. Accordingly, marking them as reachable is unwise. `macro` macros
|
||||||
|
// have normal hygine, so we can treat them like other items without type
|
||||||
|
// privacy and mark them reachable.
|
||||||
|
DefKind::Macro(_) => {
|
||||||
|
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
|
let item = self.tcx.hir().expect_item(hir_id);
|
||||||
|
if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }) = item.kind {
|
||||||
|
if vis.is_accessible_from(module.to_def_id(), self.tcx) {
|
||||||
|
self.update(def_id, level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We can't use a module name as the final segment of a path, except
|
// We can't use a module name as the final segment of a path, except
|
||||||
// in use statements. Since re-export checking doesn't consider
|
// in use statements. Since re-export checking doesn't consider
|
||||||
// hygiene these don't need to be marked reachable. The contents of
|
// hygiene these don't need to be marked reachable. The contents of
|
||||||
@ -644,6 +692,12 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
|||||||
hir::ItemKind::Impl { .. } => {
|
hir::ItemKind::Impl { .. } => {
|
||||||
Option::<AccessLevel>::of_impl(item.def_id, self.tcx, &self.access_levels)
|
Option::<AccessLevel>::of_impl(item.def_id, self.tcx, &self.access_levels)
|
||||||
}
|
}
|
||||||
|
// Only exported `macro_rules!` items are public, but they always are.
|
||||||
|
hir::ItemKind::Macro(MacroDef { macro_rules: true, .. }) => {
|
||||||
|
let def_id = item.def_id.to_def_id();
|
||||||
|
let is_macro_export = self.tcx.has_attr(def_id, sym::macro_export);
|
||||||
|
if is_macro_export { Some(AccessLevel::Public) } else { None }
|
||||||
|
}
|
||||||
// Foreign modules inherit level from parents.
|
// Foreign modules inherit level from parents.
|
||||||
hir::ItemKind::ForeignMod { .. } => self.prev_level,
|
hir::ItemKind::ForeignMod { .. } => self.prev_level,
|
||||||
// Other `pub` items inherit levels from parents.
|
// Other `pub` items inherit levels from parents.
|
||||||
@ -652,6 +706,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
|||||||
| hir::ItemKind::ExternCrate(..)
|
| hir::ItemKind::ExternCrate(..)
|
||||||
| hir::ItemKind::GlobalAsm(..)
|
| hir::ItemKind::GlobalAsm(..)
|
||||||
| hir::ItemKind::Fn(..)
|
| hir::ItemKind::Fn(..)
|
||||||
|
| hir::ItemKind::Macro(..)
|
||||||
| hir::ItemKind::Mod(..)
|
| hir::ItemKind::Mod(..)
|
||||||
| hir::ItemKind::Static(..)
|
| hir::ItemKind::Static(..)
|
||||||
| hir::ItemKind::Struct(..)
|
| hir::ItemKind::Struct(..)
|
||||||
@ -708,6 +763,9 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hir::ItemKind::Macro(ref macro_def) => {
|
||||||
|
self.update_reachability_from_macro(item.def_id, macro_def);
|
||||||
|
}
|
||||||
hir::ItemKind::ForeignMod { items, .. } => {
|
hir::ItemKind::ForeignMod { items, .. } => {
|
||||||
for foreign_item in items {
|
for foreign_item in items {
|
||||||
if foreign_item.vis.node.is_pub() {
|
if foreign_item.vis.node.is_pub() {
|
||||||
@ -715,6 +773,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ItemKind::OpaqueTy(..)
|
hir::ItemKind::OpaqueTy(..)
|
||||||
| hir::ItemKind::Use(..)
|
| hir::ItemKind::Use(..)
|
||||||
| hir::ItemKind::Static(..)
|
| hir::ItemKind::Static(..)
|
||||||
@ -730,7 +789,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
|||||||
// Mark all items in interfaces of reachable items as reachable.
|
// Mark all items in interfaces of reachable items as reachable.
|
||||||
match item.kind {
|
match item.kind {
|
||||||
// The interface is empty.
|
// The interface is empty.
|
||||||
hir::ItemKind::ExternCrate(..) => {}
|
hir::ItemKind::Macro(..) | hir::ItemKind::ExternCrate(..) => {}
|
||||||
// All nested items are checked by `visit_item`.
|
// All nested items are checked by `visit_item`.
|
||||||
hir::ItemKind::Mod(..) => {}
|
hir::ItemKind::Mod(..) => {}
|
||||||
// Re-exports are handled in `visit_mod`. However, in order to avoid looping over
|
// Re-exports are handled in `visit_mod`. However, in order to avoid looping over
|
||||||
@ -885,45 +944,6 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
|||||||
|
|
||||||
intravisit::walk_mod(self, m, id);
|
intravisit::walk_mod(self, m, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) {
|
|
||||||
// Non-opaque macros cannot make other items more accessible than they already are.
|
|
||||||
let attrs = self.tcx.hir().attrs(md.hir_id());
|
|
||||||
if attr::find_transparency(&attrs, md.ast.macro_rules).0 != Transparency::Opaque {
|
|
||||||
// `#[macro_export]`-ed `macro_rules!` are `Public` since they
|
|
||||||
// ignore their containing path to always appear at the crate root.
|
|
||||||
if md.ast.macro_rules {
|
|
||||||
self.update(md.def_id, Some(AccessLevel::Public));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let macro_module_def_id =
|
|
||||||
ty::DefIdTree::parent(self.tcx, md.def_id.to_def_id()).unwrap().expect_local();
|
|
||||||
if self.tcx.hir().opt_def_kind(macro_module_def_id) != Some(DefKind::Mod) {
|
|
||||||
// The macro's parent doesn't correspond to a `mod`, return early (#63164, #65252).
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let level = if md.vis.node.is_pub() { self.get(macro_module_def_id) } else { None };
|
|
||||||
let new_level = self.update(md.def_id, level);
|
|
||||||
if new_level.is_none() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since we are starting from an externally visible module,
|
|
||||||
// all the parents in the loop below are also guaranteed to be modules.
|
|
||||||
let mut module_def_id = macro_module_def_id;
|
|
||||||
loop {
|
|
||||||
let changed_reachability =
|
|
||||||
self.update_macro_reachable(module_def_id, macro_module_def_id);
|
|
||||||
if changed_reachability || module_def_id == CRATE_DEF_ID {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
module_def_id =
|
|
||||||
ty::DefIdTree::parent(self.tcx, module_def_id.to_def_id()).unwrap().expect_local();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReachEverythingInTheInterfaceVisitor<'_, 'tcx> {
|
impl ReachEverythingInTheInterfaceVisitor<'_, 'tcx> {
|
||||||
@ -1981,7 +2001,7 @@ impl<'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'tcx> {
|
|||||||
// Checked in resolve.
|
// Checked in resolve.
|
||||||
hir::ItemKind::Use(..) => {}
|
hir::ItemKind::Use(..) => {}
|
||||||
// No subitems.
|
// No subitems.
|
||||||
hir::ItemKind::GlobalAsm(..) => {}
|
hir::ItemKind::Macro(..) | hir::ItemKind::GlobalAsm(..) => {}
|
||||||
// Subitems of these items have inherited publicity.
|
// Subitems of these items have inherited publicity.
|
||||||
hir::ItemKind::Const(..)
|
hir::ItemKind::Const(..)
|
||||||
| hir::ItemKind::Static(..)
|
| hir::ItemKind::Static(..)
|
||||||
|
@ -740,6 +740,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||||||
|
|
||||||
hir::ItemKind::ExternCrate(_)
|
hir::ItemKind::ExternCrate(_)
|
||||||
| hir::ItemKind::Use(..)
|
| hir::ItemKind::Use(..)
|
||||||
|
| hir::ItemKind::Macro(..)
|
||||||
| hir::ItemKind::Mod(..)
|
| hir::ItemKind::Mod(..)
|
||||||
| hir::ItemKind::ForeignMod { .. }
|
| hir::ItemKind::ForeignMod { .. }
|
||||||
| hir::ItemKind::GlobalAsm(..) => {
|
| hir::ItemKind::GlobalAsm(..) => {
|
||||||
|
@ -416,6 +416,14 @@ impl<'hir> Sig for hir::Item<'hir> {
|
|||||||
|
|
||||||
Ok(sig)
|
Ok(sig)
|
||||||
}
|
}
|
||||||
|
hir::ItemKind::Macro(_) => {
|
||||||
|
let mut text = "macro".to_owned();
|
||||||
|
let name = self.ident.to_string();
|
||||||
|
text.push_str(&name);
|
||||||
|
text.push_str(&"! {}");
|
||||||
|
|
||||||
|
Ok(text_sig(text))
|
||||||
|
}
|
||||||
hir::ItemKind::Mod(ref _mod) => {
|
hir::ItemKind::Mod(ref _mod) => {
|
||||||
let mut text = "mod ".to_owned();
|
let mut text = "mod ".to_owned();
|
||||||
let name = self.ident.to_string();
|
let name = self.ident.to_string();
|
||||||
|
@ -746,6 +746,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::Mod(_)
|
| hir::ItemKind::Mod(_)
|
||||||
| hir::ItemKind::GlobalAsm(_) => {}
|
| hir::ItemKind::GlobalAsm(_) => {}
|
||||||
hir::ItemKind::ForeignMod { items, .. } => {
|
hir::ItemKind::ForeignMod { items, .. } => {
|
||||||
|
@ -427,6 +427,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||||||
}
|
}
|
||||||
ItemKind::Trait(..)
|
ItemKind::Trait(..)
|
||||||
| ItemKind::TraitAlias(..)
|
| ItemKind::TraitAlias(..)
|
||||||
|
| ItemKind::Macro(..)
|
||||||
| ItemKind::Mod(..)
|
| ItemKind::Mod(..)
|
||||||
| ItemKind::ForeignMod { .. }
|
| ItemKind::ForeignMod { .. }
|
||||||
| ItemKind::GlobalAsm(..)
|
| ItemKind::GlobalAsm(..)
|
||||||
|
@ -123,6 +123,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
|||||||
hir::ItemKind::Const(..)
|
hir::ItemKind::Const(..)
|
||||||
| hir::ItemKind::Enum(..)
|
| hir::ItemKind::Enum(..)
|
||||||
| hir::ItemKind::Mod(..)
|
| hir::ItemKind::Mod(..)
|
||||||
|
| hir::ItemKind::Macro(..)
|
||||||
| hir::ItemKind::Static(..)
|
| hir::ItemKind::Static(..)
|
||||||
| hir::ItemKind::Struct(..)
|
| hir::ItemKind::Struct(..)
|
||||||
| hir::ItemKind::Trait(..)
|
| hir::ItemKind::Trait(..)
|
||||||
|
Loading…
Reference in New Issue
Block a user