1
Fork 0

Auto merge of #93970 - cjgillot:novis, r=petrochenkov

Remove visibility information from HIR

The resolver exports all the necessary visibility information through the `tcx.visibility` query.
This PR stops having a dedicated visibility field in HIR, in order to use this query.
We keep a `vis_span` field for diagnostic purposes.
This commit is contained in:
bors 2022-04-23 22:25:51 +00:00
commit 143eaa8d44
45 changed files with 312 additions and 550 deletions

View file

@ -290,18 +290,6 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
self.insert(lifetime.span, lifetime.hir_id, Node::Lifetime(lifetime)); self.insert(lifetime.span, lifetime.hir_id, Node::Lifetime(lifetime));
} }
fn visit_vis(&mut self, visibility: &'hir Visibility<'hir>) {
match visibility.node {
VisibilityKind::Public | VisibilityKind::Crate(_) | VisibilityKind::Inherited => {}
VisibilityKind::Restricted { hir_id, .. } => {
self.insert(visibility.span, hir_id, Node::Visibility(visibility));
self.with_parent(hir_id, |this| {
intravisit::walk_vis(this, visibility);
});
}
}
}
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| {

View file

@ -14,7 +14,7 @@ use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
use rustc_index::vec::{Idx, IndexVec}; use rustc_index::vec::{Idx, IndexVec};
use rustc_session::utils::NtToTokenstream; use rustc_session::utils::NtToTokenstream;
use rustc_session::Session; use rustc_session::Session;
use rustc_span::source_map::{respan, DesugaringKind}; use rustc_span::source_map::DesugaringKind;
use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span; use rustc_span::Span;
use rustc_target::spec::abi; use rustc_target::spec::abi;
@ -230,15 +230,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> { fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
let mut ident = i.ident; let mut ident = i.ident;
let mut vis = self.lower_visibility(&i.vis); let vis_span = self.lower_span(i.vis.span);
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, vis_span, &i.kind);
let item = hir::Item { let item = hir::Item {
def_id: hir_id.expect_owner(), def_id: hir_id.expect_owner(),
ident: self.lower_ident(ident), ident: self.lower_ident(ident),
kind, kind,
vis, vis_span,
span: self.lower_span(i.span), span: self.lower_span(i.span),
}; };
self.arena.alloc(item) self.arena.alloc(item)
@ -251,7 +251,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir_id: hir::HirId, hir_id: hir::HirId,
ident: &mut Ident, ident: &mut Ident,
attrs: Option<&'hir [Attribute]>, attrs: Option<&'hir [Attribute]>,
vis: &mut hir::Visibility<'hir>, vis_span: Span,
i: &ItemKind, i: &ItemKind,
) -> hir::ItemKind<'hir> { ) -> hir::ItemKind<'hir> {
match *i { match *i {
@ -260,7 +260,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Start with an empty prefix. // Start with an empty prefix.
let prefix = Path { segments: vec![], span: use_tree.span, tokens: None }; let prefix = Path { segments: vec![], span: use_tree.span, tokens: None };
self.lower_use_tree(use_tree, &prefix, id, vis, ident, attrs) self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs)
} }
ItemKind::Static(ref t, m, ref e) => { ItemKind::Static(ref t, m, ref e) => {
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref()); let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
@ -527,12 +527,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
tree: &UseTree, tree: &UseTree,
prefix: &Path, prefix: &Path,
id: NodeId, id: NodeId,
vis: &mut hir::Visibility<'hir>, vis_span: Span,
ident: &mut Ident, ident: &mut Ident,
attrs: Option<&'hir [Attribute]>, attrs: Option<&'hir [Attribute]>,
) -> hir::ItemKind<'hir> { ) -> hir::ItemKind<'hir> {
debug!("lower_use_tree(tree={:?})", tree); debug!("lower_use_tree(tree={:?})", tree);
debug!("lower_use_tree: vis = {:?}", vis);
let path = &tree.prefix; let path = &tree.prefix;
let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect(); let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect();
@ -586,7 +585,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
let res = this.lower_res(res); let res = this.lower_res(res);
let path = this.lower_path_extra(res, &path, ParamMode::Explicit); let path = this.lower_path_extra(res, &path, ParamMode::Explicit);
let kind = hir::ItemKind::Use(path, hir::UseKind::Single); let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
let vis = this.rebuild_vis(&vis);
if let Some(attrs) = attrs { if let Some(attrs) = attrs {
this.attrs.insert(hir::ItemLocalId::new(0), attrs); this.attrs.insert(hir::ItemLocalId::new(0), attrs);
} }
@ -595,7 +593,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
def_id: new_id, def_id: new_id,
ident: this.lower_ident(ident), ident: this.lower_ident(ident),
kind, kind,
vis, vis_span,
span: this.lower_span(span), span: this.lower_span(span),
}; };
hir::OwnerNode::Item(this.arena.alloc(item)) hir::OwnerNode::Item(this.arena.alloc(item))
@ -657,11 +655,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
// own its own names, we have to adjust the owner before // own its own names, we have to adjust the owner before
// lowering the rest of the import. // lowering the rest of the import.
self.with_hir_id_owner(id, |this| { self.with_hir_id_owner(id, |this| {
let mut vis = this.rebuild_vis(&vis);
let mut ident = *ident; let mut ident = *ident;
let kind = let kind =
this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs); this.lower_use_tree(use_tree, &prefix, id, vis_span, &mut ident, attrs);
if let Some(attrs) = attrs { if let Some(attrs) = attrs {
this.attrs.insert(hir::ItemLocalId::new(0), attrs); this.attrs.insert(hir::ItemLocalId::new(0), attrs);
} }
@ -670,37 +667,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
def_id: new_hir_id, def_id: new_hir_id,
ident: this.lower_ident(ident), ident: this.lower_ident(ident),
kind, kind,
vis, vis_span,
span: this.lower_span(use_tree.span), span: this.lower_span(use_tree.span),
}; };
hir::OwnerNode::Item(this.arena.alloc(item)) hir::OwnerNode::Item(this.arena.alloc(item))
}); });
} }
// Subtle and a bit hacky: we lower the privacy level
// of the list stem to "private" most of the time, but
// not for "restricted" paths. The key thing is that
// we don't want it to stay as `pub` (with no caveats)
// because that affects rustdoc and also the lints
// about `pub` items. But we can't *always* make it
// private -- particularly not for restricted paths --
// because it contains node-ids that would then be
// unused, failing the check that HirIds are "densely
// assigned".
match vis.node {
hir::VisibilityKind::Public
| hir::VisibilityKind::Crate(_)
| hir::VisibilityKind::Inherited => {
*vis = respan(
self.lower_span(prefix.span.shrink_to_lo()),
hir::VisibilityKind::Inherited,
);
}
hir::VisibilityKind::Restricted { .. } => {
// Do nothing here, as described in the comment on the match.
}
}
let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err); let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err);
let res = self.lower_res(res); let res = self.lower_res(res);
let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit); let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit);
@ -709,37 +682,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
} }
/// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated
/// many times in the HIR tree; for each occurrence, we need to assign distinct
/// `NodeId`s. (See, e.g., #56128.)
fn rebuild_use_path(&mut self, path: &hir::Path<'hir>) -> &'hir hir::Path<'hir> {
debug!("rebuild_use_path(path = {:?})", path);
let segments =
self.arena.alloc_from_iter(path.segments.iter().map(|seg| hir::PathSegment {
ident: seg.ident,
hir_id: seg.hir_id.map(|_| self.next_id()),
res: seg.res,
args: None,
infer_args: seg.infer_args,
}));
self.arena.alloc(hir::Path { span: path.span, res: path.res, segments })
}
fn rebuild_vis(&mut self, vis: &hir::Visibility<'hir>) -> hir::Visibility<'hir> {
let vis_kind = match vis.node {
hir::VisibilityKind::Public => hir::VisibilityKind::Public,
hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
hir::VisibilityKind::Restricted { ref path, hir_id: _ } => {
hir::VisibilityKind::Restricted {
path: self.rebuild_use_path(path),
hir_id: self.next_id(),
}
}
};
respan(self.lower_span(vis.span), vis_kind)
}
fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> { fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
let hir_id = self.lower_node_id(i.id); let hir_id = self.lower_node_id(i.id);
let def_id = hir_id.expect_owner(); let def_id = hir_id.expect_owner();
@ -773,7 +715,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type, ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"), ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
}, },
vis: self.lower_visibility(&i.vis), vis_span: self.lower_span(i.vis.span),
span: self.lower_span(i.span), span: self.lower_span(i.span),
}; };
self.arena.alloc(item) self.arena.alloc(item)
@ -851,7 +793,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// FIXME(jseyfried): positional field hygiene. // FIXME(jseyfried): positional field hygiene.
None => Ident::new(sym::integer(index), self.lower_span(f.span)), None => Ident::new(sym::integer(index), self.lower_span(f.span)),
}, },
vis: self.lower_visibility(&f.vis), vis_span: self.lower_span(f.vis.span),
ty, ty,
} }
} }
@ -1016,8 +958,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
def_id: hir_id.expect_owner(), def_id: hir_id.expect_owner(),
ident: self.lower_ident(i.ident), ident: self.lower_ident(i.ident),
generics, generics,
vis: self.lower_visibility(&i.vis),
kind, kind,
vis_span: self.lower_span(i.vis.span),
span: self.lower_span(i.span), span: self.lower_span(i.span),
}; };
self.arena.alloc(item) self.arena.alloc(item)
@ -1044,28 +986,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
} }
/// If an `explicit_owner` is given, this method allocates the `HirId` in
/// the address space of that item instead of the item currently being
/// lowered. This can happen during `lower_impl_item_ref()` where we need to
/// lower a `Visibility` value although we haven't lowered the owning
/// `ImplItem` in question yet.
fn lower_visibility(&mut self, v: &Visibility) -> hir::Visibility<'hir> {
let node = match v.kind {
VisibilityKind::Public => hir::VisibilityKind::Public,
VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
VisibilityKind::Restricted { ref path, id } => {
debug!("lower_visibility: restricted path id = {:?}", id);
let lowered_id = self.lower_node_id(id);
hir::VisibilityKind::Restricted {
path: self.lower_path(id, path, ParamMode::Explicit),
hir_id: lowered_id,
}
}
VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
};
respan(self.lower_span(v.span), node)
}
fn lower_defaultness( fn lower_defaultness(
&self, &self,
d: Defaultness, d: Defaultness,

View file

@ -61,7 +61,7 @@ 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, MacroKind}; use rustc_span::hygiene::{ExpnId, MacroKind};
use rustc_span::source_map::{respan, DesugaringKind}; use rustc_span::source_map::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};
@ -1530,7 +1530,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
def_id: opaque_ty_id, def_id: opaque_ty_id,
ident: Ident::empty(), ident: Ident::empty(),
kind: opaque_ty_item_kind, kind: opaque_ty_item_kind,
vis: respan(self.lower_span(span.shrink_to_lo()), hir::VisibilityKind::Inherited), vis_span: self.lower_span(span.shrink_to_lo()),
span: self.lower_span(opaque_ty_span), span: self.lower_span(opaque_ty_span),
}; };
hir::OwnerNode::Item(self.arena.alloc(opaque_ty_item)) hir::OwnerNode::Item(self.arena.alloc(opaque_ty_item))

View file

@ -4,8 +4,8 @@ crate use crate::hir_id::{HirId, ItemLocalId};
use crate::intravisit::FnKind; use crate::intravisit::FnKind;
use crate::LangItem; use crate::LangItem;
use rustc_ast as ast;
use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::util::parser::ExprPrecedence;
use rustc_ast::{self as ast, CrateSugar};
use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, TraitObjectSyntax, UintTy}; use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, TraitObjectSyntax, UintTy};
pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto}; pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto};
pub use rustc_ast::{CaptureBy, Movability, Mutability}; pub use rustc_ast::{CaptureBy, Movability, Mutability};
@ -2140,10 +2140,10 @@ impl ImplItemId {
pub struct ImplItem<'hir> { pub struct ImplItem<'hir> {
pub ident: Ident, pub ident: Ident,
pub def_id: LocalDefId, pub def_id: LocalDefId,
pub vis: Visibility<'hir>,
pub generics: Generics<'hir>, pub generics: Generics<'hir>,
pub kind: ImplItemKind<'hir>, pub kind: ImplItemKind<'hir>,
pub span: Span, pub span: Span,
pub vis_span: Span,
} }
impl ImplItem<'_> { impl ImplItem<'_> {
@ -2645,34 +2645,11 @@ pub struct PolyTraitRef<'hir> {
pub span: Span, pub span: Span,
} }
pub type Visibility<'hir> = Spanned<VisibilityKind<'hir>>;
#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub enum VisibilityKind<'hir> {
Public,
Crate(CrateSugar),
Restricted { path: &'hir Path<'hir>, hir_id: HirId },
Inherited,
}
impl VisibilityKind<'_> {
pub fn is_pub(&self) -> bool {
matches!(*self, VisibilityKind::Public)
}
pub fn is_pub_restricted(&self) -> bool {
match *self {
VisibilityKind::Public | VisibilityKind::Inherited => false,
VisibilityKind::Crate(..) | VisibilityKind::Restricted { .. } => true,
}
}
}
#[derive(Debug, HashStable_Generic)] #[derive(Debug, HashStable_Generic)]
pub struct FieldDef<'hir> { pub struct FieldDef<'hir> {
pub span: Span, pub span: Span,
pub vis_span: Span,
pub ident: Ident, pub ident: Ident,
pub vis: Visibility<'hir>,
pub hir_id: HirId, pub hir_id: HirId,
pub ty: &'hir Ty<'hir>, pub ty: &'hir Ty<'hir>,
} }
@ -2744,8 +2721,8 @@ pub struct Item<'hir> {
pub ident: Ident, pub ident: Ident,
pub def_id: LocalDefId, pub def_id: LocalDefId,
pub kind: ItemKind<'hir>, pub kind: ItemKind<'hir>,
pub vis: Visibility<'hir>,
pub span: Span, pub span: Span,
pub vis_span: Span,
} }
impl Item<'_> { impl Item<'_> {
@ -3002,7 +2979,7 @@ pub struct ForeignItem<'hir> {
pub kind: ForeignItemKind<'hir>, pub kind: ForeignItemKind<'hir>,
pub def_id: LocalDefId, pub def_id: LocalDefId,
pub span: Span, pub span: Span,
pub vis: Visibility<'hir>, pub vis_span: Span,
} }
impl ForeignItem<'_> { impl ForeignItem<'_> {
@ -3210,7 +3187,6 @@ pub enum Node<'hir> {
Lifetime(&'hir Lifetime), Lifetime(&'hir Lifetime),
GenericParam(&'hir GenericParam<'hir>), GenericParam(&'hir GenericParam<'hir>),
Visibility(&'hir Visibility<'hir>),
Crate(&'hir Mod<'hir>), Crate(&'hir Mod<'hir>),
@ -3253,7 +3229,6 @@ impl<'hir> Node<'hir> {
| Node::Binding(..) | Node::Binding(..)
| Node::Arm(..) | Node::Arm(..)
| Node::Local(..) | Node::Local(..)
| Node::Visibility(..)
| Node::Crate(..) | Node::Crate(..)
| Node::Ty(..) | Node::Ty(..)
| Node::TraitRef(..) | Node::TraitRef(..)
@ -3318,18 +3293,18 @@ impl<'hir> Node<'hir> {
match self { match self {
Node::Item(i) => match i.kind { Node::Item(i) => match i.kind {
ItemKind::Fn(ref sig, ref generics, _) => { ItemKind::Fn(ref sig, ref generics, _) => {
Some(FnKind::ItemFn(i.ident, generics, sig.header, &i.vis)) Some(FnKind::ItemFn(i.ident, generics, sig.header))
} }
_ => None, _ => None,
}, },
Node::TraitItem(ti) => match ti.kind { Node::TraitItem(ti) => match ti.kind {
TraitItemKind::Fn(ref sig, TraitFn::Provided(_)) => { TraitItemKind::Fn(ref sig, TraitFn::Provided(_)) => {
Some(FnKind::Method(ti.ident, sig, None)) Some(FnKind::Method(ti.ident, sig))
} }
_ => None, _ => None,
}, },
Node::ImplItem(ii) => match ii.kind { Node::ImplItem(ii) => match ii.kind {
ImplItemKind::Fn(ref sig, _) => Some(FnKind::Method(ii.ident, sig, Some(&ii.vis))), ImplItemKind::Fn(ref sig, _) => Some(FnKind::Method(ii.ident, sig)),
_ => None, _ => None,
}, },
Node::Expr(e) => match e.kind { Node::Expr(e) => match e.kind {
@ -3350,8 +3325,8 @@ mod size_asserts {
rustc_data_structures::static_assert_size!(super::QPath<'static>, 24); rustc_data_structures::static_assert_size!(super::QPath<'static>, 24);
rustc_data_structures::static_assert_size!(super::Ty<'static>, 72); rustc_data_structures::static_assert_size!(super::Ty<'static>, 72);
rustc_data_structures::static_assert_size!(super::Item<'static>, 184); rustc_data_structures::static_assert_size!(super::Item<'static>, 160);
rustc_data_structures::static_assert_size!(super::TraitItem<'static>, 128); rustc_data_structures::static_assert_size!(super::TraitItem<'static>, 128);
rustc_data_structures::static_assert_size!(super::ImplItem<'static>, 144); rustc_data_structures::static_assert_size!(super::ImplItem<'static>, 120);
rustc_data_structures::static_assert_size!(super::ForeignItem<'static>, 136); rustc_data_structures::static_assert_size!(super::ForeignItem<'static>, 112);
} }

View file

@ -100,10 +100,10 @@ where
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub enum FnKind<'a> { pub enum FnKind<'a> {
/// `#[xxx] pub async/const/extern "Abi" fn foo()` /// `#[xxx] pub async/const/extern "Abi" fn foo()`
ItemFn(Ident, &'a Generics<'a>, FnHeader, &'a Visibility<'a>), ItemFn(Ident, &'a Generics<'a>, FnHeader),
/// `fn foo(&self)` /// `fn foo(&self)`
Method(Ident, &'a FnSig<'a>, Option<&'a Visibility<'a>>), Method(Ident, &'a FnSig<'a>),
/// `|x, y| {}` /// `|x, y| {}`
Closure, Closure,
@ -112,8 +112,8 @@ pub enum FnKind<'a> {
impl<'a> FnKind<'a> { impl<'a> FnKind<'a> {
pub fn header(&self) -> Option<&FnHeader> { pub fn header(&self) -> Option<&FnHeader> {
match *self { match *self {
FnKind::ItemFn(_, _, ref header, _) => Some(header), FnKind::ItemFn(_, _, ref header) => Some(header),
FnKind::Method(_, ref sig, _) => Some(&sig.header), FnKind::Method(_, ref sig) => Some(&sig.header),
FnKind::Closure => None, FnKind::Closure => None,
} }
} }
@ -475,9 +475,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_vis(&mut self, vis: &'v Visibility<'v>) {
walk_vis(self, vis)
}
fn visit_associated_item_kind(&mut self, kind: &'v AssocItemKind) { fn visit_associated_item_kind(&mut self, kind: &'v AssocItemKind) {
walk_associated_item_kind(self, kind); walk_associated_item_kind(self, kind);
} }
@ -554,7 +551,6 @@ pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) {
} }
pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
visitor.visit_vis(&item.vis);
visitor.visit_ident(item.ident); visitor.visit_ident(item.ident);
match item.kind { match item.kind {
ItemKind::ExternCrate(orig_name) => { ItemKind::ExternCrate(orig_name) => {
@ -572,7 +568,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
visitor.visit_nested_body(body); visitor.visit_nested_body(body);
} }
ItemKind::Fn(ref sig, ref generics, body_id) => visitor.visit_fn( ItemKind::Fn(ref sig, ref generics, body_id) => visitor.visit_fn(
FnKind::ItemFn(item.ident, generics, sig.header, &item.vis), FnKind::ItemFn(item.ident, generics, sig.header),
&sig.decl, &sig.decl,
body_id, body_id,
item.span, item.span,
@ -859,7 +855,6 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) {
pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem<'v>) { pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem<'v>) {
visitor.visit_id(foreign_item.hir_id()); visitor.visit_id(foreign_item.hir_id());
visitor.visit_vis(&foreign_item.vis);
visitor.visit_ident(foreign_item.ident); visitor.visit_ident(foreign_item.ident);
match foreign_item.kind { match foreign_item.kind {
@ -999,7 +994,7 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
} }
TraitItemKind::Fn(ref sig, TraitFn::Provided(body_id)) => { TraitItemKind::Fn(ref sig, TraitFn::Provided(body_id)) => {
visitor.visit_fn( visitor.visit_fn(
FnKind::Method(trait_item.ident, sig, None), FnKind::Method(trait_item.ident, sig),
&sig.decl, &sig.decl,
body_id, body_id,
trait_item.span, trait_item.span,
@ -1025,10 +1020,9 @@ pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_item_ref:
pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem<'v>) { pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem<'v>) {
// N.B., deliberately force a compilation error if/when new fields are added. // N.B., deliberately force a compilation error if/when new fields are added.
let ImplItem { def_id: _, ident, ref vis, ref generics, ref kind, span: _ } = *impl_item; let ImplItem { def_id: _, ident, ref generics, ref kind, span: _, vis_span: _ } = *impl_item;
visitor.visit_ident(ident); visitor.visit_ident(ident);
visitor.visit_vis(vis);
visitor.visit_generics(generics); visitor.visit_generics(generics);
match *kind { match *kind {
ImplItemKind::Const(ref ty, body) => { ImplItemKind::Const(ref ty, body) => {
@ -1038,7 +1032,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
} }
ImplItemKind::Fn(ref sig, body_id) => { ImplItemKind::Fn(ref sig, body_id) => {
visitor.visit_fn( visitor.visit_fn(
FnKind::Method(impl_item.ident, sig, Some(&impl_item.vis)), FnKind::Method(impl_item.ident, sig),
&sig.decl, &sig.decl,
body_id, body_id,
impl_item.span, impl_item.span,
@ -1082,7 +1076,6 @@ pub fn walk_struct_def<'v, V: Visitor<'v>>(
pub fn walk_field_def<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v FieldDef<'v>) { pub fn walk_field_def<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v FieldDef<'v>) {
visitor.visit_id(field.hir_id); visitor.visit_id(field.hir_id);
visitor.visit_vis(&field.vis);
visitor.visit_ident(field.ident); visitor.visit_ident(field.ident);
visitor.visit_ty(&field.ty); visitor.visit_ty(&field.ty);
} }
@ -1250,13 +1243,6 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) {
visitor.visit_expr(&arm.body); visitor.visit_expr(&arm.body);
} }
pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility<'v>) {
if let VisibilityKind::Restricted { ref path, hir_id } = vis.node {
visitor.visit_id(hir_id);
visitor.visit_path(path, hir_id)
}
}
pub fn walk_associated_item_kind<'v, V: Visitor<'v>>(_: &mut V, _: &'v AssocItemKind) { pub fn walk_associated_item_kind<'v, V: Visitor<'v>>(_: &mut V, _: &'v AssocItemKind) {
// No visitable content here: this fn exists so you can call it if // No visitable content here: this fn exists so you can call it if
// the right thing to do, should content be added in the future, // the right thing to do, should content be added in the future,

View file

@ -8,12 +8,11 @@ use rustc_ast_pretty::pprust::{Comments, PrintState};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::{GenericArg, GenericParam, GenericParamKind, Node, Term}; use rustc_hir::{GenericArg, GenericParam, GenericParamKind, Node, Term};
use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier}; use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier};
use rustc_span::source_map::{SourceMap, Spanned}; use rustc_span::source_map::SourceMap;
use rustc_span::symbol::{kw, Ident, IdentPrinter, Symbol}; use rustc_span::symbol::{kw, Ident, IdentPrinter, Symbol};
use rustc_span::{self, FileName}; use rustc_span::{self, FileName};
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
use std::borrow::Cow;
use std::cell::Cell; use std::cell::Cell;
use std::vec; use std::vec;
@ -98,7 +97,6 @@ impl<'a> State<'a> {
self.print_block(&a) self.print_block(&a)
} }
Node::Lifetime(a) => self.print_lifetime(&a), Node::Lifetime(a) => self.print_lifetime(&a),
Node::Visibility(a) => self.print_visibility(&a),
Node::GenericParam(_) => panic!("cannot print Node::GenericParam"), Node::GenericParam(_) => panic!("cannot print Node::GenericParam"),
Node::Field(_) => panic!("cannot print Node::Field"), Node::Field(_) => panic!("cannot print Node::Field"),
// These cases do not carry enough information in the // These cases do not carry enough information in the
@ -191,13 +189,6 @@ where
printer.s.eof() printer.s.eof()
} }
pub fn visibility_qualified<S: Into<Cow<'static, str>>>(vis: &hir::Visibility<'_>, w: S) -> String {
to_string(NO_ANN, |s| {
s.print_visibility(vis);
s.word(w)
})
}
pub fn generic_params_to_string(generic_params: &[GenericParam<'_>]) -> String { pub fn generic_params_to_string(generic_params: &[GenericParam<'_>]) -> String {
to_string(NO_ANN, |s| s.print_generic_params(generic_params)) to_string(NO_ANN, |s| s.print_generic_params(generic_params))
} }
@ -223,11 +214,10 @@ pub fn fn_to_string(
header: hir::FnHeader, header: hir::FnHeader,
name: Option<Symbol>, name: Option<Symbol>,
generics: &hir::Generics<'_>, generics: &hir::Generics<'_>,
vis: &hir::Visibility<'_>,
arg_names: &[Ident], arg_names: &[Ident],
body_id: Option<hir::BodyId>, body_id: Option<hir::BodyId>,
) -> String { ) -> String {
to_string(NO_ANN, |s| s.print_fn(decl, header, name, generics, vis, arg_names, body_id)) to_string(NO_ANN, |s| s.print_fn(decl, header, name, generics, arg_names, body_id))
} }
pub fn enum_def_to_string( pub fn enum_def_to_string(
@ -235,9 +225,8 @@ pub fn enum_def_to_string(
generics: &hir::Generics<'_>, generics: &hir::Generics<'_>,
name: Symbol, name: Symbol,
span: rustc_span::Span, span: rustc_span::Span,
visibility: &hir::Visibility<'_>,
) -> String { ) -> String {
to_string(NO_ANN, |s| s.print_enum_def(enum_definition, generics, name, span, visibility)) to_string(NO_ANN, |s| s.print_enum_def(enum_definition, generics, name, span))
} }
impl<'a> State<'a> { impl<'a> State<'a> {
@ -395,7 +384,6 @@ impl<'a> State<'a> {
}, },
Some(item.ident.name), Some(item.ident.name),
generics, generics,
&item.vis,
arg_names, arg_names,
None, None,
); );
@ -404,7 +392,7 @@ impl<'a> State<'a> {
self.end() // end the outer fn box self.end() // end the outer fn box
} }
hir::ForeignItemKind::Static(ref t, m) => { hir::ForeignItemKind::Static(ref t, m) => {
self.head(visibility_qualified(&item.vis, "static")); self.head("static");
if m == hir::Mutability::Mut { if m == hir::Mutability::Mut {
self.word_space("mut"); self.word_space("mut");
} }
@ -416,7 +404,7 @@ impl<'a> State<'a> {
self.end() // end the outer cbox self.end() // end the outer cbox
} }
hir::ForeignItemKind::Type => { hir::ForeignItemKind::Type => {
self.head(visibility_qualified(&item.vis, "type")); self.head("type");
self.print_ident(item.ident); self.print_ident(item.ident);
self.word(";"); self.word(";");
self.end(); // end the head-ibox self.end(); // end the head-ibox
@ -430,9 +418,8 @@ impl<'a> State<'a> {
ident: Ident, ident: Ident,
ty: &hir::Ty<'_>, ty: &hir::Ty<'_>,
default: Option<hir::BodyId>, default: Option<hir::BodyId>,
vis: &hir::Visibility<'_>,
) { ) {
self.word(visibility_qualified(vis, "")); self.head("");
self.word_space("const"); self.word_space("const");
self.print_ident(ident); self.print_ident(ident);
self.word_space(":"); self.word_space(":");
@ -473,7 +460,7 @@ impl<'a> State<'a> {
generics: &hir::Generics<'_>, generics: &hir::Generics<'_>,
inner: impl Fn(&mut Self), inner: impl Fn(&mut Self),
) { ) {
self.head(visibility_qualified(&item.vis, "type")); self.head("type");
self.print_ident(item.ident); self.print_ident(item.ident);
self.print_generic_params(&generics.params); self.print_generic_params(&generics.params);
self.end(); // end the inner ibox self.end(); // end the inner ibox
@ -494,7 +481,7 @@ impl<'a> State<'a> {
self.ann.pre(self, AnnNode::Item(item)); self.ann.pre(self, AnnNode::Item(item));
match item.kind { match item.kind {
hir::ItemKind::ExternCrate(orig_name) => { hir::ItemKind::ExternCrate(orig_name) => {
self.head(visibility_qualified(&item.vis, "extern crate")); self.head("extern crate");
if let Some(orig_name) = orig_name { if let Some(orig_name) = orig_name {
self.print_name(orig_name); self.print_name(orig_name);
self.space(); self.space();
@ -507,7 +494,7 @@ impl<'a> State<'a> {
self.end(); // end outer head-block self.end(); // end outer head-block
} }
hir::ItemKind::Use(ref path, kind) => { hir::ItemKind::Use(ref path, kind) => {
self.head(visibility_qualified(&item.vis, "use")); self.head("use");
self.print_path(path, false); self.print_path(path, false);
match kind { match kind {
@ -526,7 +513,7 @@ impl<'a> State<'a> {
self.end(); // end outer head-block self.end(); // end outer head-block
} }
hir::ItemKind::Static(ref ty, m, expr) => { hir::ItemKind::Static(ref ty, m, expr) => {
self.head(visibility_qualified(&item.vis, "static")); self.head("static");
if m == hir::Mutability::Mut { if m == hir::Mutability::Mut {
self.word_space("mut"); self.word_space("mut");
} }
@ -542,7 +529,7 @@ impl<'a> State<'a> {
self.end(); // end the outer cbox self.end(); // end the outer cbox
} }
hir::ItemKind::Const(ref ty, expr) => { hir::ItemKind::Const(ref ty, expr) => {
self.head(visibility_qualified(&item.vis, "const")); self.head("const");
self.print_ident(item.ident); self.print_ident(item.ident);
self.word_space(":"); self.word_space(":");
self.print_type(&ty); self.print_type(&ty);
@ -561,7 +548,6 @@ impl<'a> State<'a> {
sig.header, sig.header,
Some(item.ident.name), Some(item.ident.name),
param_names, param_names,
&item.vis,
&[], &[],
Some(body), Some(body),
); );
@ -571,12 +557,10 @@ impl<'a> State<'a> {
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.print_visibility(&item.vis)
});
} }
hir::ItemKind::Mod(ref _mod) => { hir::ItemKind::Mod(ref _mod) => {
self.head(visibility_qualified(&item.vis, "mod")); self.head("mod");
self.print_ident(item.ident); self.print_ident(item.ident);
self.nbsp(); self.nbsp();
self.bopen(); self.bopen();
@ -594,7 +578,7 @@ impl<'a> State<'a> {
self.bclose(item.span); self.bclose(item.span);
} }
hir::ItemKind::GlobalAsm(ref asm) => { hir::ItemKind::GlobalAsm(ref asm) => {
self.head(visibility_qualified(&item.vis, "global_asm!")); self.head("global_asm!");
self.print_inline_asm(asm); self.print_inline_asm(asm);
self.end() self.end()
} }
@ -620,14 +604,14 @@ impl<'a> State<'a> {
}); });
} }
hir::ItemKind::Enum(ref enum_definition, ref params) => { hir::ItemKind::Enum(ref enum_definition, ref params) => {
self.print_enum_def(enum_definition, params, item.ident.name, item.span, &item.vis); self.print_enum_def(enum_definition, params, item.ident.name, item.span);
} }
hir::ItemKind::Struct(ref struct_def, ref generics) => { hir::ItemKind::Struct(ref struct_def, ref generics) => {
self.head(visibility_qualified(&item.vis, "struct")); self.head("struct");
self.print_struct(struct_def, generics, item.ident.name, item.span, true); self.print_struct(struct_def, generics, item.ident.name, item.span, true);
} }
hir::ItemKind::Union(ref struct_def, ref generics) => { hir::ItemKind::Union(ref struct_def, ref generics) => {
self.head(visibility_qualified(&item.vis, "union")); self.head("union");
self.print_struct(struct_def, generics, item.ident.name, item.span, true); self.print_struct(struct_def, generics, item.ident.name, item.span, true);
} }
hir::ItemKind::Impl(hir::Impl { hir::ItemKind::Impl(hir::Impl {
@ -642,7 +626,6 @@ impl<'a> State<'a> {
items, items,
}) => { }) => {
self.head(""); self.head("");
self.print_visibility(&item.vis);
self.print_defaultness(defaultness); self.print_defaultness(defaultness);
self.print_unsafety(unsafety); self.print_unsafety(unsafety);
self.word_nbsp("impl"); self.word_nbsp("impl");
@ -679,7 +662,6 @@ impl<'a> State<'a> {
} }
hir::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, trait_items) => { hir::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, trait_items) => {
self.head(""); self.head("");
self.print_visibility(&item.vis);
self.print_is_auto(is_auto); self.print_is_auto(is_auto);
self.print_unsafety(unsafety); self.print_unsafety(unsafety);
self.word_nbsp("trait"); self.word_nbsp("trait");
@ -705,7 +687,7 @@ impl<'a> State<'a> {
self.bclose(item.span); self.bclose(item.span);
} }
hir::ItemKind::TraitAlias(ref generics, ref bounds) => { hir::ItemKind::TraitAlias(ref generics, ref bounds) => {
self.head(visibility_qualified(&item.vis, "trait")); self.head("trait");
self.print_ident(item.ident); self.print_ident(item.ident);
self.print_generic_params(&generics.params); self.print_generic_params(&generics.params);
let mut real_bounds = Vec::with_capacity(bounds.len()); let mut real_bounds = Vec::with_capacity(bounds.len());
@ -753,9 +735,8 @@ impl<'a> State<'a> {
generics: &hir::Generics<'_>, generics: &hir::Generics<'_>,
name: Symbol, name: Symbol,
span: rustc_span::Span, span: rustc_span::Span,
visibility: &hir::Visibility<'_>,
) { ) {
self.head(visibility_qualified(visibility, "enum")); self.head("enum");
self.print_name(name); self.print_name(name);
self.print_generic_params(&generics.params); self.print_generic_params(&generics.params);
self.print_where_clause(&generics.where_clause); self.print_where_clause(&generics.where_clause);
@ -778,27 +759,6 @@ impl<'a> State<'a> {
self.bclose(span) self.bclose(span)
} }
pub fn print_visibility(&mut self, vis: &hir::Visibility<'_>) {
match vis.node {
hir::VisibilityKind::Public => self.word_nbsp("pub"),
hir::VisibilityKind::Crate(ast::CrateSugar::JustCrate) => self.word_nbsp("crate"),
hir::VisibilityKind::Crate(ast::CrateSugar::PubCrate) => self.word_nbsp("pub(crate)"),
hir::VisibilityKind::Restricted { ref path, .. } => {
self.word("pub(");
if path.segments.len() == 1 && path.segments[0].ident.name == kw::Super {
// Special case: `super` can print like `pub(super)`.
self.word("super");
} else {
// Everything else requires `in` at present.
self.word_nbsp("in");
self.print_path(path, false);
}
self.word_nbsp(")");
}
hir::VisibilityKind::Inherited => (),
}
}
pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) { pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) {
match defaultness { match defaultness {
hir::Defaultness::Default { .. } => self.word_nbsp("default"), hir::Defaultness::Default { .. } => self.word_nbsp("default"),
@ -823,7 +783,6 @@ impl<'a> State<'a> {
self.commasep(Inconsistent, struct_def.fields(), |s, field| { self.commasep(Inconsistent, struct_def.fields(), |s, field| {
s.maybe_print_comment(field.span.lo()); s.maybe_print_comment(field.span.lo());
s.print_outer_attributes(s.attrs(field.hir_id)); s.print_outer_attributes(s.attrs(field.hir_id));
s.print_visibility(&field.vis);
s.print_type(&field.ty) s.print_type(&field.ty)
}); });
self.pclose(); self.pclose();
@ -845,7 +804,6 @@ impl<'a> State<'a> {
self.hardbreak_if_not_bol(); self.hardbreak_if_not_bol();
self.maybe_print_comment(field.span.lo()); self.maybe_print_comment(field.span.lo());
self.print_outer_attributes(self.attrs(field.hir_id)); self.print_outer_attributes(self.attrs(field.hir_id));
self.print_visibility(&field.vis);
self.print_ident(field.ident); self.print_ident(field.ident);
self.word_nbsp(":"); self.word_nbsp(":");
self.print_type(&field.ty); self.print_type(&field.ty);
@ -872,11 +830,10 @@ impl<'a> State<'a> {
ident: Ident, ident: Ident,
m: &hir::FnSig<'_>, m: &hir::FnSig<'_>,
generics: &hir::Generics<'_>, generics: &hir::Generics<'_>,
vis: &hir::Visibility<'_>,
arg_names: &[Ident], arg_names: &[Ident],
body_id: Option<hir::BodyId>, body_id: Option<hir::BodyId>,
) { ) {
self.print_fn(&m.decl, m.header, Some(ident.name), generics, vis, arg_names, body_id) self.print_fn(&m.decl, m.header, Some(ident.name), generics, arg_names, body_id)
} }
pub fn print_trait_item(&mut self, ti: &hir::TraitItem<'_>) { pub fn print_trait_item(&mut self, ti: &hir::TraitItem<'_>) {
@ -886,21 +843,15 @@ impl<'a> State<'a> {
self.print_outer_attributes(self.attrs(ti.hir_id())); self.print_outer_attributes(self.attrs(ti.hir_id()));
match ti.kind { match ti.kind {
hir::TraitItemKind::Const(ref ty, default) => { hir::TraitItemKind::Const(ref ty, default) => {
let vis = self.print_associated_const(ti.ident, &ty, default);
Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Inherited };
self.print_associated_const(ti.ident, &ty, default, &vis);
} }
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(ref arg_names)) => { hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(ref arg_names)) => {
let vis = self.print_method_sig(ti.ident, sig, &ti.generics, arg_names, None);
Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Inherited };
self.print_method_sig(ti.ident, sig, &ti.generics, &vis, arg_names, None);
self.word(";"); self.word(";");
} }
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => { hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
let vis =
Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Inherited };
self.head(""); self.head("");
self.print_method_sig(ti.ident, sig, &ti.generics, &vis, &[], Some(body)); self.print_method_sig(ti.ident, sig, &ti.generics, &[], Some(body));
self.nbsp(); self.nbsp();
self.end(); // need to close a box self.end(); // need to close a box
self.end(); // need to close a box self.end(); // need to close a box
@ -926,11 +877,11 @@ impl<'a> State<'a> {
match ii.kind { match ii.kind {
hir::ImplItemKind::Const(ref ty, expr) => { hir::ImplItemKind::Const(ref ty, expr) => {
self.print_associated_const(ii.ident, &ty, Some(expr), &ii.vis); self.print_associated_const(ii.ident, &ty, Some(expr));
} }
hir::ImplItemKind::Fn(ref sig, body) => { hir::ImplItemKind::Fn(ref sig, body) => {
self.head(""); self.head("");
self.print_method_sig(ii.ident, sig, &ii.generics, &ii.vis, &[], Some(body)); self.print_method_sig(ii.ident, sig, &ii.generics, &[], Some(body));
self.nbsp(); self.nbsp();
self.end(); // need to close a box self.end(); // need to close a box
self.end(); // need to close a box self.end(); // need to close a box
@ -2008,11 +1959,10 @@ impl<'a> State<'a> {
header: hir::FnHeader, header: hir::FnHeader,
name: Option<Symbol>, name: Option<Symbol>,
generics: &hir::Generics<'_>, generics: &hir::Generics<'_>,
vis: &hir::Visibility<'_>,
arg_names: &[Ident], arg_names: &[Ident],
body_id: Option<hir::BodyId>, body_id: Option<hir::BodyId>,
) { ) {
self.print_fn_header_info(header, vis); self.print_fn_header_info(header);
if let Some(name) = name { if let Some(name) = name {
self.nbsp(); self.nbsp();
@ -2301,16 +2251,13 @@ impl<'a> State<'a> {
}, },
name, name,
&generics, &generics,
&Spanned { span: rustc_span::DUMMY_SP, node: hir::VisibilityKind::Inherited },
arg_names, arg_names,
None, None,
); );
self.end(); self.end();
} }
pub fn print_fn_header_info(&mut self, header: hir::FnHeader, vis: &hir::Visibility<'_>) { pub fn print_fn_header_info(&mut self, header: hir::FnHeader) {
self.word(visibility_qualified(vis, ""));
match header.constness { match header.constness {
hir::Constness::NotConst => {} hir::Constness::NotConst => {}
hir::Constness::Const => self.word_nbsp("const"), hir::Constness::Const => self.word_nbsp("const"),

View file

@ -36,8 +36,7 @@ use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, Gate
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID}; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID};
use rustc_hir::{ForeignItemKind, GenericParamKind, PatKind}; use rustc_hir::{ForeignItemKind, GenericParamKind, HirId, PatKind};
use rustc_hir::{HirId, Node};
use rustc_index::vec::Idx; use rustc_index::vec::Idx;
use rustc_middle::lint::LintDiagnosticBuilder; use rustc_middle::lint::LintDiagnosticBuilder;
use rustc_middle::ty::layout::{LayoutError, LayoutOf}; use rustc_middle::ty::layout::{LayoutError, LayoutOf};
@ -487,9 +486,6 @@ declare_lint! {
pub struct MissingDoc { pub struct MissingDoc {
/// Stack of whether `#[doc(hidden)]` is set at each level which has lint attributes. /// Stack of whether `#[doc(hidden)]` is set at each level which has lint attributes.
doc_hidden_stack: Vec<bool>, doc_hidden_stack: Vec<bool>,
/// Private traits or trait items that leaked through. Don't check their methods.
private_traits: FxHashSet<hir::HirId>,
} }
impl_lint_pass!(MissingDoc => [MISSING_DOCS]); impl_lint_pass!(MissingDoc => [MISSING_DOCS]);
@ -520,7 +516,7 @@ fn has_doc(attr: &ast::Attribute) -> bool {
impl MissingDoc { impl MissingDoc {
pub fn new() -> MissingDoc { pub fn new() -> MissingDoc {
MissingDoc { doc_hidden_stack: vec![false], private_traits: FxHashSet::default() } MissingDoc { doc_hidden_stack: vec![false] }
} }
fn doc_hidden(&self) -> bool { fn doc_hidden(&self) -> bool {
@ -598,30 +594,16 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
match it.kind { match it.kind {
hir::ItemKind::Trait(.., trait_item_refs) => { hir::ItemKind::Trait(..) => {
// Issue #11592: traits are always considered exported, even when private. // Issue #11592: traits are always considered exported, even when private.
if let hir::VisibilityKind::Inherited = it.vis.node { if cx.tcx.visibility(it.def_id)
self.private_traits.insert(it.hir_id()); == ty::Visibility::Restricted(
for trait_item_ref in trait_item_refs { cx.tcx.parent_module_from_def_id(it.def_id).to_def_id(),
self.private_traits.insert(trait_item_ref.id.hir_id()); )
} {
return; return;
} }
} }
hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), items, .. }) => {
// If the trait is private, add the impl items to `private_traits` so they don't get
// reported for missing docs.
let real_trait = trait_ref.path.res.def_id();
let Some(def_id) = real_trait.as_local() else { return };
let Some(Node::Item(item)) = cx.tcx.hir().find_by_def_id(def_id) else { return };
if let hir::VisibilityKind::Inherited = item.vis.node {
for impl_item_ref in items {
self.private_traits.insert(impl_item_ref.id.hir_id());
}
}
return;
}
hir::ItemKind::TyAlias(..) hir::ItemKind::TyAlias(..)
| hir::ItemKind::Fn(..) | hir::ItemKind::Fn(..)
| hir::ItemKind::Macro(..) | hir::ItemKind::Macro(..)
@ -641,10 +623,6 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
} }
fn check_trait_item(&mut self, cx: &LateContext<'_>, trait_item: &hir::TraitItem<'_>) { fn check_trait_item(&mut self, cx: &LateContext<'_>, trait_item: &hir::TraitItem<'_>) {
if self.private_traits.contains(&trait_item.hir_id()) {
return;
}
let (article, desc) = cx.tcx.article_and_description(trait_item.def_id.to_def_id()); let (article, desc) = cx.tcx.article_and_description(trait_item.def_id.to_def_id());
self.check_missing_docs_attrs(cx, trait_item.def_id, trait_item.span, article, desc); self.check_missing_docs_attrs(cx, trait_item.def_id, trait_item.span, article, desc);
@ -1384,14 +1362,13 @@ impl UnreachablePub {
cx: &LateContext<'_>, cx: &LateContext<'_>,
what: &str, what: &str,
def_id: LocalDefId, def_id: LocalDefId,
vis: &hir::Visibility<'_>,
span: Span, span: Span,
vis_span: Span,
exportable: bool, exportable: bool,
) { ) {
let mut applicability = Applicability::MachineApplicable; let mut applicability = Applicability::MachineApplicable;
match vis.node { if cx.tcx.visibility(def_id).is_public() && !cx.access_levels.is_reachable(def_id) {
hir::VisibilityKind::Public if !cx.access_levels.is_reachable(def_id) => { if vis_span.from_expansion() {
if span.from_expansion() {
applicability = Applicability::MaybeIncorrect; applicability = Applicability::MaybeIncorrect;
} }
let def_span = cx.tcx.sess.source_map().guess_head_span(span); let def_span = cx.tcx.sess.source_map().guess_head_span(span);
@ -1405,7 +1382,7 @@ impl UnreachablePub {
.to_owned(); .to_owned();
err.span_suggestion( err.span_suggestion(
vis.span, vis_span,
"consider restricting its visibility", "consider restricting its visibility",
replacement, replacement,
applicability, applicability,
@ -1416,14 +1393,16 @@ impl UnreachablePub {
err.emit(); err.emit();
}); });
} }
_ => {}
}
} }
} }
impl<'tcx> LateLintPass<'tcx> for UnreachablePub { impl<'tcx> LateLintPass<'tcx> for UnreachablePub {
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) { fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
self.perform_lint(cx, "item", item.def_id, &item.vis, item.span, true); // Do not warn for fake `use` statements.
if let hir::ItemKind::Use(_, hir::UseKind::ListStem) = &item.kind {
return;
}
self.perform_lint(cx, "item", item.def_id, item.span, item.vis_span, true);
} }
fn check_foreign_item(&mut self, cx: &LateContext<'_>, foreign_item: &hir::ForeignItem<'tcx>) { fn check_foreign_item(&mut self, cx: &LateContext<'_>, foreign_item: &hir::ForeignItem<'tcx>) {
@ -1431,19 +1410,29 @@ impl<'tcx> LateLintPass<'tcx> for UnreachablePub {
cx, cx,
"item", "item",
foreign_item.def_id, foreign_item.def_id,
&foreign_item.vis,
foreign_item.span, foreign_item.span,
foreign_item.vis_span,
true, true,
); );
} }
fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) { fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) {
let def_id = cx.tcx.hir().local_def_id(field.hir_id); let def_id = cx.tcx.hir().local_def_id(field.hir_id);
self.perform_lint(cx, "field", def_id, &field.vis, field.span, false); self.perform_lint(cx, "field", def_id, field.span, field.vis_span, false);
} }
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) { fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
self.perform_lint(cx, "item", impl_item.def_id, &impl_item.vis, impl_item.span, false); // Only lint inherent impl items.
if cx.tcx.associated_item(impl_item.def_id).trait_item_def_id.is_none() {
self.perform_lint(
cx,
"item",
impl_item.def_id,
impl_item.span,
impl_item.vis_span,
false,
);
}
} }
} }

View file

@ -406,7 +406,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
} }
_ => (), _ => (),
}, },
FnKind::ItemFn(ident, _, header, _) => { FnKind::ItemFn(ident, _, header) => {
// Skip foreign-ABI #[no_mangle] functions (Issue #31924) // Skip foreign-ABI #[no_mangle] functions (Issue #31924)
if header.abi != Abi::Rust && cx.sess().contains_name(attrs, sym::no_mangle) { if header.abi != Abi::Rust && cx.sess().contains_name(attrs, sym::no_mangle) {
return; return;

View file

@ -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::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;
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
@ -304,7 +303,6 @@ impl<'hir> Map<'hir> {
| Node::Param(_) | Node::Param(_)
| Node::Arm(_) | Node::Arm(_)
| Node::Lifetime(_) | Node::Lifetime(_)
| Node::Visibility(_)
| Node::Block(_) => return None, | Node::Block(_) => return None,
}; };
Some(def_kind) Some(def_kind)
@ -1000,12 +998,7 @@ impl<'hir> Map<'hir> {
}, },
Node::Lifetime(lifetime) => lifetime.span, Node::Lifetime(lifetime) => lifetime.span,
Node::GenericParam(param) => param.span, Node::GenericParam(param) => param.span,
Node::Visibility(&Spanned {
node: VisibilityKind::Restricted { ref path, .. },
..
}) => path.span,
Node::Infer(i) => i.span, Node::Infer(i) => i.span,
Node::Visibility(v) => bug!("unexpected Visibility {:?}", v),
Node::Local(local) => local.span, Node::Local(local) => local.span,
Node::Crate(item) => item.spans.inner_span, Node::Crate(item) => item.spans.inner_span,
}; };
@ -1128,6 +1121,10 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
} }
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);
// Hash visibility information since it does not appear in HIR.
let resolutions = tcx.resolutions(());
resolutions.visibilities.hash_stable(&mut hcx, &mut stable_hasher);
resolutions.has_pub_restricted.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())
@ -1232,7 +1229,6 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
Some(Node::Ctor(..)) => format!("ctor {}{}", path_str(), id_str), Some(Node::Ctor(..)) => format!("ctor {}{}", path_str(), id_str),
Some(Node::Lifetime(_)) => node_str("lifetime"), Some(Node::Lifetime(_)) => node_str("lifetime"),
Some(Node::GenericParam(ref param)) => format!("generic_param {:?}{}", param, id_str), Some(Node::GenericParam(ref param)) => format!("generic_param {:?}{}", param, id_str),
Some(Node::Visibility(ref vis)) => format!("visibility {:?}{}", vis, id_str),
Some(Node::Crate(..)) => String::from("root_crate"), Some(Node::Crate(..)) => String::from("root_crate"),
None => format!("unknown node{}", id_str), None => format!("unknown node{}", id_str),
} }

View file

@ -36,7 +36,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::tagged_ptr::CopyTaggedPtr; use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, CRATE_DEF_ID}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap};
use rustc_hir::Node; use rustc_hir::Node;
use rustc_macros::HashStable; use rustc_macros::HashStable;
use rustc_query_system::ich::StableHashingContext; use rustc_query_system::ich::StableHashingContext;
@ -131,6 +131,8 @@ pub struct ResolverOutputs {
pub definitions: rustc_hir::definitions::Definitions, pub definitions: rustc_hir::definitions::Definitions,
pub cstore: Box<CrateStoreDyn>, pub cstore: Box<CrateStoreDyn>,
pub visibilities: FxHashMap<LocalDefId, Visibility>, pub visibilities: FxHashMap<LocalDefId, Visibility>,
/// This field is used to decide whether we should make `PRIVATE_IN_PUBLIC` a hard error.
pub has_pub_restricted: bool,
pub access_levels: AccessLevels, pub access_levels: AccessLevels,
pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>, pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
pub maybe_unused_trait_imports: FxHashSet<LocalDefId>, pub maybe_unused_trait_imports: FxHashSet<LocalDefId>,
@ -317,22 +319,6 @@ impl<'tcx> DefIdTree for TyCtxt<'tcx> {
} }
impl Visibility { impl Visibility {
pub fn from_hir(visibility: &hir::Visibility<'_>, id: hir::HirId, tcx: TyCtxt<'_>) -> Self {
match visibility.node {
hir::VisibilityKind::Public => Visibility::Public,
hir::VisibilityKind::Crate(_) => Visibility::Restricted(CRATE_DEF_ID.to_def_id()),
hir::VisibilityKind::Restricted { ref path, .. } => match path.res {
// If there is no resolution, `resolve` will have already reported an error, so
// assume that the visibility is public to avoid reporting more privacy errors.
Res::Err => Visibility::Public,
def => Visibility::Restricted(def.def_id()),
},
hir::VisibilityKind::Inherited => {
Visibility::Restricted(tcx.parent_module(id).to_def_id())
}
}
}
/// Returns `true` if an item with this visibility is accessible from the given block. /// Returns `true` if an item with this visibility is accessible from the given block.
pub fn is_accessible_from<T: DefIdTree>(self, module: DefId, tree: T) -> bool { pub fn is_accessible_from<T: DefIdTree>(self, module: DefId, tree: T) -> bool {
let restriction = match self { let restriction = match self {

View file

@ -45,8 +45,6 @@ struct MarkSymbolVisitor<'tcx> {
live_symbols: FxHashSet<LocalDefId>, live_symbols: FxHashSet<LocalDefId>,
repr_has_repr_c: bool, repr_has_repr_c: bool,
in_pat: bool, in_pat: bool,
inherited_pub_visibility: bool,
pub_visibility: bool,
ignore_variant_stack: Vec<DefId>, ignore_variant_stack: Vec<DefId>,
// maps from tuple struct constructors to tuple struct items // maps from tuple struct constructors to tuple struct items
struct_constructors: FxHashMap<LocalDefId, LocalDefId>, struct_constructors: FxHashMap<LocalDefId, LocalDefId>,
@ -284,16 +282,9 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
} }
let had_repr_c = self.repr_has_repr_c; let had_repr_c = self.repr_has_repr_c;
let had_inherited_pub_visibility = self.inherited_pub_visibility;
let had_pub_visibility = self.pub_visibility;
self.repr_has_repr_c = false; self.repr_has_repr_c = false;
self.inherited_pub_visibility = false;
self.pub_visibility = false;
match node { match node {
Node::Item(item) => { Node::Item(item) => match item.kind {
self.pub_visibility = item.vis.node.is_pub();
match item.kind {
hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => { hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
let def = self.tcx.adt_def(item.def_id); let def = self.tcx.adt_def(item.def_id);
self.repr_has_repr_c = def.repr().c(); self.repr_has_repr_c = def.repr().c();
@ -301,16 +292,13 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
intravisit::walk_item(self, &item); intravisit::walk_item(self, &item);
} }
hir::ItemKind::Enum(..) => { hir::ItemKind::Enum(..) => {
self.inherited_pub_visibility = self.pub_visibility;
intravisit::walk_item(self, &item); intravisit::walk_item(self, &item);
} }
hir::ItemKind::ForeignMod { .. } => {} hir::ItemKind::ForeignMod { .. } => {}
_ => { _ => {
intravisit::walk_item(self, &item); intravisit::walk_item(self, &item);
} }
} },
}
Node::TraitItem(trait_item) => { Node::TraitItem(trait_item) => {
intravisit::walk_trait_item(self, trait_item); intravisit::walk_trait_item(self, trait_item);
} }
@ -322,8 +310,6 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
} }
_ => {} _ => {}
} }
self.pub_visibility = had_pub_visibility;
self.inherited_pub_visibility = had_inherited_pub_visibility;
self.repr_has_repr_c = had_repr_c; self.repr_has_repr_c = had_repr_c;
} }
@ -354,14 +340,19 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
_: hir::HirId, _: hir::HirId,
_: rustc_span::Span, _: rustc_span::Span,
) { ) {
let tcx = self.tcx;
let has_repr_c = self.repr_has_repr_c; let has_repr_c = self.repr_has_repr_c;
let inherited_pub_visibility = self.inherited_pub_visibility; let live_fields = def.fields().iter().filter_map(|f| {
let pub_visibility = self.pub_visibility; let def_id = tcx.hir().local_def_id(f.hir_id);
let live_fields = def.fields().iter().filter(|f| { if has_repr_c {
has_repr_c || (pub_visibility && (inherited_pub_visibility || f.vis.node.is_pub())) return Some(def_id);
}
if !tcx.visibility(f.hir_id.owner).is_public() {
return None;
}
if tcx.visibility(def_id).is_public() { Some(def_id) } else { None }
}); });
let hir = self.tcx.hir(); self.live_symbols.extend(live_fields);
self.live_symbols.extend(live_fields.map(|f| hir.local_def_id(f.hir_id)));
intravisit::walk_struct_def(self, def); intravisit::walk_struct_def(self, def);
} }
@ -602,8 +593,6 @@ fn live_symbols_and_ignored_derived_traits<'tcx>(
live_symbols: Default::default(), live_symbols: Default::default(),
repr_has_repr_c: false, repr_has_repr_c: false,
in_pat: false, in_pat: false,
inherited_pub_visibility: false,
pub_visibility: false,
ignore_variant_stack: vec![], ignore_variant_stack: vec![],
struct_constructors, struct_constructors,
ignored_derived_traits: FxHashMap::default(), ignored_derived_traits: FxHashMap::default(),

View file

@ -295,28 +295,6 @@ fn min(vis1: ty::Visibility, vis2: ty::Visibility, tcx: TyCtxt<'_>) -> ty::Visib
if vis1.is_at_least(vis2, tcx) { vis2 } else { vis1 } if vis1.is_at_least(vis2, tcx) { vis2 } else { vis1 }
} }
////////////////////////////////////////////////////////////////////////////////
/// Visitor used to determine if pub(restricted) is used anywhere in the crate.
///
/// This is done so that `private_in_public` warnings can be turned into hard errors
/// in crates that have been updated to use pub(restricted).
////////////////////////////////////////////////////////////////////////////////
struct PubRestrictedVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
has_pub_restricted: bool,
}
impl<'tcx> Visitor<'tcx> for PubRestrictedVisitor<'tcx> {
type NestedFilter = nested_filter::All;
fn nested_visit_map(&mut self) -> Self::Map {
self.tcx.hir()
}
fn visit_vis(&mut self, vis: &'tcx hir::Visibility<'tcx>) {
self.has_pub_restricted = self.has_pub_restricted || vis.node.is_pub_restricted();
}
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// Visitor used to determine impl visibility and reachability. /// Visitor used to determine impl visibility and reachability.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -682,7 +660,9 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
self.update_with_hir_id(ctor_hir_id, item_level); self.update_with_hir_id(ctor_hir_id, item_level);
} }
for field in def.fields() { for field in def.fields() {
if field.vis.node.is_pub() { let def_id = self.tcx.hir().local_def_id(field.hir_id);
let vis = self.tcx.visibility(def_id);
if vis.is_public() {
self.update_with_hir_id(field.hir_id, item_level); self.update_with_hir_id(field.hir_id, item_level);
} }
} }
@ -1361,7 +1341,7 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
// .. and it corresponds to a private type in the AST (this returns // .. and it corresponds to a private type in the AST (this returns
// `None` for type parameters). // `None` for type parameters).
match self.tcx.hir().find(self.tcx.hir().local_def_id_to_hir_id(did)) { match self.tcx.hir().find(self.tcx.hir().local_def_id_to_hir_id(did)) {
Some(Node::Item(item)) => !item.vis.node.is_pub(), Some(Node::Item(_)) => !self.tcx.visibility(did).is_public(),
Some(_) | None => false, Some(_) | None => false,
} }
} else { } else {
@ -1383,8 +1363,8 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
} }
} }
fn item_is_public(&self, def_id: LocalDefId, vis: &hir::Visibility<'_>) -> bool { fn item_is_public(&self, def_id: LocalDefId) -> bool {
self.access_levels.is_reachable(def_id) || vis.node.is_pub() self.access_levels.is_reachable(def_id) || self.tcx.visibility(def_id).is_public()
} }
} }
@ -1519,8 +1499,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
match impl_item.kind { match impl_item.kind {
hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..) hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..)
if self if self.item_is_public(impl_item.def_id) =>
.item_is_public(impl_item.def_id, &impl_item.vis) =>
{ {
intravisit::walk_impl_item(self, impl_item) intravisit::walk_impl_item(self, impl_item)
} }
@ -1591,7 +1570,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
hir::ItemKind::TyAlias(..) => return, hir::ItemKind::TyAlias(..) => return,
// Not at all public, so we don't care. // Not at all public, so we don't care.
_ if !self.item_is_public(item.def_id, &item.vis) => { _ if !self.item_is_public(item.def_id) => {
return; return;
} }
@ -1655,7 +1634,9 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
} }
fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) { fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) {
if s.vis.node.is_pub() || self.in_variant { let def_id = self.tcx.hir().local_def_id(s.hir_id);
let vis = self.tcx.visibility(def_id);
if vis.is_public() || self.in_variant {
intravisit::walk_field_def(self, s); intravisit::walk_field_def(self, s);
} }
} }
@ -1680,7 +1661,6 @@ struct SearchInterfaceForPrivateItemsVisitor<'tcx> {
item_def_id: LocalDefId, item_def_id: LocalDefId,
/// The visitor checks that each component type is at least this visible. /// The visitor checks that each component type is at least this visible.
required_visibility: ty::Visibility, required_visibility: ty::Visibility,
has_pub_restricted: bool,
has_old_errors: bool, has_old_errors: bool,
in_assoc_ty: bool, in_assoc_ty: bool,
} }
@ -1769,7 +1749,10 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
}; };
let make_msg = || format!("{} {} `{}` in public interface", vis_descr, kind, descr); let make_msg = || format!("{} {} `{}` in public interface", vis_descr, kind, descr);
let span = self.tcx.def_span(self.item_def_id.to_def_id()); let span = self.tcx.def_span(self.item_def_id.to_def_id());
if self.has_pub_restricted || self.has_old_errors || self.in_assoc_ty { if self.has_old_errors
|| self.in_assoc_ty
|| self.tcx.resolutions(()).has_pub_restricted
{
let mut err = if kind == "trait" { let mut err = if kind == "trait" {
struct_span_err!(self.tcx.sess, span, E0445, "{}", make_msg()) struct_span_err!(self.tcx.sess, span, E0445, "{}", make_msg())
} else { } else {
@ -1828,7 +1811,6 @@ impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
struct PrivateItemsInPublicInterfacesVisitor<'tcx> { struct PrivateItemsInPublicInterfacesVisitor<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
has_pub_restricted: bool,
old_error_set_ancestry: LocalDefIdSet, old_error_set_ancestry: LocalDefIdSet,
} }
@ -1842,7 +1824,6 @@ impl<'tcx> PrivateItemsInPublicInterfacesVisitor<'tcx> {
tcx: self.tcx, tcx: self.tcx,
item_def_id: def_id, item_def_id: def_id,
required_visibility, required_visibility,
has_pub_restricted: self.has_pub_restricted,
has_old_errors: self.old_error_set_ancestry.contains(&def_id), has_old_errors: self.old_error_set_ancestry.contains(&def_id),
in_assoc_ty: false, in_assoc_ty: false,
} }
@ -1994,19 +1975,16 @@ fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility {
match tcx.hir().get(hir_id) { match tcx.hir().get(hir_id) {
// Unique types created for closures participate in type privacy checking. // Unique types created for closures participate in type privacy checking.
// They have visibilities inherited from the module they are defined in. // They have visibilities inherited from the module they are defined in.
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => { Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(..), .. })
ty::Visibility::Restricted(tcx.parent_module(hir_id).to_def_id()) // - AST lowering creates dummy `use` items which don't
}
// - AST lowering may clone `use` items and the clones don't
// get their entries in the resolver's visibility table. // get their entries in the resolver's visibility table.
// - AST lowering also creates opaque type items with inherited visibilities. // - AST lowering also creates opaque type items with inherited visibilities.
// Visibility on them should have no effect, but to avoid the visibility // Visibility on them should have no effect, but to avoid the visibility
// query failing on some items, we provide it for opaque types as well. // query failing on some items, we provide it for opaque types as well.
Node::Item(hir::Item { | Node::Item(hir::Item {
vis, kind: hir::ItemKind::Use(_, hir::UseKind::ListStem) | hir::ItemKind::OpaqueTy(..),
kind: hir::ItemKind::Use(..) | hir::ItemKind::OpaqueTy(..),
.. ..
}) => ty::Visibility::from_hir(vis, hir_id, tcx), }) => ty::Visibility::Restricted(tcx.parent_module(hir_id).to_def_id()),
// Visibilities of trait impl items are inherited from their traits // Visibilities of trait impl items are inherited from their traits
// and are not filled in resolve. // and are not filled in resolve.
Node::ImplItem(impl_item) => { Node::ImplItem(impl_item) => {
@ -2083,12 +2061,6 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
}; };
tcx.hir().walk_toplevel_module(&mut visitor); tcx.hir().walk_toplevel_module(&mut visitor);
let has_pub_restricted = {
let mut pub_restricted_visitor = PubRestrictedVisitor { tcx, has_pub_restricted: false };
tcx.hir().walk_toplevel_module(&mut pub_restricted_visitor);
pub_restricted_visitor.has_pub_restricted
};
let mut old_error_set_ancestry = HirIdSet::default(); let mut old_error_set_ancestry = HirIdSet::default();
for mut id in visitor.old_error_set.iter().copied() { for mut id in visitor.old_error_set.iter().copied() {
loop { loop {
@ -2106,7 +2078,6 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
// Check for private types and traits in public interfaces. // Check for private types and traits in public interfaces.
let mut visitor = PrivateItemsInPublicInterfacesVisitor { let mut visitor = PrivateItemsInPublicInterfacesVisitor {
tcx, tcx,
has_pub_restricted,
// Only definition IDs are ever searched in `old_error_set_ancestry`, // Only definition IDs are ever searched in `old_error_set_ancestry`,
// so we can filter away all non-definition IDs at this point. // so we can filter away all non-definition IDs at this point.
old_error_set_ancestry: old_error_set_ancestry old_error_set_ancestry: old_error_set_ancestry

View file

@ -265,6 +265,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
}) })
} }
ast::VisibilityKind::Restricted { ref path, id, .. } => { ast::VisibilityKind::Restricted { ref path, id, .. } => {
// Make `PRIVATE_IN_PUBLIC` lint a hard error.
self.r.has_pub_restricted = true;
// For visibilities we are not ready to provide correct implementation of "uniform // For visibilities we are not ready to provide correct implementation of "uniform
// paths" right now, so on 2018 edition we only allow module-relative paths for now. // paths" right now, so on 2018 edition we only allow module-relative paths for now.
// On 2015 edition visibilities are resolved as crate-relative by default, // On 2015 edition visibilities are resolved as crate-relative by default,
@ -458,6 +460,14 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
let mut source = module_path.pop().unwrap(); let mut source = module_path.pop().unwrap();
let mut type_ns_only = false; let mut type_ns_only = false;
self.r.visibilities.insert(self.r.local_def_id(id), vis);
if id1 != ast::DUMMY_NODE_ID {
self.r.visibilities.insert(self.r.local_def_id(id1), vis);
}
if id2 != ast::DUMMY_NODE_ID {
self.r.visibilities.insert(self.r.local_def_id(id2), vis);
}
if nested { if nested {
// Correctly handle `self` // Correctly handle `self`
if source.ident.name == kw::SelfLower { if source.ident.name == kw::SelfLower {
@ -580,6 +590,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
is_prelude: self.r.session.contains_name(&item.attrs, sym::prelude_import), is_prelude: self.r.session.contains_name(&item.attrs, sym::prelude_import),
max_vis: Cell::new(ty::Visibility::Invisible), max_vis: Cell::new(ty::Visibility::Invisible),
}; };
self.r.visibilities.insert(self.r.local_def_id(id), vis);
self.add_import(prefix, kind, use_tree.span, id, item, root_span, item.id, vis); self.add_import(prefix, kind, use_tree.span, id, item, root_span, item.id, vis);
} }
ast::UseTreeKind::Nested(ref items) => { ast::UseTreeKind::Nested(ref items) => {

View file

@ -685,8 +685,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
hir_id: hir::HirId, hir_id: hir::HirId,
) { ) {
let name = match fk { let name = match fk {
intravisit::FnKind::ItemFn(id, _, _, _) => id.name, intravisit::FnKind::ItemFn(id, _, _) => id.name,
intravisit::FnKind::Method(id, _, _) => id.name, intravisit::FnKind::Method(id, _) => id.name,
intravisit::FnKind::Closure => sym::closure, intravisit::FnKind::Closure => sym::closure,
}; };
let name = name.as_str(); let name = name.as_str();

View file

@ -934,6 +934,7 @@ pub struct Resolver<'a> {
glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>, glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
/// Visibilities in "lowered" form, for all entities that have them. /// Visibilities in "lowered" form, for all entities that have them.
visibilities: FxHashMap<LocalDefId, ty::Visibility>, visibilities: FxHashMap<LocalDefId, ty::Visibility>,
has_pub_restricted: bool,
used_imports: FxHashSet<NodeId>, used_imports: FxHashSet<NodeId>,
maybe_unused_trait_imports: FxHashSet<LocalDefId>, maybe_unused_trait_imports: FxHashSet<LocalDefId>,
maybe_unused_extern_crates: Vec<(LocalDefId, Span)>, maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
@ -1313,6 +1314,7 @@ impl<'a> Resolver<'a> {
glob_map: Default::default(), glob_map: Default::default(),
visibilities, visibilities,
has_pub_restricted: false,
used_imports: FxHashSet::default(), used_imports: FxHashSet::default(),
maybe_unused_trait_imports: Default::default(), maybe_unused_trait_imports: Default::default(),
maybe_unused_extern_crates: Vec::new(), maybe_unused_extern_crates: Vec::new(),
@ -1423,6 +1425,7 @@ impl<'a> Resolver<'a> {
let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect(); let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect();
let definitions = self.definitions; let definitions = self.definitions;
let visibilities = self.visibilities; let visibilities = self.visibilities;
let has_pub_restricted = self.has_pub_restricted;
let extern_crate_map = self.extern_crate_map; let extern_crate_map = self.extern_crate_map;
let reexport_map = self.reexport_map; let reexport_map = self.reexport_map;
let maybe_unused_trait_imports = self.maybe_unused_trait_imports; let maybe_unused_trait_imports = self.maybe_unused_trait_imports;
@ -1435,6 +1438,7 @@ impl<'a> Resolver<'a> {
definitions, definitions,
cstore: Box::new(self.crate_loader.into_cstore()), cstore: Box::new(self.crate_loader.into_cstore()),
visibilities, visibilities,
has_pub_restricted,
access_levels, access_levels,
extern_crate_map, extern_crate_map,
reexport_map, reexport_map,
@ -1461,6 +1465,7 @@ impl<'a> Resolver<'a> {
access_levels: self.access_levels.clone(), access_levels: self.access_levels.clone(),
cstore: Box::new(self.cstore().clone()), cstore: Box::new(self.cstore().clone()),
visibilities: self.visibilities.clone(), visibilities: self.visibilities.clone(),
has_pub_restricted: self.has_pub_restricted,
extern_crate_map: self.extern_crate_map.clone(), extern_crate_map: self.extern_crate_map.clone(),
reexport_map: self.reexport_map.clone(), reexport_map: self.reexport_map.clone(),
glob_map: self.glob_map.clone(), glob_map: self.glob_map.clone(),

View file

@ -25,7 +25,6 @@ use rustc_middle::hir::nested_filter;
use rustc_middle::span_bug; use rustc_middle::span_bug;
use rustc_middle::ty::{self, DefIdTree, TyCtxt}; use rustc_middle::ty::{self, DefIdTree, TyCtxt};
use rustc_session::config::Input; use rustc_session::config::Input;
use rustc_span::source_map::respan;
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
use rustc_span::*; use rustc_span::*;
@ -57,20 +56,14 @@ macro_rules! down_cast_data {
} }
macro_rules! access_from { macro_rules! access_from {
($save_ctxt:expr, $item:expr, $id:expr) => { ($save_ctxt:expr, $id:expr) => {
Access { Access {
public: $item.vis.node.is_pub(), public: $save_ctxt.tcx.visibility($id).is_public(),
reachable: $save_ctxt.access_levels.is_reachable($id), reachable: $save_ctxt.access_levels.is_reachable($id),
} }
}; };
} }
macro_rules! access_from_vis {
($save_ctxt:expr, $vis:expr, $id:expr) => {
Access { public: $vis.node.is_pub(), reachable: $save_ctxt.access_levels.is_reachable($id) }
};
}
pub struct DumpVisitor<'tcx> { pub struct DumpVisitor<'tcx> {
pub save_ctxt: SaveContext<'tcx>, pub save_ctxt: SaveContext<'tcx>,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
@ -257,7 +250,6 @@ impl<'tcx> DumpVisitor<'tcx> {
def_id: LocalDefId, def_id: LocalDefId,
ident: Ident, ident: Ident,
generics: &'tcx hir::Generics<'tcx>, generics: &'tcx hir::Generics<'tcx>,
vis: &hir::Visibility<'tcx>,
span: Span, span: Span,
) { ) {
debug!("process_method: {:?}:{}", def_id, ident); debug!("process_method: {:?}:{}", def_id, ident);
@ -272,10 +264,10 @@ impl<'tcx> DumpVisitor<'tcx> {
v.process_generic_params(&generics, &method_data.qualname, hir_id); v.process_generic_params(&generics, &method_data.qualname, hir_id);
method_data.value = method_data.value =
fn_to_string(sig.decl, sig.header, Some(ident.name), generics, vis, &[], None); fn_to_string(sig.decl, sig.header, Some(ident.name), generics, &[], None);
method_data.sig = sig::method_signature(hir_id, ident, generics, sig, &v.save_ctxt); method_data.sig = sig::method_signature(hir_id, ident, generics, sig, &v.save_ctxt);
v.dumper.dump_def(&access_from_vis!(v.save_ctxt, vis, def_id), method_data); v.dumper.dump_def(&access_from!(v.save_ctxt, def_id), method_data);
} }
// walk arg and return types // walk arg and return types
@ -302,7 +294,7 @@ impl<'tcx> DumpVisitor<'tcx> {
let field_data = self.save_ctxt.get_field_data(field, parent_id); let field_data = self.save_ctxt.get_field_data(field, parent_id);
if let Some(field_data) = field_data { if let Some(field_data) = field_data {
self.dumper.dump_def( self.dumper.dump_def(
&access_from!(self.save_ctxt, field, self.tcx.hir().local_def_id(field.hir_id)), &access_from!(self.save_ctxt, self.tcx.hir().local_def_id(field.hir_id)),
field_data, field_data,
); );
} }
@ -369,7 +361,7 @@ impl<'tcx> DumpVisitor<'tcx> {
v.process_formals(body.params, &fn_data.qualname); v.process_formals(body.params, &fn_data.qualname);
v.process_generic_params(ty_params, &fn_data.qualname, item.hir_id()); v.process_generic_params(ty_params, &fn_data.qualname, item.hir_id());
v.dumper.dump_def(&access_from!(v.save_ctxt, item, item.def_id), fn_data); v.dumper.dump_def(&access_from!(v.save_ctxt, item.def_id), fn_data);
} }
for arg in decl.inputs { for arg in decl.inputs {
@ -393,7 +385,7 @@ impl<'tcx> DumpVisitor<'tcx> {
self.nest_typeck_results(item.def_id, |v| { self.nest_typeck_results(item.def_id, |v| {
if let Some(var_data) = v.save_ctxt.get_item_data(item) { if let Some(var_data) = v.save_ctxt.get_item_data(item) {
down_cast_data!(var_data, DefData, item.span); down_cast_data!(var_data, DefData, item.span);
v.dumper.dump_def(&access_from!(v.save_ctxt, item, item.def_id), var_data); v.dumper.dump_def(&access_from!(v.save_ctxt, item.def_id), var_data);
} }
v.visit_ty(&typ); v.visit_ty(&typ);
v.visit_expr(expr); v.visit_expr(expr);
@ -407,7 +399,6 @@ impl<'tcx> DumpVisitor<'tcx> {
typ: &'tcx hir::Ty<'tcx>, typ: &'tcx hir::Ty<'tcx>,
expr: Option<&'tcx hir::Expr<'tcx>>, expr: Option<&'tcx hir::Expr<'tcx>>,
parent_id: DefId, parent_id: DefId,
vis: &hir::Visibility<'tcx>,
attrs: &'tcx [ast::Attribute], attrs: &'tcx [ast::Attribute],
) { ) {
let qualname = format!("::{}", self.tcx.def_path_str(def_id.to_def_id())); let qualname = format!("::{}", self.tcx.def_path_str(def_id.to_def_id()));
@ -418,7 +409,7 @@ impl<'tcx> DumpVisitor<'tcx> {
let span = self.span_from_span(ident.span); let span = self.span_from_span(ident.span);
self.dumper.dump_def( self.dumper.dump_def(
&access_from_vis!(self.save_ctxt, vis, def_id), &access_from!(self.save_ctxt, def_id),
Def { Def {
kind: DefKind::Const, kind: DefKind::Const,
id: id_from_hir_id(hir_id, &self.save_ctxt), id: id_from_hir_id(hir_id, &self.save_ctxt),
@ -469,7 +460,11 @@ impl<'tcx> DumpVisitor<'tcx> {
let fields_str = fields let fields_str = fields
.iter() .iter()
.filter_map(|f| { .filter_map(|f| {
if include_priv_fields || f.vis.node.is_pub() { if include_priv_fields {
return Some(f.ident.to_string());
}
let def_id = self.save_ctxt.tcx.hir().local_def_id(f.hir_id);
if self.save_ctxt.tcx.visibility(def_id).is_public() {
Some(f.ident.to_string()) Some(f.ident.to_string())
} else { } else {
None None
@ -487,7 +482,7 @@ impl<'tcx> DumpVisitor<'tcx> {
let span = self.span_from_span(item.ident.span); let span = self.span_from_span(item.ident.span);
let attrs = self.tcx.hir().attrs(item.hir_id()); let attrs = self.tcx.hir().attrs(item.hir_id());
self.dumper.dump_def( self.dumper.dump_def(
&access_from!(self.save_ctxt, item, item.def_id), &access_from!(self.save_ctxt, item.def_id),
Def { Def {
kind, kind,
id: id_from_def_id(item.def_id.to_def_id()), id: id_from_def_id(item.def_id.to_def_id()),
@ -527,7 +522,7 @@ impl<'tcx> DumpVisitor<'tcx> {
}; };
down_cast_data!(enum_data, DefData, item.span); down_cast_data!(enum_data, DefData, item.span);
let access = access_from!(self.save_ctxt, item, item.def_id); let access = access_from!(self.save_ctxt, item.def_id);
for variant in enum_definition.variants { for variant in enum_definition.variants {
let name = variant.ident.name.to_string(); let name = variant.ident.name.to_string();
@ -662,7 +657,7 @@ impl<'tcx> DumpVisitor<'tcx> {
methods.iter().map(|i| id_from_def_id(i.id.def_id.to_def_id())).collect(); methods.iter().map(|i| id_from_def_id(i.id.def_id.to_def_id())).collect();
let attrs = self.tcx.hir().attrs(item.hir_id()); let attrs = self.tcx.hir().attrs(item.hir_id());
self.dumper.dump_def( self.dumper.dump_def(
&access_from!(self.save_ctxt, item, item.def_id), &access_from!(self.save_ctxt, item.def_id),
Def { Def {
kind: DefKind::Trait, kind: DefKind::Trait,
id, id,
@ -724,7 +719,7 @@ impl<'tcx> DumpVisitor<'tcx> {
fn process_mod(&mut self, item: &'tcx hir::Item<'tcx>) { fn process_mod(&mut self, item: &'tcx hir::Item<'tcx>) {
if let Some(mod_data) = self.save_ctxt.get_item_data(item) { if let Some(mod_data) = self.save_ctxt.get_item_data(item) {
down_cast_data!(mod_data, DefData, item.span); down_cast_data!(mod_data, DefData, item.span);
self.dumper.dump_def(&access_from!(self.save_ctxt, item, item.def_id), mod_data); self.dumper.dump_def(&access_from!(self.save_ctxt, item.def_id), mod_data);
} }
} }
@ -979,11 +974,9 @@ impl<'tcx> DumpVisitor<'tcx> {
fn process_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>, trait_id: DefId) { fn process_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>, trait_id: DefId) {
self.process_macro_use(trait_item.span); self.process_macro_use(trait_item.span);
let vis_span = trait_item.span.shrink_to_lo();
match trait_item.kind { match trait_item.kind {
hir::TraitItemKind::Const(ref ty, body) => { hir::TraitItemKind::Const(ref ty, body) => {
let body = body.map(|b| &self.tcx.hir().body(b).value); let body = body.map(|b| &self.tcx.hir().body(b).value);
let respan = respan(vis_span, hir::VisibilityKind::Public);
let attrs = self.tcx.hir().attrs(trait_item.hir_id()); let attrs = self.tcx.hir().attrs(trait_item.hir_id());
self.process_assoc_const( self.process_assoc_const(
trait_item.def_id, trait_item.def_id,
@ -991,21 +984,18 @@ impl<'tcx> DumpVisitor<'tcx> {
&ty, &ty,
body, body,
trait_id, trait_id,
&respan,
attrs, attrs,
); );
} }
hir::TraitItemKind::Fn(ref sig, ref trait_fn) => { hir::TraitItemKind::Fn(ref sig, ref trait_fn) => {
let body = let body =
if let hir::TraitFn::Provided(body) = trait_fn { Some(*body) } else { None }; if let hir::TraitFn::Provided(body) = trait_fn { Some(*body) } else { None };
let respan = respan(vis_span, hir::VisibilityKind::Public);
self.process_method( self.process_method(
sig, sig,
body, body,
trait_item.def_id, trait_item.def_id,
trait_item.ident, trait_item.ident,
&trait_item.generics, &trait_item.generics,
&respan,
trait_item.span, trait_item.span,
); );
} }
@ -1064,7 +1054,6 @@ impl<'tcx> DumpVisitor<'tcx> {
&ty, &ty,
Some(&body.value), Some(&body.value),
impl_id, impl_id,
&impl_item.vis,
attrs, attrs,
); );
} }
@ -1075,7 +1064,6 @@ impl<'tcx> DumpVisitor<'tcx> {
impl_item.def_id, impl_item.def_id,
impl_item.ident, impl_item.ident,
&impl_item.generics, &impl_item.generics,
&impl_item.vis,
impl_item.span, impl_item.span,
); );
} }
@ -1147,7 +1135,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
hir::ItemKind::Use(path, hir::UseKind::Single) => { hir::ItemKind::Use(path, hir::UseKind::Single) => {
let sub_span = path.segments.last().unwrap().ident.span; let sub_span = path.segments.last().unwrap().ident.span;
if !self.span.filter_generated(sub_span) { if !self.span.filter_generated(sub_span) {
let access = access_from!(self.save_ctxt, item, item.def_id); let access = access_from!(self.save_ctxt, item.def_id);
let ref_id = self.lookup_def_id(item.hir_id()).map(id_from_def_id); let ref_id = self.lookup_def_id(item.hir_id()).map(id_from_def_id);
let span = self.span_from_span(sub_span); let span = self.span_from_span(sub_span);
let parent = let parent =
@ -1176,7 +1164,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
// we don't want to track anyway, since it's probably macro-internal `use` // we don't want to track anyway, since it's probably macro-internal `use`
if let Some(sub_span) = self.span.sub_span_of_star(item.span) { if let Some(sub_span) = self.span.sub_span_of_star(item.span) {
if !self.span.filter_generated(item.span) { if !self.span.filter_generated(item.span) {
let access = access_from!(self.save_ctxt, item, item.def_id); let access = access_from!(self.save_ctxt, item.def_id);
let span = self.span_from_span(sub_span); let span = self.span_from_span(sub_span);
let parent = let parent =
self.save_ctxt.tcx.parent(item.def_id.to_def_id()).map(id_from_def_id); self.save_ctxt.tcx.parent(item.def_id.to_def_id()).map(id_from_def_id);
@ -1249,7 +1237,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
let attrs = self.tcx.hir().attrs(item.hir_id()); let attrs = self.tcx.hir().attrs(item.hir_id());
self.dumper.dump_def( self.dumper.dump_def(
&access_from!(self.save_ctxt, item, item.def_id), &access_from!(self.save_ctxt, item.def_id),
Def { Def {
kind: DefKind::Type, kind: DefKind::Type,
id, id,
@ -1443,7 +1431,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
} }
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) { fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
let access = access_from!(self.save_ctxt, item, item.def_id); let access = access_from!(self.save_ctxt, item.def_id);
match item.kind { match item.kind {
hir::ForeignItemKind::Fn(decl, _, ref generics) => { hir::ForeignItemKind::Fn(decl, _, ref generics) => {

View file

@ -27,7 +27,6 @@ use rustc_middle::{bug, span_bug};
use rustc_session::config::{CrateType, Input, OutputType}; use rustc_session::config::{CrateType, Input, OutputType};
use rustc_session::cstore::ExternCrate; use rustc_session::cstore::ExternCrate;
use rustc_session::output::{filename_for_metadata, out_filename}; use rustc_session::output::{filename_for_metadata, out_filename};
use rustc_span::source_map::Spanned;
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
use rustc_span::*; use rustc_span::*;
@ -165,7 +164,6 @@ impl<'tcx> SaveContext<'tcx> {
}, },
Some(item.ident.name), Some(item.ident.name),
generics, generics,
&item.vis,
arg_names, arg_names,
None, None,
), ),
@ -221,7 +219,6 @@ impl<'tcx> SaveContext<'tcx> {
sig.header, sig.header,
Some(item.ident.name), Some(item.ident.name),
generics, generics,
&item.vis,
&[], &[],
None, None,
), ),
@ -310,7 +307,7 @@ impl<'tcx> SaveContext<'tcx> {
let qualname = format!("::{}", self.tcx.def_path_str(def_id)); let qualname = format!("::{}", self.tcx.def_path_str(def_id));
filter!(self.span_utils, item.ident.span); filter!(self.span_utils, item.ident.span);
let value = let value =
enum_def_to_string(def, generics, item.ident.name, item.span, &item.vis); enum_def_to_string(def, generics, item.ident.name, item.span);
Some(Data::DefData(Def { Some(Data::DefData(Def {
kind: DefKind::Enum, kind: DefKind::Enum,
id: id_from_def_id(def_id), id: id_from_def_id(def_id),
@ -595,11 +592,6 @@ impl<'tcx> SaveContext<'tcx> {
Node::TraitRef(tr) => tr.path.res, Node::TraitRef(tr) => tr.path.res,
Node::Item(&hir::Item { kind: hir::ItemKind::Use(path, _), .. }) => path.res, Node::Item(&hir::Item { kind: hir::ItemKind::Use(path, _), .. }) => path.res,
Node::Visibility(&Spanned {
node: hir::VisibilityKind::Restricted { ref path, .. },
..
}) => path.res,
Node::PathSegment(seg) => match seg.res { Node::PathSegment(seg) => match seg.res {
Some(res) if res != Res::Err => res, Some(res) if res != Res::Err => res,
_ => { _ => {

View file

@ -257,7 +257,6 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
| hir::Node::Ctor(..) | hir::Node::Ctor(..)
| hir::Node::Lifetime(..) | hir::Node::Lifetime(..)
| hir::Node::GenericParam(..) | hir::Node::GenericParam(..)
| hir::Node::Visibility(..)
| hir::Node::Crate(..) | hir::Node::Crate(..)
| hir::Node::Infer(..) => bug!("Unsupported branch target: {:?}", node), | hir::Node::Infer(..) => bug!("Unsupported branch target: {:?}", node),
} }

View file

@ -18,8 +18,11 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
for id in tcx.hir().items() { for id in tcx.hir().items() {
if matches!(tcx.hir().def_kind(id.def_id), DefKind::Use) { if matches!(tcx.hir().def_kind(id.def_id), DefKind::Use) {
if tcx.visibility(id.def_id).is_public() {
continue;
}
let item = tcx.hir().item(id); let item = tcx.hir().item(id);
if item.vis.node.is_pub() || item.span.is_dummy() { if item.span.is_dummy() {
continue; continue;
} }
if let hir::ItemKind::Use(path, _) = item.kind { if let hir::ItemKind::Use(path, _) = item.kind {
@ -176,7 +179,7 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
Some(orig_name) => format!("use {} as {};", orig_name, item.ident.name), Some(orig_name) => format!("use {} as {};", orig_name, item.ident.name),
None => format!("use {};", item.ident.name), None => format!("use {};", item.ident.name),
}; };
let vis = tcx.sess.source_map().span_to_snippet(item.vis.span).unwrap_or_default(); let vis = tcx.sess.source_map().span_to_snippet(item.vis_span).unwrap_or_default();
let add_vis = |to| if vis.is_empty() { to } else { format!("{} {}", vis, to) }; let add_vis = |to| if vis.is_empty() { to } else { format!("{} {}", vis, to) };
lint.build("`extern crate` is not idiomatic in the new edition") lint.build("`extern crate` is not idiomatic in the new edition")
.span_suggestion_short( .span_suggestion_short(

View file

@ -32,13 +32,11 @@
enum EnumVisibility { A } enum EnumVisibility { A }
#[cfg(not(any(cfail1,cfail4)))] #[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")] #[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")] #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
pub enum EnumVisibility { pub enum EnumVisibility { A }
A
}

View file

@ -116,7 +116,7 @@ impl Foo {
// Change Method Privacy ------------------------------------------------------- // Change Method Privacy -------------------------------------------------------
#[cfg(any(cfail1,cfail4))] #[cfg(any(cfail1,cfail4))]
impl Foo { impl Foo {
//------------------------------------------------------------------------------ //----------------------------------------------------
//-------------------------- //--------------------------
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//-------------------------- //--------------------------
@ -129,9 +129,9 @@ impl Foo {
#[rustc_clean(cfg="cfail5")] #[rustc_clean(cfg="cfail5")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
impl Foo { impl Foo {
#[rustc_clean(cfg="cfail2", except="associated_item,hir_owner,hir_owner_nodes")] #[rustc_clean(cfg="cfail2", except="associated_item")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(cfg="cfail5", except="associated_item,hir_owner,hir_owner_nodes")] #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,associated_item")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
fn method_privacy() { } fn method_privacy() { }
} }

View file

@ -27,7 +27,7 @@
static STATIC_VISIBILITY: u8 = 0; static STATIC_VISIBILITY: u8 = 0;
#[cfg(not(any(cfail1,cfail4)))] #[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")] #[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")] #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]

View file

@ -84,12 +84,12 @@ struct TupleStructAddField(
// Tuple Struct Field Visibility ----------------------------------------------- // Tuple Struct Field Visibility -----------------------------------------------
#[cfg(any(cfail1,cfail4))] #[cfg(any(cfail1,cfail4))]
struct TupleStructFieldVisibility(char); struct TupleStructFieldVisibility( char);
#[cfg(not(any(cfail1,cfail4)))] #[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail2")] #[rustc_clean(cfg="cfail2", except="type_of")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail5")] #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
struct TupleStructFieldVisibility(pub char); struct TupleStructFieldVisibility(pub char);
@ -145,13 +145,11 @@ struct RecordStructAddField {
struct RecordStructFieldVisibility { x: f32 } struct RecordStructFieldVisibility { x: f32 }
#[cfg(not(any(cfail1,cfail4)))] #[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail2")] #[rustc_clean(cfg="cfail2", except="type_of")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail5")] #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
struct RecordStructFieldVisibility { struct RecordStructFieldVisibility { pub x: f32 }
pub x: f32
}
// Add Lifetime Parameter ------------------------------------------------------ // Add Lifetime Parameter ------------------------------------------------------
@ -260,9 +258,9 @@ pub struct EmptyStruct;
struct Visibility; struct Visibility;
#[cfg(not(any(cfail1,cfail4)))] #[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")] #[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
pub struct Visibility; pub struct Visibility;

View file

@ -31,9 +31,9 @@
trait TraitVisibility { } trait TraitVisibility { }
#[cfg(not(any(cfail1,cfail4)))] #[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")] #[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
pub trait TraitVisibility { } pub trait TraitVisibility { }

View file

@ -6,4 +6,4 @@ extern crate std;
// pretty-mode:hir // pretty-mode:hir
// pp-exact:hir-pretty-loop.pp // pp-exact:hir-pretty-loop.pp
pub fn foo() { loop { break; } } fn foo() { loop { break; } }

View file

@ -8,9 +8,9 @@ extern crate std;
// #4264 fixed-length vector types // #4264 fixed-length vector types
pub fn foo(_: [i32; (3 as usize)]) ({ } as ()) fn foo(_: [i32; (3 as usize)]) ({ } as ())
pub fn bar() ({ fn bar() ({
const FOO: usize = ((5 as usize) - (4 as usize) as usize); const FOO: usize = ((5 as usize) - (4 as usize) as usize);
let _: [(); (FOO as usize)] = ([(() as ())] as [(); 1]); let _: [(); (FOO as usize)] = ([(() as ())] as [(); 1]);
@ -41,14 +41,14 @@ pub fn bar() ({
(res as String) (res as String)
} as String); } as String);
} as ()) } as ())
pub type Foo = [i32; (3 as usize)]; type Foo = [i32; (3 as usize)];
pub struct Bar { struct Bar {
pub x: [i32; (3 as usize)], x: [i32; (3 as usize)],
} }
pub struct TupleBar([i32; (4 as usize)]); struct TupleBar([i32; (4 as usize)]);
pub enum Baz { BazVariant([i32; (5 as usize)]), } enum Baz { BazVariant([i32; (5 as usize)]), }
pub fn id<T>(x: T) -> T ({ (x as T) } as T) fn id<T>(x: T) -> T ({ (x as T) } as T)
pub fn use_id() ({ fn use_id() ({
let _ = let _ =
((id::<[i32; (3 as usize)]> as ((id::<[i32; (3 as usize)]> as
fn([i32; 3]) -> [i32; 3] {id::<[i32; 3]>})(([(1 as i32), fn([i32; 3]) -> [i32; 3] {id::<[i32; 3]>})(([(1 as i32),

View file

@ -26,6 +26,11 @@ mod private_mod {
pub fn count_neutrons(&self) -> usize { self.neutrons } //~ WARNING unreachable_pub pub fn count_neutrons(&self) -> usize { self.neutrons } //~ WARNING unreachable_pub
pub(crate) fn count_electrons(&self) -> usize { self.electrons } pub(crate) fn count_electrons(&self) -> usize { self.electrons }
} }
impl Clone for Hydrogen {
fn clone(&self) -> Hydrogen {
Hydrogen { neutrons: self.neutrons, electrons: self.electrons }
}
}
pub enum Helium {} //~ WARNING unreachable_pub pub enum Helium {} //~ WARNING unreachable_pub
pub union Lithium { c1: usize, c2: u8 } //~ WARNING unreachable_pub pub union Lithium { c1: usize, c2: u8 } //~ WARNING unreachable_pub

View file

@ -50,7 +50,7 @@ LL | pub fn count_neutrons(&self) -> usize { self.neutrons }
| help: consider restricting its visibility: `pub(crate)` | help: consider restricting its visibility: `pub(crate)`
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub-pub_crate.rs:30:5 --> $DIR/unreachable_pub-pub_crate.rs:35:5
| |
LL | pub enum Helium {} LL | pub enum Helium {}
| ---^^^^^^^^^^^^ | ---^^^^^^^^^^^^
@ -60,7 +60,7 @@ LL | pub enum Helium {}
= help: or consider exporting it for use by other crates = help: or consider exporting it for use by other crates
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub-pub_crate.rs:31:5 --> $DIR/unreachable_pub-pub_crate.rs:36:5
| |
LL | pub union Lithium { c1: usize, c2: u8 } LL | pub union Lithium { c1: usize, c2: u8 }
| ---^^^^^^^^^^^^^^ | ---^^^^^^^^^^^^^^
@ -70,7 +70,7 @@ LL | pub union Lithium { c1: usize, c2: u8 }
= help: or consider exporting it for use by other crates = help: or consider exporting it for use by other crates
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub-pub_crate.rs:32:5 --> $DIR/unreachable_pub-pub_crate.rs:37:5
| |
LL | pub fn beryllium() {} LL | pub fn beryllium() {}
| ---^^^^^^^^^^^^^^^ | ---^^^^^^^^^^^^^^^
@ -80,7 +80,7 @@ LL | pub fn beryllium() {}
= help: or consider exporting it for use by other crates = help: or consider exporting it for use by other crates
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub-pub_crate.rs:33:5 --> $DIR/unreachable_pub-pub_crate.rs:38:5
| |
LL | pub trait Boron {} LL | pub trait Boron {}
| ---^^^^^^^^^^^^ | ---^^^^^^^^^^^^
@ -90,7 +90,7 @@ LL | pub trait Boron {}
= help: or consider exporting it for use by other crates = help: or consider exporting it for use by other crates
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub-pub_crate.rs:34:5 --> $DIR/unreachable_pub-pub_crate.rs:39:5
| |
LL | pub const CARBON: usize = 1; LL | pub const CARBON: usize = 1;
| ---^^^^^^^^^^^^^^^^^^^^^^^^^ | ---^^^^^^^^^^^^^^^^^^^^^^^^^
@ -100,7 +100,7 @@ LL | pub const CARBON: usize = 1;
= help: or consider exporting it for use by other crates = help: or consider exporting it for use by other crates
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub-pub_crate.rs:35:5 --> $DIR/unreachable_pub-pub_crate.rs:40:5
| |
LL | pub static NITROGEN: usize = 2; LL | pub static NITROGEN: usize = 2;
| ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -110,7 +110,7 @@ LL | pub static NITROGEN: usize = 2;
= help: or consider exporting it for use by other crates = help: or consider exporting it for use by other crates
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub-pub_crate.rs:36:5 --> $DIR/unreachable_pub-pub_crate.rs:41:5
| |
LL | pub type Oxygen = bool; LL | pub type Oxygen = bool;
| ---^^^^^^^^^^^^^^^^^^^^ | ---^^^^^^^^^^^^^^^^^^^^
@ -120,7 +120,7 @@ LL | pub type Oxygen = bool;
= help: or consider exporting it for use by other crates = help: or consider exporting it for use by other crates
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub-pub_crate.rs:39:47 --> $DIR/unreachable_pub-pub_crate.rs:44:47
| |
LL | ($visibility: vis, $name: ident) => { $visibility struct $name {} } LL | ($visibility: vis, $name: ident) => { $visibility struct $name {} }
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
@ -135,7 +135,7 @@ LL | define_empty_struct_with_visibility!(pub, Fluorine);
= note: this warning originates in the macro `define_empty_struct_with_visibility` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this warning originates in the macro `define_empty_struct_with_visibility` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub-pub_crate.rs:45:9 --> $DIR/unreachable_pub-pub_crate.rs:50:9
| |
LL | pub fn catalyze() -> bool; LL | pub fn catalyze() -> bool;
| ---^^^^^^^^^^^^^^^^^^^^^^^ | ---^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -22,6 +22,11 @@ mod private_mod {
pub fn count_neutrons(&self) -> usize { self.neutrons } //~ WARNING unreachable_pub pub fn count_neutrons(&self) -> usize { self.neutrons } //~ WARNING unreachable_pub
crate fn count_electrons(&self) -> usize { self.electrons } crate fn count_electrons(&self) -> usize { self.electrons }
} }
impl Clone for Hydrogen {
fn clone(&self) -> Hydrogen {
Hydrogen { neutrons: self.neutrons, electrons: self.electrons }
}
}
pub enum Helium {} //~ WARNING unreachable_pub pub enum Helium {} //~ WARNING unreachable_pub
pub union Lithium { c1: usize, c2: u8 } //~ WARNING unreachable_pub pub union Lithium { c1: usize, c2: u8 } //~ WARNING unreachable_pub

View file

@ -50,7 +50,7 @@ LL | pub fn count_neutrons(&self) -> usize { self.neutrons }
| help: consider restricting its visibility: `crate` | help: consider restricting its visibility: `crate`
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub.rs:26:5 --> $DIR/unreachable_pub.rs:31:5
| |
LL | pub enum Helium {} LL | pub enum Helium {}
| ---^^^^^^^^^^^^ | ---^^^^^^^^^^^^
@ -60,7 +60,7 @@ LL | pub enum Helium {}
= help: or consider exporting it for use by other crates = help: or consider exporting it for use by other crates
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub.rs:27:5 --> $DIR/unreachable_pub.rs:32:5
| |
LL | pub union Lithium { c1: usize, c2: u8 } LL | pub union Lithium { c1: usize, c2: u8 }
| ---^^^^^^^^^^^^^^ | ---^^^^^^^^^^^^^^
@ -70,7 +70,7 @@ LL | pub union Lithium { c1: usize, c2: u8 }
= help: or consider exporting it for use by other crates = help: or consider exporting it for use by other crates
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub.rs:28:5 --> $DIR/unreachable_pub.rs:33:5
| |
LL | pub fn beryllium() {} LL | pub fn beryllium() {}
| ---^^^^^^^^^^^^^^^ | ---^^^^^^^^^^^^^^^
@ -80,7 +80,7 @@ LL | pub fn beryllium() {}
= help: or consider exporting it for use by other crates = help: or consider exporting it for use by other crates
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub.rs:29:5 --> $DIR/unreachable_pub.rs:34:5
| |
LL | pub trait Boron {} LL | pub trait Boron {}
| ---^^^^^^^^^^^^ | ---^^^^^^^^^^^^
@ -90,7 +90,7 @@ LL | pub trait Boron {}
= help: or consider exporting it for use by other crates = help: or consider exporting it for use by other crates
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub.rs:30:5 --> $DIR/unreachable_pub.rs:35:5
| |
LL | pub const CARBON: usize = 1; LL | pub const CARBON: usize = 1;
| ---^^^^^^^^^^^^^^^^^^^^^^^^^ | ---^^^^^^^^^^^^^^^^^^^^^^^^^
@ -100,7 +100,7 @@ LL | pub const CARBON: usize = 1;
= help: or consider exporting it for use by other crates = help: or consider exporting it for use by other crates
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub.rs:31:5 --> $DIR/unreachable_pub.rs:36:5
| |
LL | pub static NITROGEN: usize = 2; LL | pub static NITROGEN: usize = 2;
| ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -110,7 +110,7 @@ LL | pub static NITROGEN: usize = 2;
= help: or consider exporting it for use by other crates = help: or consider exporting it for use by other crates
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub.rs:32:5 --> $DIR/unreachable_pub.rs:37:5
| |
LL | pub type Oxygen = bool; LL | pub type Oxygen = bool;
| ---^^^^^^^^^^^^^^^^^^^^ | ---^^^^^^^^^^^^^^^^^^^^
@ -120,7 +120,7 @@ LL | pub type Oxygen = bool;
= help: or consider exporting it for use by other crates = help: or consider exporting it for use by other crates
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub.rs:35:47 --> $DIR/unreachable_pub.rs:40:47
| |
LL | ($visibility: vis, $name: ident) => { $visibility struct $name {} } LL | ($visibility: vis, $name: ident) => { $visibility struct $name {} }
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
@ -135,7 +135,7 @@ LL | define_empty_struct_with_visibility!(pub, Fluorine);
= note: this warning originates in the macro `define_empty_struct_with_visibility` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this warning originates in the macro `define_empty_struct_with_visibility` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: unreachable `pub` item warning: unreachable `pub` item
--> $DIR/unreachable_pub.rs:41:9 --> $DIR/unreachable_pub.rs:46:9
| |
LL | pub fn catalyze() -> bool; LL | pub fn catalyze() -> bool;
| ---^^^^^^^^^^^^^^^^^^^^^^^ | ---^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -6,7 +6,7 @@ extern crate std;
// compile-flags: -Zunpretty=hir,typed // compile-flags: -Zunpretty=hir,typed
// check-pass // check-pass
pub fn main() ({ fn main() ({
(if (true as bool) (if (true as bool)
({ } as ({ } as
()) else if (let Some(a) = ()) else if (let Some(a) =

View file

@ -10,5 +10,5 @@ extern crate std;
trait Animal { } trait Animal { }
fn main() { fn main() {
pub type ServeFut = /*impl Trait*/; type ServeFut = /*impl Trait*/;
} }

View file

@ -82,7 +82,7 @@ impl CognitiveComplexity {
if rust_cc > self.limit.limit() { if rust_cc > self.limit.limit() {
let fn_span = match kind { let fn_span = match kind {
FnKind::ItemFn(ident, _, _, _) | FnKind::Method(ident, _, _) => ident.span, FnKind::ItemFn(ident, _, _) | FnKind::Method(ident, _) => ident.span,
FnKind::Closure => { FnKind::Closure => {
let header_span = body_span.with_hi(decl.output.span().lo()); let header_span = body_span.with_hi(decl.output.span().lo());
let pos = snippet_opt(cx, header_span).and_then(|snip| { let pos = snippet_opt(cx, header_span).and_then(|snip| {

View file

@ -260,7 +260,7 @@ impl LateLintPass<'_> for EnumVariantNames {
} }
// The `module_name_repetitions` lint should only trigger if the item has the module in its // The `module_name_repetitions` lint should only trigger if the item has the module in its
// name. Having the same name is accepted. // name. Having the same name is accepted.
if item.vis.node.is_pub() && item_camel.len() > mod_camel.len() { if cx.tcx.visibility(item.def_id).is_public() && item_camel.len() > mod_camel.len() {
let matching = count_match_start(mod_camel, &item_camel); let matching = count_match_start(mod_camel, &item_camel);
let rmatching = count_match_end(mod_camel, &item_camel); let rmatching = count_match_end(mod_camel, &item_camel);
let nchars = mod_camel.chars().count(); let nchars = mod_camel.chars().count();

View file

@ -78,7 +78,10 @@ impl LateLintPass<'_> for ExhaustiveItems {
if !attrs.iter().any(|a| a.has_name(sym::non_exhaustive)); if !attrs.iter().any(|a| a.has_name(sym::non_exhaustive));
then { then {
let (lint, msg) = if let ItemKind::Struct(ref v, ..) = item.kind { let (lint, msg) = if let ItemKind::Struct(ref v, ..) = item.kind {
if v.fields().iter().any(|f| !f.vis.node.is_pub()) { if v.fields().iter().any(|f| {
let def_id = cx.tcx.hir().local_def_id(f.hir_id);
!cx.tcx.visibility(def_id).is_public()
}) {
// skip structs with private fields // skip structs with private fields
return; return;
} }

View file

@ -17,8 +17,8 @@ pub(super) fn check_fn<'tcx>(
hir_id: hir::HirId, hir_id: hir::HirId,
) { ) {
let unsafety = match kind { let unsafety = match kind {
intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _) => unsafety, intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }) => unsafety,
intravisit::FnKind::Method(_, sig, _) => sig.header.unsafety, intravisit::FnKind::Method(_, sig) => sig.header.unsafety,
intravisit::FnKind::Closure => return, intravisit::FnKind::Closure => return,
}; };

View file

@ -26,9 +26,8 @@ pub(super) fn check_fn(
header: hir::FnHeader { abi: Abi::Rust, .. }, header: hir::FnHeader { abi: Abi::Rust, .. },
.. ..
}, },
_,
) )
| intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _) => check_arg_number( | intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }) => check_arg_number(
cx, cx,
decl, decl,
span.with_hi(decl.output.span().hi()), span.with_hi(decl.output.span().hi()),

View file

@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
} }
match kind { match kind {
FnKind::ItemFn(.., header, _) => { FnKind::ItemFn(.., header) => {
let attrs = cx.tcx.hir().attrs(hir_id); let attrs = cx.tcx.hir().attrs(hir_id);
if header.abi != Abi::Rust || requires_exact_signature(attrs) { if header.abi != Abi::Rust || requires_exact_signature(attrs) {
return; return;

View file

@ -251,7 +251,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
} }
match kind { match kind {
FnKind::ItemFn(.., header, _) => { FnKind::ItemFn(.., header) => {
if header.abi != Abi::Rust { if header.abi != Abi::Rust {
return; return;
} }

View file

@ -1,8 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Item, ItemKind, VisibilityKind}; use rustc_hir::{Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::def_id::CRATE_DEF_ID;
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
@ -41,7 +43,7 @@ impl_lint_pass!(RedundantPubCrate => [REDUNDANT_PUB_CRATE]);
impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate { impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
if let VisibilityKind::Crate { .. } = item.vis.node { if cx.tcx.visibility(item.def_id) == ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id()) {
if !cx.access_levels.is_exported(item.def_id) && self.is_exported.last() == Some(&false) { if !cx.access_levels.is_exported(item.def_id) && self.is_exported.last() == Some(&false) {
let span = item.span.with_hi(item.ident.span.hi()); let span = item.span.with_hi(item.ident.span.hi());
let descr = cx.tcx.def_kind(item.def_id).descr(item.def_id.to_def_id()); let descr = cx.tcx.def_kind(item.def_id).descr(item.def_id.to_def_id());
@ -52,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
&format!("pub(crate) {} inside private module", descr), &format!("pub(crate) {} inside private module", descr),
|diag| { |diag| {
diag.span_suggestion( diag.span_suggestion(
item.vis.span, item.vis_span,
"consider using", "consider using",
"pub".to_string(), "pub".to_string(),
Applicability::MachineApplicable, Applicability::MachineApplicable,

View file

@ -111,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for ReturnSelfNotMustUse {
) { ) {
if_chain! { if_chain! {
// We are only interested in methods, not in functions or associated functions. // We are only interested in methods, not in functions or associated functions.
if matches!(kind, FnKind::Method(_, _, _)); if matches!(kind, FnKind::Method(_, _));
if let Some(fn_def) = cx.tcx.hir().opt_local_def_id(hir_id); if let Some(fn_def) = cx.tcx.hir().opt_local_def_id(hir_id);
if let Some(impl_def) = cx.tcx.impl_of_method(fn_def.to_def_id()); if let Some(impl_def) = cx.tcx.impl_of_method(fn_def.to_def_id());
// We don't want this method to be te implementation of a trait because the // We don't want this method to be te implementation of a trait because the

View file

@ -67,7 +67,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
span: Span, span: Span,
hir_id: HirId, hir_id: HirId,
) { ) {
if let FnKind::ItemFn(_, _, FnHeader { asyncness, .. }, _) = &fn_kind { if let FnKind::ItemFn(_, _, FnHeader { asyncness, .. }) = &fn_kind {
if matches!(asyncness, IsAsync::Async) { if matches!(asyncness, IsAsync::Async) {
let mut visitor = AsyncFnVisitor { cx, found_await: false }; let mut visitor = AsyncFnVisitor { cx, found_await: false };
walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), span, hir_id); walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), span, hir_id);

View file

@ -4,6 +4,7 @@ use clippy_utils::get_attr;
use rustc_ast::ast::{Attribute, InlineAsmTemplatePiece}; use rustc_ast::ast::{Attribute, InlineAsmTemplatePiece};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::ty;
use rustc_session::Session; use rustc_session::Session;
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
@ -45,14 +46,16 @@ impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector {
return; return;
} }
println!("impl item `{}`", item.ident.name); println!("impl item `{}`", item.ident.name);
match item.vis.node { match cx.tcx.visibility(item.def_id) {
hir::VisibilityKind::Public => println!("public"), ty::Visibility::Public => println!("public"),
hir::VisibilityKind::Crate(_) => println!("visible crate wide"), ty::Visibility::Restricted(def_id) => {
hir::VisibilityKind::Restricted { path, .. } => println!( if def_id.is_top_level_module() {
"visible in module `{}`", println!("visible crate wide")
rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_path(path, false)) } else {
), println!("visible in module `{}`", cx.tcx.def_path_str(def_id))
hir::VisibilityKind::Inherited => println!("visibility inherited from outer item"), }
},
ty::Visibility::Invisible => println!("invisible"),
} }
match item.kind { match item.kind {
hir::ImplItemKind::Const(_, body_id) => { hir::ImplItemKind::Const(_, body_id) => {
@ -360,14 +363,16 @@ fn print_expr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, indent: usize) {
fn print_item(cx: &LateContext<'_>, item: &hir::Item<'_>) { fn print_item(cx: &LateContext<'_>, item: &hir::Item<'_>) {
let did = item.def_id; let did = item.def_id;
println!("item `{}`", item.ident.name); println!("item `{}`", item.ident.name);
match item.vis.node { match cx.tcx.visibility(item.def_id) {
hir::VisibilityKind::Public => println!("public"), ty::Visibility::Public => println!("public"),
hir::VisibilityKind::Crate(_) => println!("visible crate wide"), ty::Visibility::Restricted(def_id) => {
hir::VisibilityKind::Restricted { path, .. } => println!( if def_id.is_top_level_module() {
"visible in module `{}`", println!("visible crate wide")
rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_path(path, false)) } else {
), println!("visible in module `{}`", cx.tcx.def_path_str(def_id))
hir::VisibilityKind::Inherited => println!("visibility inherited from outer item"), }
},
ty::Visibility::Invisible => println!("invisible"),
} }
match item.kind { match item.kind {
hir::ItemKind::ExternCrate(ref _renamed_from) => { hir::ItemKind::ExternCrate(ref _renamed_from) => {

View file

@ -8,6 +8,7 @@ use rustc_hir::{
Item, ItemKind, PathSegment, UseKind, Item, ItemKind, PathSegment, UseKind,
}; };
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::symbol::kw; use rustc_span::symbol::kw;
use rustc_span::{sym, BytePos}; use rustc_span::{sym, BytePos};
@ -115,7 +116,8 @@ impl LateLintPass<'_> for WildcardImports {
if is_test_module_or_function(cx.tcx, item) { if is_test_module_or_function(cx.tcx, item) {
self.test_modules_deep = self.test_modules_deep.saturating_add(1); self.test_modules_deep = self.test_modules_deep.saturating_add(1);
} }
if item.vis.node.is_pub() || item.vis.node.is_pub_restricted() { let module = cx.tcx.parent_module_from_def_id(item.def_id);
if cx.tcx.visibility(item.def_id) != ty::Visibility::Restricted(module.to_def_id()) {
return; return;
} }
if_chain! { if_chain! {

View file

@ -1690,7 +1690,7 @@ pub fn if_sequence<'tcx>(mut expr: &'tcx Expr<'tcx>) -> (Vec<&'tcx Expr<'tcx>>,
/// Checks if the given function kind is an async function. /// Checks if the given function kind is an async function.
pub fn is_async_fn(kind: FnKind<'_>) -> bool { pub fn is_async_fn(kind: FnKind<'_>) -> bool {
matches!(kind, FnKind::ItemFn(_, _, header, _) if header.asyncness == IsAsync::Async) matches!(kind, FnKind::ItemFn(_, _, header) if header.asyncness == IsAsync::Async)
} }
/// Peels away all the compiler generated code surrounding the body of an async function, /// Peels away all the compiler generated code surrounding the body of an async function,