Auto merge of #104963 - petrochenkov:noaddids2, r=cjgillot

rustc_ast_lowering: Stop lowering imports into multiple items

Lower them into a single item with multiple resolutions instead.
This also allows to remove additional `NodId`s and `DefId`s related to those additional items.
This commit is contained in:
bors 2022-12-02 04:24:57 +00:00
commit 11663b1b48
56 changed files with 229 additions and 326 deletions

View File

@ -2517,10 +2517,7 @@ pub struct Variant {
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum UseTreeKind {
/// `use prefix` or `use prefix as rename`
///
/// The extra `NodeId`s are for HIR lowering, when additional statements are created for each
/// namespace.
Simple(Option<Ident>, NodeId, NodeId),
Simple(Option<Ident>),
/// `use prefix::{...}`
Nested(Vec<(UseTree, NodeId)>),
/// `use prefix::*`
@ -2539,8 +2536,8 @@ pub struct UseTree {
impl UseTree {
pub fn ident(&self) -> Ident {
match self.kind {
UseTreeKind::Simple(Some(rename), ..) => rename,
UseTreeKind::Simple(None, ..) => {
UseTreeKind::Simple(Some(rename)) => rename,
UseTreeKind::Simple(None) => {
self.prefix.segments.last().expect("empty prefix in a simple import").ident
}
_ => panic!("`UseTree::ident` can only be used on a simple import"),

View File

@ -410,11 +410,7 @@ pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) {
let UseTree { prefix, kind, span } = use_tree;
vis.visit_path(prefix);
match kind {
UseTreeKind::Simple(rename, id1, id2) => {
visit_opt(rename, |rename| vis.visit_ident(rename));
vis.visit_id(id1);
vis.visit_id(id2);
}
UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)),
UseTreeKind::Nested(items) => {
for (tree, id) in items {
vis.visit_use_tree(tree);

View File

@ -439,7 +439,7 @@ pub fn walk_path<'a, V: Visitor<'a>>(visitor: &mut V, path: &'a Path) {
pub fn walk_use_tree<'a, V: Visitor<'a>>(visitor: &mut V, use_tree: &'a UseTree, id: NodeId) {
visitor.visit_path(&use_tree.prefix, id);
match &use_tree.kind {
UseTreeKind::Simple(rename, ..) => {
UseTreeKind::Simple(rename) => {
// The extra IDs are handled during HIR lowering.
if let &Some(rename) = rename {
visitor.visit_ident(rename);

View File

@ -19,7 +19,6 @@ use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{Span, Symbol};
use rustc_target::spec::abi;
use smallvec::{smallvec, SmallVec};
use std::iter;
use thin_vec::ThinVec;
pub(super) struct ItemLowerer<'a, 'hir> {
@ -179,36 +178,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
let mut node_ids =
smallvec![hir::ItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } }];
if let ItemKind::Use(use_tree) = &i.kind {
self.lower_item_id_use_tree(use_tree, i.id, &mut node_ids);
self.lower_item_id_use_tree(use_tree, &mut node_ids);
}
node_ids
}
fn lower_item_id_use_tree(
&mut self,
tree: &UseTree,
base_id: NodeId,
vec: &mut SmallVec<[hir::ItemId; 1]>,
) {
fn lower_item_id_use_tree(&mut self, tree: &UseTree, vec: &mut SmallVec<[hir::ItemId; 1]>) {
match &tree.kind {
UseTreeKind::Nested(nested_vec) => {
for &(ref nested, id) in nested_vec {
vec.push(hir::ItemId {
owner_id: hir::OwnerId { def_id: self.local_def_id(id) },
});
self.lower_item_id_use_tree(nested, id, vec);
}
}
UseTreeKind::Glob => {}
UseTreeKind::Simple(_, id1, id2) => {
for (_, id) in
iter::zip(self.expect_full_res_from_use(base_id).skip(1), [*id1, *id2])
{
vec.push(hir::ItemId {
owner_id: hir::OwnerId { def_id: self.local_def_id(id) },
});
self.lower_item_id_use_tree(nested, vec);
}
}
UseTreeKind::Simple(..) | UseTreeKind::Glob => {}
}
}
@ -489,7 +474,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect();
match tree.kind {
UseTreeKind::Simple(rename, id1, id2) => {
UseTreeKind::Simple(rename) => {
*ident = tree.ident();
// First, apply the prefix to the path.
@ -505,66 +490,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}
let mut resolutions = self.expect_full_res_from_use(id).fuse();
// We want to return *something* from this function, so hold onto the first item
// for later.
let ret_res = self.lower_res(resolutions.next().unwrap_or(Res::Err));
// Here, we are looping over namespaces, if they exist for the definition
// being imported. We only handle type and value namespaces because we
// won't be dealing with macros in the rest of the compiler.
// Essentially a single `use` which imports two names is desugared into
// two imports.
for new_node_id in [id1, id2] {
let new_id = self.local_def_id(new_node_id);
let Some(res) = resolutions.next() else {
debug_assert!(self.children.iter().find(|(id, _)| id == &new_id).is_none());
// Associate an HirId to both ids even if there is no resolution.
self.children.push((
new_id,
hir::MaybeOwner::NonOwner(hir::HirId::make_owner(new_id))),
);
continue;
};
let ident = *ident;
let mut path = path.clone();
for seg in &mut path.segments {
// Give the cloned segment the same resolution information
// as the old one (this is needed for stability checking).
let new_id = self.next_node_id();
self.resolver.clone_res(seg.id, new_id);
seg.id = new_id;
}
let span = path.span;
self.with_hir_id_owner(new_node_id, |this| {
let res = this.lower_res(res);
let path = this.lower_path_extra(res, &path, ParamMode::Explicit);
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
if let Some(attrs) = attrs {
this.attrs.insert(hir::ItemLocalId::new(0), attrs);
}
let item = hir::Item {
owner_id: hir::OwnerId { def_id: new_id },
ident: this.lower_ident(ident),
kind,
vis_span,
span: this.lower_span(span),
};
hir::OwnerNode::Item(this.arena.alloc(item))
});
}
let path = self.lower_path_extra(ret_res, &path, ParamMode::Explicit);
let res =
self.expect_full_res_from_use(id).map(|res| self.lower_res(res)).collect();
let path = self.lower_use_path(res, &path, ParamMode::Explicit);
hir::ItemKind::Use(path, hir::UseKind::Single)
}
UseTreeKind::Glob => {
let path = self.lower_path(
id,
&Path { segments, span: path.span, tokens: None },
ParamMode::Explicit,
);
let res = self.expect_full_res(id);
let res = smallvec![self.lower_res(res)];
let path = Path { segments, span: path.span, tokens: None };
let path = self.lower_use_path(res, &path, ParamMode::Explicit);
hir::ItemKind::Use(path, hir::UseKind::Glob)
}
UseTreeKind::Nested(ref trees) => {
@ -634,9 +569,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
});
}
let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err);
let res = self.lower_res(res);
let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit);
let res =
self.expect_full_res_from_use(id).map(|res| self.lower_res(res)).collect();
let path = self.lower_use_path(res, &prefix, ParamMode::Explicit);
hir::ItemKind::Use(path, hir::UseKind::ListStem)
}
}

View File

@ -12,7 +12,7 @@ use rustc_hir::GenericArg;
use rustc_span::symbol::{kw, Ident};
use rustc_span::{BytePos, Span, DUMMY_SP};
use smallvec::smallvec;
use smallvec::{smallvec, SmallVec};
impl<'a, 'hir> LoweringContext<'a, 'hir> {
#[instrument(level = "trace", skip(self))]
@ -144,13 +144,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
);
}
pub(crate) fn lower_path_extra(
pub(crate) fn lower_use_path(
&mut self,
res: Res,
res: SmallVec<[Res; 3]>,
p: &Path,
param_mode: ParamMode,
) -> &'hir hir::Path<'hir> {
self.arena.alloc(hir::Path {
) -> &'hir hir::UsePath<'hir> {
self.arena.alloc(hir::UsePath {
res,
segments: self.arena.alloc_from_iter(p.segments.iter().map(|segment| {
self.lower_path_segment(
@ -165,17 +165,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
})
}
pub(crate) fn lower_path(
&mut self,
id: NodeId,
p: &Path,
param_mode: ParamMode,
) -> &'hir hir::Path<'hir> {
let res = self.expect_full_res(id);
let res = self.lower_res(res);
self.lower_path_extra(res, p, param_mode)
}
pub(crate) fn lower_path_segment(
&mut self,
path_span: Span,

View File

@ -663,7 +663,7 @@ impl<'a> State<'a> {
fn print_use_tree(&mut self, tree: &ast::UseTree) {
match &tree.kind {
ast::UseTreeKind::Simple(rename, ..) => {
ast::UseTreeKind::Simple(rename) => {
self.print_path(&tree.prefix, false, 0);
if let &Some(rename) = rename {
self.nbsp();

View File

@ -106,7 +106,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
(
UseTree {
prefix: this.cx.path(this.span, vec![Ident::with_dummy_span(sym)]),
kind: UseTreeKind::Simple(None, DUMMY_NODE_ID, DUMMY_NODE_ID),
kind: UseTreeKind::Simple(None),
span: this.span,
},
DUMMY_NODE_ID,

View File

@ -399,7 +399,7 @@ where
}
}
impl<A, CTX> HashStable<CTX> for SmallVec<[A; 1]>
impl<A, const N: usize, CTX> HashStable<CTX> for SmallVec<[A; N]>
where
A: HashStable<CTX>,
{

View File

@ -39,6 +39,7 @@ macro_rules! arena_types {
[] param: rustc_hir::Param<'tcx>,
[] pat: rustc_hir::Pat<'tcx>,
[] path: rustc_hir::Path<'tcx>,
[] use_path: rustc_hir::UsePath<'tcx>,
[] path_segment: rustc_hir::PathSegment<'tcx>,
[] poly_trait_ref: rustc_hir::PolyTraitRef<'tcx>,
[] qpath: rustc_hir::QPath<'tcx>,

View File

@ -183,14 +183,17 @@ impl Lifetime {
/// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
/// along with a bunch of supporting information.
#[derive(Debug, HashStable_Generic)]
pub struct Path<'hir> {
pub struct Path<'hir, R = Res> {
pub span: Span,
/// The resolution for the path.
pub res: Res,
pub res: R,
/// The segments in the path: the things separated by `::`.
pub segments: &'hir [PathSegment<'hir>],
}
/// Up to three resolutions for type, value and macro namespaces.
pub type UsePath<'hir> = Path<'hir, SmallVec<[Res; 3]>>;
impl Path<'_> {
pub fn is_global(&self) -> bool {
!self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot
@ -3068,7 +3071,7 @@ pub enum ItemKind<'hir> {
/// or just
///
/// `use foo::bar::baz;` (with `as baz` implicitly on the right).
Use(&'hir Path<'hir>, UseKind),
Use(&'hir UsePath<'hir>, UseKind),
/// A `static` item.
Static(&'hir Ty<'hir>, Mutability, BodyId),

View File

@ -367,7 +367,7 @@ pub trait Visitor<'v>: Sized {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl<'v>, b: BodyId, _: Span, id: HirId) {
walk_fn(self, fk, fd, b, id)
}
fn visit_use(&mut self, path: &'v Path<'v>, hir_id: HirId) {
fn visit_use(&mut self, path: &'v UsePath<'v>, hir_id: HirId) {
walk_use(self, path, hir_id)
}
fn visit_trait_item(&mut self, ti: &'v TraitItem<'v>) {
@ -422,7 +422,7 @@ pub trait Visitor<'v>: Sized {
fn visit_qpath(&mut self, qpath: &'v QPath<'v>, id: HirId, _span: Span) {
walk_qpath(self, qpath, id)
}
fn visit_path(&mut self, path: &'v Path<'v>, _id: HirId) {
fn visit_path(&mut self, path: &Path<'v>, _id: HirId) {
walk_path(self, path)
}
fn visit_path_segment(&mut self, path_segment: &'v PathSegment<'v>) {
@ -938,9 +938,12 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'
}
}
pub fn walk_use<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path<'v>, hir_id: HirId) {
pub fn walk_use<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v UsePath<'v>, hir_id: HirId) {
visitor.visit_id(hir_id);
visitor.visit_path(path, hir_id);
let UsePath { segments, ref res, span } = *path;
for &res in res {
visitor.visit_path(&Path { segments, res, span }, hir_id);
}
}
pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem<'v>) {
@ -1126,7 +1129,7 @@ pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath<'v>, id:
}
}
pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path<'v>) {
pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &Path<'v>) {
for segment in path.segments {
visitor.visit_path_segment(segment);
}

View File

@ -814,7 +814,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}
}
fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, _: hir::HirId) {
fn visit_path(&mut self, path: &hir::Path<'tcx>, _: hir::HirId) {
for (i, segment) in path.segments.iter().enumerate() {
let depth = path.segments.len() - i - 1;
if let Some(ref args) = segment.args {

View File

@ -1591,7 +1591,7 @@ impl<'a> State<'a> {
self.print_ident(Ident::with_dummy_span(name))
}
pub fn print_path(&mut self, path: &hir::Path<'_>, colons_before_params: bool) {
pub fn print_path<R>(&mut self, path: &hir::Path<'_, R>, colons_before_params: bool) {
self.maybe_print_comment(path.span.lo());
for (i, segment) in path.segments.iter().enumerate() {

View File

@ -117,7 +117,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
fn check_path(
&mut self,
cx: &LateContext<'tcx>,
path: &'tcx rustc_hir::Path<'tcx>,
path: &rustc_hir::Path<'tcx>,
_: rustc_hir::HirId,
) {
if let Some(segment) = path.segments.iter().nth_back(1)

View File

@ -292,7 +292,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
hir_visit::walk_lifetime(self, lt);
}
fn visit_path(&mut self, p: &'tcx hir::Path<'tcx>, id: hir::HirId) {
fn visit_path(&mut self, p: &hir::Path<'tcx>, id: hir::HirId) {
lint_callback!(self, check_path, p, id);
hir_visit::walk_path(self, p);
}

View File

@ -44,7 +44,7 @@ macro_rules! late_lint_methods {
fn check_struct_def(a: &$hir hir::VariantData<$hir>);
fn check_field_def(a: &$hir hir::FieldDef<$hir>);
fn check_variant(a: &$hir hir::Variant<$hir>);
fn check_path(a: &$hir hir::Path<$hir>, b: hir::HirId);
fn check_path(a: &hir::Path<$hir>, b: hir::HirId);
fn check_attribute(a: &$hir ast::Attribute);
/// Called when entering a syntax node that can have lint attributes such

View File

@ -1264,7 +1264,7 @@ impl UnusedImportBraces {
// Trigger the lint if the nested item is a non-self single item
let node_name = match items[0].0.kind {
ast::UseTreeKind::Simple(rename, ..) => {
ast::UseTreeKind::Simple(rename) => {
let orig_ident = items[0].0.prefix.segments.last().unwrap().ident;
if orig_ident.name == kw::SelfLower {
return;

View File

@ -1012,7 +1012,7 @@ impl<'a> Parser<'a> {
prefix.span = lo.to(self.prev_token.span);
}
UseTreeKind::Simple(self.parse_rename()?, DUMMY_NODE_ID, DUMMY_NODE_ID)
UseTreeKind::Simple(self.parse_rename()?)
}
};

View File

@ -433,7 +433,7 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
self.in_pat = false;
}
fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, _: hir::HirId) {
fn visit_path(&mut self, path: &hir::Path<'tcx>, _: hir::HirId) {
self.handle_res(path.res);
intravisit::walk_path(self, path);
}

View File

@ -369,7 +369,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
hir_visit::walk_fn(self, fk, fd, b, id)
}
fn visit_use(&mut self, p: &'v hir::Path<'v>, hir_id: hir::HirId) {
fn visit_use(&mut self, p: &'v hir::UsePath<'v>, hir_id: hir::HirId) {
// This is `visit_use`, but the type is `Path` so record it that way.
self.record("Path", Id::None, p);
hir_visit::walk_use(self, p, hir_id)
@ -442,7 +442,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
hir_visit::walk_lifetime(self, lifetime)
}
fn visit_path(&mut self, path: &'v hir::Path<'v>, _id: hir::HirId) {
fn visit_path(&mut self, path: &hir::Path<'v>, _id: hir::HirId) {
self.record("Path", Id::None, path);
hir_visit::walk_path(self, path)
}

View File

@ -787,7 +787,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
intravisit::walk_item(self, item);
}
fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, id: hir::HirId) {
fn visit_path(&mut self, path: &hir::Path<'tcx>, id: hir::HirId) {
if let Some(def_id) = path.res.opt_def_id() {
let method_span = path.segments.last().map(|s| s.ident.span);
let item_is_allowed = self.tcx.check_stability_allow_unstable(
@ -880,7 +880,7 @@ struct CheckTraitImplStable<'tcx> {
}
impl<'tcx> Visitor<'tcx> for CheckTraitImplStable<'tcx> {
fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, _id: hir::HirId) {
fn visit_path(&mut self, path: &hir::Path<'tcx>, _id: hir::HirId) {
if let Some(def_id) = path.res.opt_def_id() {
if let Some(stab) = self.tcx.lookup_stability(def_id) {
self.fully_stable &= stab.level.is_stable();

View File

@ -66,7 +66,7 @@ impl CaptureCollector<'_, '_> {
}
impl<'tcx> Visitor<'tcx> for CaptureCollector<'_, 'tcx> {
fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, _: hir::HirId) {
fn visit_path(&mut self, path: &hir::Path<'tcx>, _: hir::HirId) {
if let Res::Local(var_id) = path.res {
self.visit_local_use(var_id, path.span);
}

View File

@ -445,19 +445,13 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
prefix.is_empty() || prefix.len() == 1 && prefix[0].ident.name == kw::PathRoot
};
match use_tree.kind {
ast::UseTreeKind::Simple(rename, id1, id2) => {
ast::UseTreeKind::Simple(rename) => {
let mut ident = use_tree.ident();
let mut module_path = prefix;
let mut source = module_path.pop().unwrap();
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 {
// Correctly handle `self`
@ -565,7 +559,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
type_ns_only,
nested,
id,
additional_ids: (id1, id2),
};
self.add_import(module_path, kind, use_tree.span, item, root_span, item.id, vis);
@ -621,11 +614,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
let new_span = prefix[prefix.len() - 1].ident.span;
let tree = ast::UseTree {
prefix: ast::Path::from_ident(Ident::new(kw::SelfLower, new_span)),
kind: ast::UseTreeKind::Simple(
Some(Ident::new(kw::Underscore, new_span)),
ast::DUMMY_NODE_ID,
ast::DUMMY_NODE_ID,
),
kind: ast::UseTreeKind::Simple(Some(Ident::new(kw::Underscore, new_span))),
span: use_tree.span,
};
self.build_reduced_graph_for_use_tree(

View File

@ -158,14 +158,6 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) {
self.create_def(id, DefPathData::Use, use_tree.span);
match use_tree.kind {
UseTreeKind::Simple(_, id1, id2) => {
self.create_def(id1, DefPathData::Use, use_tree.prefix.span);
self.create_def(id2, DefPathData::Use, use_tree.prefix.span);
}
UseTreeKind::Glob => (),
UseTreeKind::Nested(..) => {}
}
visit::walk_use_tree(self, use_tree, id);
}

View File

@ -1,4 +1,4 @@
use crate::{ImportKind, NameBinding, NameBindingKind, Resolver, ResolverTree};
use crate::{NameBinding, NameBindingKind, Resolver, ResolverTree};
use rustc_ast::ast;
use rustc_ast::visit;
use rustc_ast::visit::Visitor;
@ -104,28 +104,11 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
for (binding, eff_vis) in visitor.import_effective_visibilities.iter() {
let NameBindingKind::Import { import, .. } = binding.kind else { unreachable!() };
if let Some(node_id) = import.id() {
let mut update = |node_id| {
r.effective_visibilities.update_eff_vis(
r.local_def_id(node_id),
eff_vis,
ResolverTree(&r.definitions, &r.crate_loader),
)
};
update(node_id);
if let ImportKind::Single { additional_ids: (id1, id2), .. } = import.kind {
// In theory all the single import IDs have individual visibilities and
// effective visibilities, but in practice these IDs go straight to HIR
// where all their few uses assume that their (effective) visibility
// applies to the whole syntactic `use` item. So they all get the same
// value which is the maximum of all bindings. Maybe HIR for imports
// shouldn't use three IDs at all.
if id1 != ast::DUMMY_NODE_ID {
update(id1);
}
if id2 != ast::DUMMY_NODE_ID {
update(id2);
}
}
}
}

View File

@ -56,9 +56,6 @@ pub enum ImportKind<'a> {
/// If this is the import for `foo::bar::a`, we would have the ID of the `UseTree`
/// for `a` in this field.
id: NodeId,
/// Additional `NodeId`s allocated to a `ast::UseTree` for automatically generated `use` statement
/// (eg. implicit struct constructors)
additional_ids: (NodeId, NodeId),
},
Glob {
is_prelude: bool,
@ -88,7 +85,6 @@ impl<'a> std::fmt::Debug for ImportKind<'a> {
ref type_ns_only,
ref nested,
ref id,
ref additional_ids,
// Ignore the following to avoid an infinite loop while printing.
source_bindings: _,
target_bindings: _,
@ -99,7 +95,6 @@ impl<'a> std::fmt::Debug for ImportKind<'a> {
.field("type_ns_only", type_ns_only)
.field("nested", nested)
.field("id", id)
.field("additional_ids", additional_ids)
.finish_non_exhaustive(),
Glob { ref is_prelude, ref max_vis, ref id } => f
.debug_struct("Glob")

View File

@ -185,13 +185,13 @@ impl<'tcx> DumpVisitor<'tcx> {
}
}
fn write_sub_paths(&mut self, path: &'tcx hir::Path<'tcx>) {
fn write_sub_paths<R>(&mut self, path: &'tcx hir::Path<'tcx, R>) {
self.write_segments(path.segments)
}
// As write_sub_paths, but does not process the last ident in the path (assuming it
// will be processed elsewhere). See note on write_sub_paths about global.
fn write_sub_paths_truncated(&mut self, path: &'tcx hir::Path<'tcx>) {
fn write_sub_paths_truncated<R>(&mut self, path: &'tcx hir::Path<'tcx, R>) {
if let [segments @ .., _] = path.segments {
self.write_segments(segments)
}

View File

@ -594,7 +594,9 @@ impl<'tcx> SaveContext<'tcx> {
match self.tcx.hir().get(hir_id) {
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.get(0).copied().unwrap_or(Res::Err)
}
Node::PathSegment(seg) => {
if seg.res != Res::Err {
seg.res

View File

@ -2231,6 +2231,26 @@ fn clean_extern_crate<'tcx>(
}
fn clean_use_statement<'tcx>(
import: &hir::Item<'tcx>,
name: Symbol,
path: &hir::UsePath<'tcx>,
kind: hir::UseKind,
cx: &mut DocContext<'tcx>,
inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
) -> Vec<Item> {
let mut items = Vec::new();
let hir::UsePath { segments, ref res, span } = *path;
for &res in res {
if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res {
continue;
}
let path = hir::Path { segments, res, span };
items.append(&mut clean_use_statement_inner(import, name, &path, kind, cx, inlined_names));
}
items
}
fn clean_use_statement_inner<'tcx>(
import: &hir::Item<'tcx>,
name: Symbol,
path: &hir::Path<'tcx>,

View File

@ -242,7 +242,9 @@ impl ExternalCrate {
hir::ItemKind::Use(path, hir::UseKind::Single)
if tcx.visibility(id.owner_id).is_public() =>
{
as_keyword(path.res.expect_non_local())
path.res
.iter()
.find_map(|res| as_keyword(res.expect_non_local()))
.map(|(_, prim)| (id.owner_id.to_def_id(), prim))
}
_ => None,
@ -310,10 +312,11 @@ impl ExternalCrate {
hir::ItemKind::Use(path, hir::UseKind::Single)
if tcx.visibility(id.owner_id).is_public() =>
{
as_primitive(path.res.expect_non_local()).map(|(_, prim)| {
path.res
.iter()
.find_map(|res| as_primitive(res.expect_non_local()))
// Pretend the primitive is local.
(id.owner_id.to_def_id(), prim)
})
.map(|(_, prim)| (id.owner_id.to_def_id(), prim))
}
_ => None,
}

View File

@ -489,7 +489,7 @@ impl<'tcx> Visitor<'tcx> for EmitIgnoredResolutionErrors<'tcx> {
self.tcx.hir()
}
fn visit_path(&mut self, path: &'tcx Path<'_>, _id: HirId) {
fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) {
debug!("visiting path {:?}", path);
if path.res == Res::Err {
// We have less context here than in rustc_resolve,

View File

@ -140,7 +140,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
self.tcx.hir()
}
fn visit_path(&mut self, path: &'tcx rustc_hir::Path<'tcx>, _id: HirId) {
fn visit_path(&mut self, path: &rustc_hir::Path<'tcx>, _id: HirId) {
if self.handle_macro(path.span) {
return;
}
@ -190,12 +190,4 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
}
intravisit::walk_expr(self, expr);
}
fn visit_use(&mut self, path: &'tcx rustc_hir::Path<'tcx>, id: HirId) {
if self.handle_macro(path.span) {
return;
}
self.handle_path(path);
intravisit::walk_use(self, path, id);
}
}

View File

@ -225,10 +225,10 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
types::ItemEnum::Function(_)
| types::ItemEnum::Module(_)
| types::ItemEnum::Import(_)
| types::ItemEnum::AssocConst { .. }
| types::ItemEnum::AssocType { .. } => true,
types::ItemEnum::ExternCrate { .. }
| types::ItemEnum::Import(_)
| types::ItemEnum::StructField(_)
| types::ItemEnum::Variant(_)
| types::ItemEnum::TraitAlias(_)

View File

@ -301,12 +301,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
hir::ItemKind::GlobalAsm(..) => {}
hir::ItemKind::Use(_, hir::UseKind::ListStem) => {}
hir::ItemKind::Use(path, kind) => {
let is_glob = kind == hir::UseKind::Glob;
for &res in &path.res {
// Struct and variant constructors and proc macro stubs always show up alongside
// their definitions, we've already processed them so just discard these.
if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = path.res {
return;
if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res {
continue;
}
let attrs = self.cx.tcx.hir().attrs(item.hir_id());
@ -320,21 +319,23 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
}
_ => false,
});
let is_glob = kind == hir::UseKind::Glob;
let ident = if is_glob { None } else { Some(name) };
if self.maybe_inline_local(
item.hir_id(),
path.res,
res,
ident,
is_glob,
om,
please_inline,
) {
return;
continue;
}
}
om.items.push((item, renamed, parent_id))
}
}
hir::ItemKind::Macro(ref macro_def, _) => {
// `#[macro_export] macro_rules!` items are handled separately in `visit()`,
// above, since they need to be documented at the module top level. Accordingly,

View File

@ -2,13 +2,13 @@ error[E0080]: could not evaluate static initializer
--> $DIR/tls.rs:11:25
|
LL | unsafe { let _val = A; }
| ^ cannot access thread local static (DefId(0:6 ~ tls[78b0]::A))
| ^ cannot access thread local static (DefId(0:4 ~ tls[78b0]::A))
error[E0080]: could not evaluate static initializer
--> $DIR/tls.rs:18:26
|
LL | unsafe { let _val = &A; }
| ^ cannot access thread local static (DefId(0:6 ~ tls[78b0]::A))
| ^ cannot access thread local static (DefId(0:4 ~ tls[78b0]::A))
warning: skipping const checks
|

View File

@ -9,7 +9,7 @@ note: generator is not `Send` as this value is used across a yield
--> $DIR/generator-print-verbose-1.rs:35:9
|
LL | let _non_send_gen = make_non_send_generator();
| ------------- has type `Opaque(DefId(0:44 ~ generator_print_verbose_1[749a]::make_non_send_generator::{opaque#0}), [])` which is not `Send`
| ------------- has type `Opaque(DefId(0:34 ~ generator_print_verbose_1[749a]::make_non_send_generator::{opaque#0}), [])` which is not `Send`
LL | yield;
| ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
LL | };
@ -35,17 +35,17 @@ note: required because it's used within this generator
|
LL | || {
| ^^
note: required because it appears within the type `Opaque(DefId(0:45 ~ generator_print_verbose_1[749a]::make_gen2::{opaque#0}), [std::sync::Arc<std::cell::RefCell<i32>>])`
note: required because it appears within the type `Opaque(DefId(0:35 ~ generator_print_verbose_1[749a]::make_gen2::{opaque#0}), [std::sync::Arc<std::cell::RefCell<i32>>])`
--> $DIR/generator-print-verbose-1.rs:41:30
|
LL | pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
note: required because it appears within the type `Opaque(DefId(0:46 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`
note: required because it appears within the type `Opaque(DefId(0:36 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`
--> $DIR/generator-print-verbose-1.rs:47:34
|
LL | fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: required because it captures the following types: `Opaque(DefId(0:46 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`, `()`
= note: required because it captures the following types: `Opaque(DefId(0:36 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`, `()`
note: required because it's used within this generator
--> $DIR/generator-print-verbose-1.rs:52:20
|

View File

@ -108,22 +108,22 @@ LL | type Bar<'b>;
= note: this bound is currently required to ensure that impls have maximum flexibility
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Item`
--> $DIR/self-outlives-lint.rs:140:5
error: missing required bound on `Iterator`
--> $DIR/self-outlives-lint.rs:142:5
|
LL | type Item<'a>;
| ^^^^^^^^^^^^^-
LL | type Iterator<'a>: Iterator<Item = Self::Item<'a>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: add the required where clause: `where Self: 'a`
|
= note: this bound is currently required to ensure that impls have maximum flexibility
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Iterator`
--> $DIR/self-outlives-lint.rs:142:5
error: missing required bound on `Item`
--> $DIR/self-outlives-lint.rs:140:5
|
LL | type Iterator<'a>: Iterator<Item = Self::Item<'a>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
LL | type Item<'a>;
| ^^^^^^^^^^^^^-
| |
| help: add the required where clause: `where Self: 'a`
|

View File

@ -72,6 +72,5 @@ mod half_public_import {
#[rustc_effective_visibility]
pub use half_public_import::HalfPublicImport; //~ ERROR Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
//~^ ERROR Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
fn main() {}

View File

@ -124,12 +124,6 @@ error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait:
LL | pub use half_public_import::HalfPublicImport;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:74:9
|
LL | pub use half_public_import::HalfPublicImport;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:14:13
|
@ -142,5 +136,5 @@ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImpl
LL | type B;
| ^^^^^^
error: aborting due to 24 previous errors
error: aborting due to 23 previous errors

View File

@ -120,59 +120,59 @@ hir-stats Name Accumulated Size Count Item Size
hir-stats ----------------------------------------------------------------
hir-stats ForeignItemRef 24 ( 0.3%) 1 24
hir-stats Lifetime 24 ( 0.3%) 1 24
hir-stats Mod 32 ( 0.3%) 1 32
hir-stats Mod 32 ( 0.4%) 1 32
hir-stats ExprField 40 ( 0.4%) 1 40
hir-stats TraitItemRef 56 ( 0.6%) 2 28
hir-stats Local 64 ( 0.7%) 1 64
hir-stats Param 64 ( 0.7%) 2 32
hir-stats InlineAsm 72 ( 0.8%) 1 72
hir-stats ImplItemRef 72 ( 0.8%) 2 36
hir-stats Body 96 ( 1.0%) 3 32
hir-stats FieldDef 96 ( 1.0%) 2 48
hir-stats Arm 96 ( 1.0%) 2 48
hir-stats Stmt 96 ( 1.0%) 3 32
hir-stats - Local 32 ( 0.3%) 1
hir-stats - Semi 32 ( 0.3%) 1
hir-stats - Expr 32 ( 0.3%) 1
hir-stats Body 96 ( 1.1%) 3 32
hir-stats FieldDef 96 ( 1.1%) 2 48
hir-stats Arm 96 ( 1.1%) 2 48
hir-stats Stmt 96 ( 1.1%) 3 32
hir-stats - Local 32 ( 0.4%) 1
hir-stats - Semi 32 ( 0.4%) 1
hir-stats - Expr 32 ( 0.4%) 1
hir-stats FnDecl 120 ( 1.3%) 3 40
hir-stats Attribute 128 ( 1.4%) 4 32
hir-stats GenericArg 128 ( 1.4%) 4 32
hir-stats - Type 32 ( 0.3%) 1
hir-stats - Lifetime 96 ( 1.0%) 3
hir-stats - Type 32 ( 0.4%) 1
hir-stats - Lifetime 96 ( 1.1%) 3
hir-stats GenericArgs 144 ( 1.6%) 3 48
hir-stats Variant 176 ( 1.9%) 2 88
hir-stats GenericBound 192 ( 2.1%) 4 48
hir-stats - Trait 192 ( 2.1%) 4
hir-stats WherePredicate 192 ( 2.1%) 3 64
hir-stats - BoundPredicate 192 ( 2.1%) 3
hir-stats Block 288 ( 3.1%) 6 48
hir-stats Pat 360 ( 3.9%) 5 72
hir-stats Block 288 ( 3.2%) 6 48
hir-stats Pat 360 ( 4.0%) 5 72
hir-stats - Wild 72 ( 0.8%) 1
hir-stats - Struct 72 ( 0.8%) 1
hir-stats - Binding 216 ( 2.4%) 3
hir-stats GenericParam 400 ( 4.4%) 5 80
hir-stats Generics 560 ( 6.1%) 10 56
hir-stats Ty 720 ( 7.9%) 15 48
hir-stats Generics 560 ( 6.2%) 10 56
hir-stats Ty 720 ( 8.0%) 15 48
hir-stats - Ptr 48 ( 0.5%) 1
hir-stats - Rptr 48 ( 0.5%) 1
hir-stats - Path 624 ( 6.8%) 13
hir-stats Expr 768 ( 8.4%) 12 64
hir-stats - Path 624 ( 6.9%) 13
hir-stats Expr 768 ( 8.5%) 12 64
hir-stats - Path 64 ( 0.7%) 1
hir-stats - Struct 64 ( 0.7%) 1
hir-stats - Match 64 ( 0.7%) 1
hir-stats - InlineAsm 64 ( 0.7%) 1
hir-stats - Lit 128 ( 1.4%) 2
hir-stats - Block 384 ( 4.2%) 6
hir-stats Item 960 (10.5%) 12 80
hir-stats Item 880 ( 9.7%) 11 80
hir-stats - Trait 80 ( 0.9%) 1
hir-stats - Enum 80 ( 0.9%) 1
hir-stats - ExternCrate 80 ( 0.9%) 1
hir-stats - ForeignMod 80 ( 0.9%) 1
hir-stats - Impl 80 ( 0.9%) 1
hir-stats - Fn 160 ( 1.7%) 2
hir-stats - Use 400 ( 4.4%) 5
hir-stats Path 1_280 (14.0%) 32 40
hir-stats PathSegment 1_920 (20.9%) 40 48
hir-stats - Fn 160 ( 1.8%) 2
hir-stats - Use 320 ( 3.5%) 4
hir-stats Path 1_240 (13.7%) 31 40
hir-stats PathSegment 1_920 (21.2%) 40 48
hir-stats ----------------------------------------------------------------
hir-stats Total 9_168
hir-stats Total 9_048
hir-stats

View File

@ -106,7 +106,9 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
if let ItemKind::Use(path, UseKind::Single) = &item.kind {
self.check_res_emit(cx, &path.res, item.span);
for res in &path.res {
self.check_res_emit(cx, res, item.span);
}
}
}

View File

@ -126,7 +126,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SelfFinder<'a, 'tcx> {
self.cx.tcx.hir()
}
fn visit_path(&mut self, path: &'tcx Path<'tcx>, _id: HirId) {
fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) {
for segment in path.segments {
match segment.ident.name {
kw::SelfLower => self.lower.push(segment.ident.span),

View File

@ -94,7 +94,10 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
let hir_id = item.hir_id();
let attrs = cx.tcx.hir().attrs(hir_id);
if let Some(mac_attr) = attrs.iter().find(|attr| attr.has_name(sym::macro_use));
if let Res::Def(DefKind::Mod, id) = path.res;
if let Some(id) = path.res.iter().find_map(|res| match res {
Res::Def(DefKind::Mod, id) => Some(id),
_ => None,
});
if !id.is_local();
then {
for kid in cx.tcx.module_children(id).iter() {

View File

@ -97,7 +97,7 @@ struct UnwrapVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for UnwrapVisitor<'a, 'tcx> {
type NestedFilter = nested_filter::All;
fn visit_path(&mut self, path: &'tcx Path<'_>, _id: HirId) {
fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) {
self.identifiers.insert(ident(path));
walk_path(self, path);
}
@ -116,7 +116,7 @@ struct MapExprVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for MapExprVisitor<'a, 'tcx> {
type NestedFilter = nested_filter::All;
fn visit_path(&mut self, path: &'tcx Path<'_>, _id: HirId) {
fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) {
if self.identifiers.contains(&ident(path)) {
self.found_identifier = true;
return;

View File

@ -66,9 +66,10 @@ impl LateLintPass<'_> for ImportRename {
}
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
if let ItemKind::Use(path, UseKind::Single) = &item.kind {
for &res in &path.res {
if_chain! {
if let ItemKind::Use(path, UseKind::Single) = &item.kind;
if let Res::Def(_, id) = path.res;
if let Res::Def(_, id) = res;
if let Some(name) = self.renames.get(&id);
// Remove semicolon since it is not present for nested imports
let span_without_semi = cx.sess().source_map().span_until_char(item.span, ';');
@ -98,4 +99,6 @@ impl LateLintPass<'_> for ImportRename {
}
}
}
}
}
}

View File

@ -84,7 +84,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
fn is_not_macro_export<'tcx>(item: &'tcx Item<'tcx>) -> bool {
if let ItemKind::Use(path, _) = item.kind {
if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = path.res {
if path.res.iter().all(|res| matches!(res, Res::Def(DefKind::Macro(MacroKind::Bang), _))) {
return false;
}
} else if let ItemKind::Macro(..) = item.kind {

View File

@ -149,7 +149,7 @@ impl SingleComponentPathImports {
// keep track of `use some_module;` usages
if segments.len() == 1 {
if let UseTreeKind::Simple(None, _, _) = use_tree.kind {
if let UseTreeKind::Simple(None) = use_tree.kind {
let name = segments[0].ident.name;
if !macros.contains(&name) {
single_use_usages.push(SingleUse {
@ -169,7 +169,7 @@ impl SingleComponentPathImports {
for tree in trees {
let segments = &tree.0.prefix.segments;
if segments.len() == 1 {
if let UseTreeKind::Simple(None, _, _) = tree.0.kind {
if let UseTreeKind::Simple(None) = tree.0.kind {
let name = segments[0].ident.name;
if !macros.contains(&name) {
single_use_usages.push(SingleUse {

View File

@ -57,7 +57,7 @@ impl EarlyLintPass for UnnecessarySelfImports {
format!(
"{}{};",
last_segment.ident,
if let UseTreeKind::Simple(Some(alias), ..) = self_tree.kind { format!(" as {alias}") } else { String::new() },
if let UseTreeKind::Simple(Some(alias)) = self_tree.kind { format!(" as {alias}") } else { String::new() },
),
Applicability::MaybeIncorrect,
);

View File

@ -39,7 +39,7 @@ impl EarlyLintPass for UnsafeNameRemoval {
fn check_use_tree(use_tree: &UseTree, cx: &EarlyContext<'_>, span: Span) {
match use_tree.kind {
UseTreeKind::Simple(Some(new_name), ..) => {
UseTreeKind::Simple(Some(new_name)) => {
let old_name = use_tree
.prefix
.segments
@ -48,7 +48,7 @@ fn check_use_tree(use_tree: &UseTree, cx: &EarlyContext<'_>, span: Span) {
.ident;
unsafe_to_safe_check(old_name, new_name, cx, span);
},
UseTreeKind::Simple(None, ..) | UseTreeKind::Glob => {},
UseTreeKind::Simple(None) | UseTreeKind::Glob => {},
UseTreeKind::Nested(ref nested_use_tree) => {
for (use_tree, _) in nested_use_tree {
check_use_tree(use_tree, cx, span);

View File

@ -330,7 +330,7 @@ struct LintCollector<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for LintCollector<'a, 'tcx> {
type NestedFilter = nested_filter::All;
fn visit_path(&mut self, path: &'tcx Path<'_>, _: HirId) {
fn visit_path(&mut self, path: &Path<'_>, _: HirId) {
if path.segments.len() == 1 {
self.output.insert(path.segments[0].ident.name);
}

View File

@ -1019,7 +1019,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for ApplicabilityResolver<'a, 'hir> {
self.cx.tcx.hir()
}
fn visit_path(&mut self, path: &'hir hir::Path<'hir>, _id: hir::HirId) {
fn visit_path(&mut self, path: &hir::Path<'hir>, _id: hir::HirId) {
for (index, enum_value) in paths::APPLICABILITY_VALUES.iter().enumerate() {
if match_path(path, enum_value) {
self.add_new_index(index);

View File

@ -176,7 +176,8 @@ impl LateLintPass<'_> for WildcardImports {
format!("{import_source_snippet}::{imports_string}")
};
let (lint, message) = if let Res::Def(DefKind::Enum, _) = use_path.res {
// Glob imports always have a single resolution.
let (lint, message) = if let Res::Def(DefKind::Enum, _) = use_path.res[0] {
(ENUM_GLOB_USE, "usage of wildcard import for enum variants")
} else {
(WILDCARD_IMPORTS, "usage of wildcard import")

View File

@ -566,7 +566,7 @@ pub fn eq_use_tree_kind(l: &UseTreeKind, r: &UseTreeKind) -> bool {
use UseTreeKind::*;
match (l, r) {
(Glob, Glob) => true,
(Simple(l, _, _), Simple(r, _, _)) => both(l, r, |l, r| eq_id(*l, *r)),
(Simple(l), Simple(r)) => both(l, r, |l, r| eq_id(*l, *r)),
(Nested(l), Nested(r)) => over(l, r, |(l, _), (r, _)| eq_use_tree(l, r)),
_ => false,
}

View File

@ -128,7 +128,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for BindingUsageFinder<'a, 'tcx> {
}
}
fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, _: hir::HirId) {
fn visit_path(&mut self, path: &hir::Path<'tcx>, _: hir::HirId) {
if let hir::def::Res::Local(id) = path.res {
if self.binding_ids.contains(&id) {
self.usage_found = true;

View File

@ -1,8 +1,8 @@
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
--> $DIR/macro_use_imports.rs:23:5
--> $DIR/macro_use_imports.rs:25:5
|
LL | #[macro_use]
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::foofoo, inner::try_err};`
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;`
|
= note: `-D clippy::macro-use-imports` implied by `-D warnings`
@ -13,10 +13,10 @@ LL | #[macro_use]
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mini_mac::ClippyMiniMacroTest;`
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
--> $DIR/macro_use_imports.rs:25:5
--> $DIR/macro_use_imports.rs:23:5
|
LL | #[macro_use]
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;`
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::foofoo, inner::try_err};`
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
--> $DIR/macro_use_imports.rs:19:5

View File

@ -490,7 +490,7 @@ impl UseTree {
);
result.path.push(UseSegment { kind, version });
}
UseTreeKind::Simple(ref rename, ..) => {
UseTreeKind::Simple(ref rename) => {
// If the path has leading double colons and is composed of only 2 segments, then we
// bypass the call to path_to_imported_ident which would get only the ident and
// lose the path root, e.g., `that` in `::that`.