Move hir::Item::ident into hir::ItemKind.

`hir::Item` has an `ident` field.

- It's always non-empty for these item kinds: `ExternCrate`, `Static`,
  `Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`,
  Trait`, TraitAalis`.

- It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`,
  `Impl`.

- For `Use`, it is non-empty for `UseKind::Single` and empty for
  `UseKind::{Glob,ListStem}`.

All of this is quite non-obvious; the only documentation is a single
comment saying "The name might be a dummy name in case of anonymous
items". Some sites that handle items check for an empty ident, some
don't. This is a very C-like way of doing things, but this is Rust, we
have sum types, we can do this properly and never forget to check for
the exceptional case and never YOLO possibly empty identifiers (or
possibly dummy spans) around and hope that things will work out.

The commit is large but it's mostly obvious plumbing work. Some notable
things.

- A similar transformation makes sense for `ast::Item`, but this is
  already a big change. That can be done later.

- Lots of assertions are added to item lowering to ensure that
  identifiers are empty/non-empty as expected. These will be removable
  when `ast::Item` is done later.

- `ItemKind::Use` doesn't get an `Ident`, but `UseKind::Single` does.

- `lower_use_tree` is significantly simpler. No more confusing `&mut
  Ident` to deal with.

- `ItemKind::ident` is a new method, it returns an `Option<Ident>`. It's
  used with `unwrap` in a few places; sometimes it's hard to tell
  exactly which item kinds might occur. None of these unwraps fail on
  the test suite. It's conceivable that some might fail on alternative
  input. We can deal with those if/when they happen.

- In `trait_path` the `find_map`/`if let` is replaced with a loop, and
  things end up much clearer that way.

- `named_span` no longer checks for an empty name; instead the call site
  now checks for a missing identifier if necessary.

- `maybe_inline_local` doesn't need the `glob` argument, it can be
  computed in-function from the `renamed` argument.

- `arbitrary_source_item_ordering::check_mod` had a big `if` statement
  that was just getting the ident from the item kinds that had one. It
  could be mostly replaced by a single call to the new `ItemKind::ident`
  method.

- `ItemKind` grows from 56 to 64 bytes, but `Item` stays the same size,
  and that's what matters, because `ItemKind` only occurs within `Item`.
This commit is contained in:
Nicholas Nethercote 2025-03-06 19:07:36 +11:00
parent 6698c26b3a
commit f2ddbcd24b
82 changed files with 666 additions and 555 deletions

View file

@ -164,7 +164,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
fn visit_item(&mut self, i: &'hir Item<'hir>) { fn visit_item(&mut self, i: &'hir Item<'hir>) {
debug_assert_eq!(i.owner_id, self.owner); debug_assert_eq!(i.owner_id, self.owner);
self.with_parent(i.hir_id(), |this| { self.with_parent(i.hir_id(), |this| {
if let ItemKind::Struct(struct_def, _) = &i.kind { if let ItemKind::Struct(_, struct_def, _) = &i.kind {
// If this is a tuple or unit-like struct, register the constructor. // If this is a tuple or unit-like struct, register the constructor.
if let Some(ctor_hir_id) = struct_def.ctor_hir_id() { if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
this.insert(i.span, ctor_hir_id, Node::Ctor(struct_def)); this.insert(i.span, ctor_hir_id, Node::Ctor(struct_def));

View file

@ -111,6 +111,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
} }
fn lower_foreign_item(&mut self, item: &ForeignItem) { fn lower_foreign_item(&mut self, item: &ForeignItem) {
debug_assert_ne!(item.ident.name, kw::Empty);
self.with_lctx(item.id, |lctx| hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item))) self.with_lctx(item.id, |lctx| hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item)))
} }
} }
@ -154,14 +155,12 @@ 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 vis_span = self.lower_span(i.vis.span); let vis_span = self.lower_span(i.vis.span);
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span); let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, vis_span, &i.kind); let kind = self.lower_item_kind(i.span, i.id, hir_id, i.ident, attrs, vis_span, &i.kind);
let item = hir::Item { let item = hir::Item {
owner_id: hir_id.expect_owner(), owner_id: hir_id.expect_owner(),
ident: self.lower_ident(ident),
kind, kind,
vis_span, vis_span,
span: self.lower_span(i.span), span: self.lower_span(i.span),
@ -174,25 +173,34 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: Span, span: Span,
id: NodeId, id: NodeId,
hir_id: hir::HirId, hir_id: hir::HirId,
ident: &mut Ident, ident: Ident,
attrs: &'hir [hir::Attribute], attrs: &'hir [hir::Attribute],
vis_span: Span, vis_span: Span,
i: &ItemKind, i: &ItemKind,
) -> hir::ItemKind<'hir> { ) -> hir::ItemKind<'hir> {
match i { match i {
ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(*orig_name), ItemKind::ExternCrate(orig_name) => {
debug_assert_ne!(ident.name, kw::Empty);
let ident = self.lower_ident(ident);
hir::ItemKind::ExternCrate(*orig_name, ident)
}
ItemKind::Use(use_tree) => { ItemKind::Use(use_tree) => {
debug_assert_eq!(ident.name, kw::Empty);
// Start with an empty prefix. // Start with an empty prefix.
let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None }; let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None };
self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs) self.lower_use_tree(use_tree, &prefix, id, vis_span, attrs)
} }
ItemKind::Static(box ast::StaticItem { ty: t, safety: _, mutability: m, expr: e }) => { ItemKind::Static(box ast::StaticItem { ty: t, safety: _, mutability: m, expr: e }) => {
debug_assert_ne!(ident.name, kw::Empty);
let ident = self.lower_ident(ident);
let (ty, body_id) = let (ty, body_id) =
self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy); self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy);
hir::ItemKind::Static(ty, *m, body_id) hir::ItemKind::Static(ident, ty, *m, body_id)
} }
ItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => { ItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
debug_assert_ne!(ident.name, kw::Empty);
let ident = self.lower_ident(ident);
let (generics, (ty, body_id)) = self.lower_generics( let (generics, (ty, body_id)) = self.lower_generics(
generics, generics,
id, id,
@ -201,7 +209,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy) this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy)
}, },
); );
hir::ItemKind::Const(ty, generics, body_id) hir::ItemKind::Const(ident, ty, generics, body_id)
} }
ItemKind::Fn(box Fn { ItemKind::Fn(box Fn {
sig: FnSig { decl, header, span: fn_sig_span }, sig: FnSig { decl, header, span: fn_sig_span },
@ -211,6 +219,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
define_opaque, define_opaque,
.. ..
}) => { }) => {
debug_assert_ne!(ident.name, kw::Empty);
self.with_new_scopes(*fn_sig_span, |this| { self.with_new_scopes(*fn_sig_span, |this| {
// Note: we don't need to change the return type from `T` to // Note: we don't need to change the return type from `T` to
// `impl Future<Output = T>` here because lower_body // `impl Future<Output = T>` here because lower_body
@ -238,28 +247,44 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: this.lower_span(*fn_sig_span), span: this.lower_span(*fn_sig_span),
}; };
this.lower_define_opaque(hir_id, &define_opaque); this.lower_define_opaque(hir_id, &define_opaque);
hir::ItemKind::Fn { sig, generics, body: body_id, has_body: body.is_some() } let ident = this.lower_ident(ident);
hir::ItemKind::Fn {
ident,
sig,
generics,
body: body_id,
has_body: body.is_some(),
}
}) })
} }
ItemKind::Mod(_, mod_kind) => match mod_kind { ItemKind::Mod(_, mod_kind) => {
debug_assert_ne!(ident.name, kw::Empty);
let ident = self.lower_ident(ident);
match mod_kind {
ModKind::Loaded(items, _, spans, _) => { ModKind::Loaded(items, _, spans, _) => {
hir::ItemKind::Mod(self.lower_mod(items, spans)) hir::ItemKind::Mod(ident, self.lower_mod(items, spans))
} }
ModKind::Unloaded => panic!("`mod` items should have been loaded by now"), ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
}, }
ItemKind::ForeignMod(fm) => hir::ItemKind::ForeignMod { }
ItemKind::ForeignMod(fm) => {
debug_assert_eq!(ident.name, kw::Empty);
hir::ItemKind::ForeignMod {
abi: fm.abi.map_or(ExternAbi::FALLBACK, |abi| self.lower_abi(abi)), abi: fm.abi.map_or(ExternAbi::FALLBACK, |abi| self.lower_abi(abi)),
items: self items: self
.arena .arena
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))), .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
}, }
}
ItemKind::GlobalAsm(asm) => { ItemKind::GlobalAsm(asm) => {
debug_assert_eq!(ident.name, kw::Empty);
let asm = self.lower_inline_asm(span, asm); let asm = self.lower_inline_asm(span, asm);
let fake_body = let fake_body =
self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm)))); self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm))));
hir::ItemKind::GlobalAsm { asm, fake_body } hir::ItemKind::GlobalAsm { asm, fake_body }
} }
ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => { ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => {
debug_assert_ne!(ident.name, kw::Empty);
// We lower // We lower
// //
// type Foo = impl Trait // type Foo = impl Trait
@ -268,6 +293,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// //
// type Foo = Foo1 // type Foo = Foo1
// opaque type Foo1: Trait // opaque type Foo1: Trait
let ident = self.lower_ident(ident);
let mut generics = generics.clone(); let mut generics = generics.clone();
add_ty_alias_where_clause(&mut generics, *where_clauses, true); add_ty_alias_where_clause(&mut generics, *where_clauses, true);
let (generics, ty) = self.lower_generics( let (generics, ty) = self.lower_generics(
@ -293,9 +319,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
), ),
}, },
); );
hir::ItemKind::TyAlias(ty, generics) hir::ItemKind::TyAlias(ident, ty, generics)
} }
ItemKind::Enum(enum_definition, generics) => { ItemKind::Enum(enum_definition, generics) => {
debug_assert_ne!(ident.name, kw::Empty);
let ident = self.lower_ident(ident);
let (generics, variants) = self.lower_generics( let (generics, variants) = self.lower_generics(
generics, generics,
id, id,
@ -306,25 +334,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
) )
}, },
); );
hir::ItemKind::Enum(hir::EnumDef { variants }, generics) hir::ItemKind::Enum(ident, hir::EnumDef { variants }, generics)
} }
ItemKind::Struct(struct_def, generics) => { ItemKind::Struct(struct_def, generics) => {
debug_assert_ne!(ident.name, kw::Empty);
let ident = self.lower_ident(ident);
let (generics, struct_def) = self.lower_generics( let (generics, struct_def) = self.lower_generics(
generics, generics,
id, id,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic), ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| this.lower_variant_data(hir_id, struct_def), |this| this.lower_variant_data(hir_id, struct_def),
); );
hir::ItemKind::Struct(struct_def, generics) hir::ItemKind::Struct(ident, struct_def, generics)
} }
ItemKind::Union(vdata, generics) => { ItemKind::Union(vdata, generics) => {
debug_assert_ne!(ident.name, kw::Empty);
let ident = self.lower_ident(ident);
let (generics, vdata) = self.lower_generics( let (generics, vdata) = self.lower_generics(
generics, generics,
id, id,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic), ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| this.lower_variant_data(hir_id, vdata), |this| this.lower_variant_data(hir_id, vdata),
); );
hir::ItemKind::Union(vdata, generics) hir::ItemKind::Union(ident, vdata, generics)
} }
ItemKind::Impl(box Impl { ItemKind::Impl(box Impl {
safety, safety,
@ -336,6 +368,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self_ty: ty, self_ty: ty,
items: impl_items, items: impl_items,
}) => { }) => {
debug_assert_eq!(ident.name, kw::Empty);
// Lower the "impl header" first. This ordering is important // Lower the "impl header" first. This ordering is important
// for in-band lifetimes! Consider `'a` here: // for in-band lifetimes! Consider `'a` here:
// //
@ -401,6 +434,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
})) }))
} }
ItemKind::Trait(box Trait { is_auto, safety, generics, bounds, items }) => { ItemKind::Trait(box Trait { is_auto, safety, generics, bounds, items }) => {
debug_assert_ne!(ident.name, kw::Empty);
let ident = self.lower_ident(ident);
let (generics, (safety, items, bounds)) = self.lower_generics( let (generics, (safety, items, bounds)) = self.lower_generics(
generics, generics,
id, id,
@ -417,9 +452,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
(safety, items, bounds) (safety, items, bounds)
}, },
); );
hir::ItemKind::Trait(*is_auto, safety, generics, bounds, items) hir::ItemKind::Trait(*is_auto, safety, ident, generics, bounds, items)
} }
ItemKind::TraitAlias(generics, bounds) => { ItemKind::TraitAlias(generics, bounds) => {
debug_assert_ne!(ident.name, kw::Empty);
let ident = self.lower_ident(ident);
let (generics, bounds) = self.lower_generics( let (generics, bounds) = self.lower_generics(
generics, generics,
id, id,
@ -431,9 +468,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
) )
}, },
); );
hir::ItemKind::TraitAlias(generics, bounds) hir::ItemKind::TraitAlias(ident, generics, bounds)
} }
ItemKind::MacroDef(MacroDef { body, macro_rules }) => { ItemKind::MacroDef(MacroDef { body, macro_rules }) => {
debug_assert_ne!(ident.name, kw::Empty);
let ident = self.lower_ident(ident);
let body = P(self.lower_delim_args(body)); let body = P(self.lower_delim_args(body));
let def_id = self.local_def_id(id); let def_id = self.local_def_id(id);
let def_kind = self.tcx.def_kind(def_id); let def_kind = self.tcx.def_kind(def_id);
@ -444,11 +483,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
); );
}; };
let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules }); let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules });
hir::ItemKind::Macro(macro_def, macro_kind) hir::ItemKind::Macro(ident, macro_def, macro_kind)
} }
ItemKind::Delegation(box delegation) => { ItemKind::Delegation(box delegation) => {
debug_assert_ne!(ident.name, kw::Empty);
let ident = self.lower_ident(ident);
let delegation_results = self.lower_delegation(delegation, id); let delegation_results = self.lower_delegation(delegation, id);
hir::ItemKind::Fn { hir::ItemKind::Fn {
ident,
sig: delegation_results.sig, sig: delegation_results.sig,
generics: delegation_results.generics, generics: delegation_results.generics,
body: delegation_results.body_id, body: delegation_results.body_id,
@ -479,7 +521,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
prefix: &Path, prefix: &Path,
id: NodeId, id: NodeId,
vis_span: Span, vis_span: Span,
ident: &mut Ident,
attrs: &'hir [hir::Attribute], attrs: &'hir [hir::Attribute],
) -> hir::ItemKind<'hir> { ) -> hir::ItemKind<'hir> {
let path = &tree.prefix; let path = &tree.prefix;
@ -487,7 +528,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
match tree.kind { match tree.kind {
UseTreeKind::Simple(rename) => { UseTreeKind::Simple(rename) => {
*ident = tree.ident(); let mut ident = tree.ident();
// First, apply the prefix to the path. // First, apply the prefix to the path.
let mut path = Path { segments, span: path.span, tokens: None }; let mut path = Path { segments, span: path.span, tokens: None };
@ -498,13 +539,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
{ {
let _ = path.segments.pop(); let _ = path.segments.pop();
if rename.is_none() { if rename.is_none() {
*ident = path.segments.last().unwrap().ident; ident = path.segments.last().unwrap().ident;
} }
} }
let res = self.lower_import_res(id, path.span); let res = self.lower_import_res(id, path.span);
let path = self.lower_use_path(res, &path, ParamMode::Explicit); let path = self.lower_use_path(res, &path, ParamMode::Explicit);
hir::ItemKind::Use(path, hir::UseKind::Single) let ident = self.lower_ident(ident);
hir::ItemKind::Use(path, hir::UseKind::Single(ident))
} }
UseTreeKind::Glob => { UseTreeKind::Glob => {
let res = self.expect_full_res(id); let res = self.expect_full_res(id);
@ -551,20 +593,16 @@ 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 ident = *ident;
// `prefix` is lowered multiple times, but in different HIR owners. // `prefix` is lowered multiple times, but in different HIR owners.
// So each segment gets renewed `HirId` with the same // So each segment gets renewed `HirId` with the same
// `ItemLocalId` and the new owner. (See `lower_node_id`) // `ItemLocalId` and the new owner. (See `lower_node_id`)
let kind = let kind = this.lower_use_tree(use_tree, &prefix, id, vis_span, attrs);
this.lower_use_tree(use_tree, &prefix, id, vis_span, &mut ident, attrs);
if !attrs.is_empty() { if !attrs.is_empty() {
this.attrs.insert(hir::ItemLocalId::ZERO, attrs); this.attrs.insert(hir::ItemLocalId::ZERO, attrs);
} }
let item = hir::Item { let item = hir::Item {
owner_id: hir::OwnerId { def_id: new_hir_id }, owner_id: hir::OwnerId { def_id: new_hir_id },
ident: this.lower_ident(ident),
kind, kind,
vis_span, vis_span,
span: this.lower_span(use_tree.span), span: this.lower_span(use_tree.span),
@ -604,7 +642,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ItemKind::Impl(impl_) => { hir::ItemKind::Impl(impl_) => {
self.is_in_trait_impl = impl_.of_trait.is_some(); self.is_in_trait_impl = impl_.of_trait.is_some();
} }
hir::ItemKind::Trait(_, _, _, _, _) => {} hir::ItemKind::Trait(..) => {}
kind => { kind => {
span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr()) span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr())
} }
@ -760,6 +798,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> { fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
debug_assert_ne!(i.ident.name, kw::Empty);
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span); let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
let trait_item_def_id = hir_id.expect_owner(); let trait_item_def_id = hir_id.expect_owner();
@ -907,6 +946,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> { fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
debug_assert_ne!(i.ident.name, kw::Empty);
// Since `default impl` is not yet implemented, this is always true in impls. // Since `default impl` is not yet implemented, this is always true in impls.
let has_value = true; let has_value = true;
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value); let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);

View file

@ -691,7 +691,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
true, true,
td.is_local(), td.is_local(),
td.as_local().and_then(|tld| match self.infcx.tcx.hir_node_by_def_id(tld) { td.as_local().and_then(|tld| match self.infcx.tcx.hir_node_by_def_id(tld) {
Node::Item(hir::Item { kind: hir::ItemKind::Trait(_, _, _, _, items), .. }) => { Node::Item(hir::Item {
kind: hir::ItemKind::Trait(_, _, _, _, _, items), ..
}) => {
let mut f_in_trait_opt = None; let mut f_in_trait_opt = None;
for hir::TraitItemRef { id: fi, kind: k, .. } in *items { for hir::TraitItemRef { id: fi, kind: k, .. } in *items {
let hi = fi.hir_id(); let hi = fi.hir_id();
@ -980,7 +982,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let arg = match tcx.hir_get_if_local(callee_def_id) { let arg = match tcx.hir_get_if_local(callee_def_id) {
Some( Some(
hir::Node::Item(hir::Item { hir::Node::Item(hir::Item {
ident, kind: hir::ItemKind::Fn { sig, .. }, .. kind: hir::ItemKind::Fn { ident, sig, .. }, ..
}) })
| hir::Node::TraitItem(hir::TraitItem { | hir::Node::TraitItem(hir::TraitItem {
ident, ident,
@ -1021,7 +1023,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
// return type. // return type.
match tcx.hir_node_by_def_id(tcx.hir_get_parent_item(fn_call_id).def_id) { match tcx.hir_node_by_def_id(tcx.hir_get_parent_item(fn_call_id).def_id) {
hir::Node::Item(hir::Item { hir::Node::Item(hir::Item {
ident, kind: hir::ItemKind::Fn { sig, .. }, .. kind: hir::ItemKind::Fn { ident, sig, .. }, ..
}) })
| hir::Node::TraitItem(hir::TraitItem { | hir::Node::TraitItem(hir::TraitItem {
ident, ident,

View file

@ -3755,7 +3755,10 @@ pub enum UseKind {
/// One import, e.g., `use foo::bar` or `use foo::bar as baz`. /// One import, e.g., `use foo::bar` or `use foo::bar as baz`.
/// Also produced for each element of a list `use`, e.g. /// Also produced for each element of a list `use`, e.g.
/// `use foo::{a, b}` lowers to `use foo::a; use foo::b;`. /// `use foo::{a, b}` lowers to `use foo::a; use foo::b;`.
Single, ///
/// The identifier is the name defined by the import. E.g. for `use
/// foo::bar` it is `bar`, for `use foo::bar as baz` it is `baz`.
Single(Ident),
/// Glob import, e.g., `use foo::*`. /// Glob import, e.g., `use foo::*`.
Glob, Glob,
@ -3897,8 +3900,6 @@ impl ItemId {
/// An item /// An item
/// ///
/// The name might be a dummy name in case of anonymous items
///
/// For more details, see the [rust lang reference]. /// For more details, see the [rust lang reference].
/// Note that the reference does not document nightly-only features. /// Note that the reference does not document nightly-only features.
/// There may be also slight differences in the names and representation of AST nodes between /// There may be also slight differences in the names and representation of AST nodes between
@ -3907,7 +3908,6 @@ impl ItemId {
/// [rust lang reference]: https://doc.rust-lang.org/reference/items.html /// [rust lang reference]: https://doc.rust-lang.org/reference/items.html
#[derive(Debug, Clone, Copy, HashStable_Generic)] #[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Item<'hir> { pub struct Item<'hir> {
pub ident: Ident,
pub owner_id: OwnerId, pub owner_id: OwnerId,
pub kind: ItemKind<'hir>, pub kind: ItemKind<'hir>,
pub span: Span, pub span: Span,
@ -3937,46 +3937,56 @@ impl<'hir> Item<'hir> {
} }
expect_methods_self_kind! { expect_methods_self_kind! {
expect_extern_crate, Option<Symbol>, ItemKind::ExternCrate(s), *s; expect_extern_crate, (Option<Symbol>, Ident),
ItemKind::ExternCrate(s, ident), (*s, *ident);
expect_use, (&'hir UsePath<'hir>, UseKind), ItemKind::Use(p, uk), (p, *uk); expect_use, (&'hir UsePath<'hir>, UseKind), ItemKind::Use(p, uk), (p, *uk);
expect_static, (&'hir Ty<'hir>, Mutability, BodyId), expect_static, (Ident, &'hir Ty<'hir>, Mutability, BodyId),
ItemKind::Static(ty, mutbl, body), (ty, *mutbl, *body); ItemKind::Static(ident, ty, mutbl, body), (*ident, ty, *mutbl, *body);
expect_const, (&'hir Ty<'hir>, &'hir Generics<'hir>, BodyId), expect_const, (Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
ItemKind::Const(ty, generics, body), (ty, generics, *body); ItemKind::Const(ident, ty, generics, body), (*ident, ty, generics, *body);
expect_fn, (&FnSig<'hir>, &'hir Generics<'hir>, BodyId), expect_fn, (Ident, &FnSig<'hir>, &'hir Generics<'hir>, BodyId),
ItemKind::Fn { sig, generics, body, .. }, (sig, generics, *body); ItemKind::Fn { ident, sig, generics, body, .. }, (*ident, sig, generics, *body);
expect_macro, (&ast::MacroDef, MacroKind), ItemKind::Macro(def, mk), (def, *mk); expect_macro, (Ident, &ast::MacroDef, MacroKind),
ItemKind::Macro(ident, def, mk), (*ident, def, *mk);
expect_mod, &'hir Mod<'hir>, ItemKind::Mod(m), m; expect_mod, (Ident, &'hir Mod<'hir>), ItemKind::Mod(ident, m), (*ident, m);
expect_foreign_mod, (ExternAbi, &'hir [ForeignItemRef]), expect_foreign_mod, (ExternAbi, &'hir [ForeignItemRef]),
ItemKind::ForeignMod { abi, items }, (*abi, items); ItemKind::ForeignMod { abi, items }, (*abi, items);
expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm; expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm;
expect_ty_alias, (&'hir Ty<'hir>, &'hir Generics<'hir>), expect_ty_alias, (Ident, &'hir Ty<'hir>, &'hir Generics<'hir>),
ItemKind::TyAlias(ty, generics), (ty, generics); ItemKind::TyAlias(ident, ty, generics), (*ident, ty, generics);
expect_enum, (&EnumDef<'hir>, &'hir Generics<'hir>), ItemKind::Enum(def, generics), (def, generics); expect_enum, (Ident, &EnumDef<'hir>, &'hir Generics<'hir>),
ItemKind::Enum(ident, def, generics), (*ident, def, generics);
expect_struct, (&VariantData<'hir>, &'hir Generics<'hir>), expect_struct, (Ident, &VariantData<'hir>, &'hir Generics<'hir>),
ItemKind::Struct(data, generics), (data, generics); ItemKind::Struct(ident, data, generics), (*ident, data, generics);
expect_union, (&VariantData<'hir>, &'hir Generics<'hir>), expect_union, (Ident, &VariantData<'hir>, &'hir Generics<'hir>),
ItemKind::Union(data, generics), (data, generics); ItemKind::Union(ident, data, generics), (*ident, data, generics);
expect_trait, expect_trait,
(IsAuto, Safety, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]), (
ItemKind::Trait(is_auto, safety, generics, bounds, items), IsAuto,
(*is_auto, *safety, generics, bounds, items); Safety,
Ident,
&'hir Generics<'hir>,
GenericBounds<'hir>,
&'hir [TraitItemRef]
),
ItemKind::Trait(is_auto, safety, ident, generics, bounds, items),
(*is_auto, *safety, *ident, generics, bounds, items);
expect_trait_alias, (&'hir Generics<'hir>, GenericBounds<'hir>), expect_trait_alias, (Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
ItemKind::TraitAlias(generics, bounds), (generics, bounds); ItemKind::TraitAlias(ident, generics, bounds), (*ident, generics, bounds);
expect_impl, &'hir Impl<'hir>, ItemKind::Impl(imp), imp; expect_impl, &'hir Impl<'hir>, ItemKind::Impl(imp), imp;
} }
@ -4094,7 +4104,7 @@ pub enum ItemKind<'hir> {
/// An `extern crate` item, with optional *original* crate name if the crate was renamed. /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
/// ///
/// E.g., `extern crate foo` or `extern crate foo_bar as foo`. /// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
ExternCrate(Option<Symbol>), ExternCrate(Option<Symbol>, Ident),
/// `use foo::bar::*;` or `use foo::bar::baz as quux;` /// `use foo::bar::*;` or `use foo::bar::baz as quux;`
/// ///
@ -4104,11 +4114,12 @@ pub enum ItemKind<'hir> {
Use(&'hir UsePath<'hir>, UseKind), Use(&'hir UsePath<'hir>, UseKind),
/// A `static` item. /// A `static` item.
Static(&'hir Ty<'hir>, Mutability, BodyId), Static(Ident, &'hir Ty<'hir>, Mutability, BodyId),
/// A `const` item. /// A `const` item.
Const(&'hir Ty<'hir>, &'hir Generics<'hir>, BodyId), Const(Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
/// A function declaration. /// A function declaration.
Fn { Fn {
ident: Ident,
sig: FnSig<'hir>, sig: FnSig<'hir>,
generics: &'hir Generics<'hir>, generics: &'hir Generics<'hir>,
body: BodyId, body: BodyId,
@ -4118,9 +4129,9 @@ pub enum ItemKind<'hir> {
has_body: bool, has_body: bool,
}, },
/// A MBE macro definition (`macro_rules!` or `macro`). /// A MBE macro definition (`macro_rules!` or `macro`).
Macro(&'hir ast::MacroDef, MacroKind), Macro(Ident, &'hir ast::MacroDef, MacroKind),
/// A module. /// A module.
Mod(&'hir Mod<'hir>), Mod(Ident, &'hir Mod<'hir>),
/// An external module, e.g. `extern { .. }`. /// An external module, e.g. `extern { .. }`.
ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemRef] }, ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemRef] },
/// Module-level inline assembly (from `global_asm!`). /// Module-level inline assembly (from `global_asm!`).
@ -4134,17 +4145,17 @@ pub enum ItemKind<'hir> {
fake_body: BodyId, fake_body: BodyId,
}, },
/// A type alias, e.g., `type Foo = Bar<u8>`. /// A type alias, e.g., `type Foo = Bar<u8>`.
TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>), TyAlias(Ident, &'hir Ty<'hir>, &'hir Generics<'hir>),
/// An enum definition, e.g., `enum Foo<A, B> { C<A>, D<B> }`. /// An enum definition, e.g., `enum Foo<A, B> { C<A>, D<B> }`.
Enum(EnumDef<'hir>, &'hir Generics<'hir>), Enum(Ident, EnumDef<'hir>, &'hir Generics<'hir>),
/// A struct definition, e.g., `struct Foo<A> {x: A}`. /// A struct definition, e.g., `struct Foo<A> {x: A}`.
Struct(VariantData<'hir>, &'hir Generics<'hir>), Struct(Ident, VariantData<'hir>, &'hir Generics<'hir>),
/// A union definition, e.g., `union Foo<A, B> {x: A, y: B}`. /// A union definition, e.g., `union Foo<A, B> {x: A, y: B}`.
Union(VariantData<'hir>, &'hir Generics<'hir>), Union(Ident, VariantData<'hir>, &'hir Generics<'hir>),
/// A trait definition. /// A trait definition.
Trait(IsAuto, Safety, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]), Trait(IsAuto, Safety, Ident, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]),
/// A trait alias. /// A trait alias.
TraitAlias(&'hir Generics<'hir>, GenericBounds<'hir>), TraitAlias(Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
/// An implementation, e.g., `impl<A> Trait for Foo { .. }`. /// An implementation, e.g., `impl<A> Trait for Foo { .. }`.
Impl(&'hir Impl<'hir>), Impl(&'hir Impl<'hir>),
@ -4173,16 +4184,39 @@ pub struct Impl<'hir> {
} }
impl ItemKind<'_> { impl ItemKind<'_> {
pub fn ident(&self) -> Option<Ident> {
match *self {
ItemKind::ExternCrate(_, ident)
| ItemKind::Use(_, UseKind::Single(ident))
| ItemKind::Static(ident, ..)
| ItemKind::Const(ident, ..)
| ItemKind::Fn { ident, .. }
| ItemKind::Macro(ident, ..)
| ItemKind::Mod(ident, ..)
| ItemKind::TyAlias(ident, ..)
| ItemKind::Enum(ident, ..)
| ItemKind::Struct(ident, ..)
| ItemKind::Union(ident, ..)
| ItemKind::Trait(_, _, ident, ..)
| ItemKind::TraitAlias(ident, ..) => Some(ident),
ItemKind::Use(_, UseKind::Glob | UseKind::ListStem)
| ItemKind::ForeignMod { .. }
| ItemKind::GlobalAsm { .. }
| ItemKind::Impl(_) => None,
}
}
pub fn generics(&self) -> Option<&Generics<'_>> { pub fn generics(&self) -> Option<&Generics<'_>> {
Some(match self { Some(match self {
ItemKind::Fn { generics, .. } ItemKind::Fn { generics, .. }
| ItemKind::TyAlias(_, generics) | ItemKind::TyAlias(_, _, generics)
| ItemKind::Const(_, generics, _) | ItemKind::Const(_, _, generics, _)
| ItemKind::Enum(_, generics) | ItemKind::Enum(_, _, generics)
| ItemKind::Struct(_, generics) | ItemKind::Struct(_, _, generics)
| ItemKind::Union(_, generics) | ItemKind::Union(_, _, generics)
| ItemKind::Trait(_, _, generics, _, _) | ItemKind::Trait(_, _, _, generics, _, _)
| ItemKind::TraitAlias(generics, _) | ItemKind::TraitAlias(_, generics, _)
| ItemKind::Impl(Impl { generics, .. }) => generics, | ItemKind::Impl(Impl { generics, .. }) => generics,
_ => return None, _ => return None,
}) })
@ -4374,8 +4408,8 @@ impl<'hir> OwnerNode<'hir> {
match self { match self {
OwnerNode::Item(Item { OwnerNode::Item(Item {
kind: kind:
ItemKind::Static(_, _, body) ItemKind::Static(_, _, _, body)
| ItemKind::Const(_, _, body) | ItemKind::Const(_, _, _, body)
| ItemKind::Fn { body, .. }, | ItemKind::Fn { body, .. },
.. ..
}) })
@ -4518,12 +4552,12 @@ impl<'hir> Node<'hir> {
/// ``` /// ```
pub fn ident(&self) -> Option<Ident> { pub fn ident(&self) -> Option<Ident> {
match self { match self {
Node::Item(item) => item.kind.ident(),
Node::TraitItem(TraitItem { ident, .. }) Node::TraitItem(TraitItem { ident, .. })
| Node::ImplItem(ImplItem { ident, .. }) | Node::ImplItem(ImplItem { ident, .. })
| Node::ForeignItem(ForeignItem { ident, .. }) | Node::ForeignItem(ForeignItem { ident, .. })
| Node::Field(FieldDef { ident, .. }) | Node::Field(FieldDef { ident, .. })
| Node::Variant(Variant { ident, .. }) | Node::Variant(Variant { ident, .. })
| Node::Item(Item { ident, .. })
| Node::PathSegment(PathSegment { ident, .. }) => Some(*ident), | Node::PathSegment(PathSegment { ident, .. }) => Some(*ident),
Node::Lifetime(lt) => Some(lt.ident), Node::Lifetime(lt) => Some(lt.ident),
Node::GenericParam(p) => Some(p.name.ident()), Node::GenericParam(p) => Some(p.name.ident()),
@ -4599,9 +4633,9 @@ impl<'hir> Node<'hir> {
pub fn ty(self) -> Option<&'hir Ty<'hir>> { pub fn ty(self) -> Option<&'hir Ty<'hir>> {
match self { match self {
Node::Item(it) => match it.kind { Node::Item(it) => match it.kind {
ItemKind::TyAlias(ty, _) ItemKind::TyAlias(_, ty, _)
| ItemKind::Static(ty, _, _) | ItemKind::Static(_, ty, _, _)
| ItemKind::Const(ty, _, _) => Some(ty), | ItemKind::Const(_, ty, _, _) => Some(ty),
ItemKind::Impl(impl_item) => Some(&impl_item.self_ty), ItemKind::Impl(impl_item) => Some(&impl_item.self_ty),
_ => None, _ => None,
}, },
@ -4621,7 +4655,7 @@ impl<'hir> Node<'hir> {
pub fn alias_ty(self) -> Option<&'hir Ty<'hir>> { pub fn alias_ty(self) -> Option<&'hir Ty<'hir>> {
match self { match self {
Node::Item(Item { kind: ItemKind::TyAlias(ty, ..), .. }) => Some(ty), Node::Item(Item { kind: ItemKind::TyAlias(_, ty, _), .. }) => Some(ty),
_ => None, _ => None,
} }
} }
@ -4632,7 +4666,9 @@ impl<'hir> Node<'hir> {
Node::Item(Item { Node::Item(Item {
owner_id, owner_id,
kind: kind:
ItemKind::Const(_, _, body) | ItemKind::Static(.., body) | ItemKind::Fn { body, .. }, ItemKind::Const(_, _, _, body)
| ItemKind::Static(.., body)
| ItemKind::Fn { body, .. },
.. ..
}) })
| Node::TraitItem(TraitItem { | Node::TraitItem(TraitItem {
@ -4693,8 +4729,8 @@ impl<'hir> Node<'hir> {
pub fn fn_kind(self) -> Option<FnKind<'hir>> { pub fn fn_kind(self) -> Option<FnKind<'hir>> {
match self { match self {
Node::Item(i) => match i.kind { Node::Item(i) => match i.kind {
ItemKind::Fn { sig, generics, .. } => { ItemKind::Fn { ident, sig, generics, .. } => {
Some(FnKind::ItemFn(i.ident, generics, sig.header)) Some(FnKind::ItemFn(ident, generics, sig.header))
} }
_ => None, _ => None,
}, },
@ -4767,7 +4803,7 @@ mod size_asserts {
static_assert_size!(ImplItem<'_>, 88); static_assert_size!(ImplItem<'_>, 88);
static_assert_size!(ImplItemKind<'_>, 40); static_assert_size!(ImplItemKind<'_>, 40);
static_assert_size!(Item<'_>, 88); static_assert_size!(Item<'_>, 88);
static_assert_size!(ItemKind<'_>, 56); static_assert_size!(ItemKind<'_>, 64);
static_assert_size!(LetStmt<'_>, 64); static_assert_size!(LetStmt<'_>, 64);
static_assert_size!(Param<'_>, 32); static_assert_size!(Param<'_>, 32);
static_assert_size!(Pat<'_>, 72); static_assert_size!(Pat<'_>, 72);

View file

@ -533,34 +533,44 @@ 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>) -> V::Result { pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::Result {
try_visit!(visitor.visit_id(item.hir_id())); try_visit!(visitor.visit_id(item.hir_id()));
try_visit!(visitor.visit_ident(item.ident));
match item.kind { match item.kind {
ItemKind::ExternCrate(orig_name) => { ItemKind::ExternCrate(orig_name, ident) => {
visit_opt!(visitor, visit_name, orig_name); visit_opt!(visitor, visit_name, orig_name);
try_visit!(visitor.visit_ident(ident));
} }
ItemKind::Use(ref path, _) => { ItemKind::Use(ref path, kind) => {
try_visit!(visitor.visit_use(path, item.hir_id())); try_visit!(visitor.visit_use(path, item.hir_id()));
match kind {
UseKind::Single(ident) => try_visit!(visitor.visit_ident(ident)),
UseKind::Glob | UseKind::ListStem => {}
} }
ItemKind::Static(ref typ, _, body) => { }
ItemKind::Static(ident, ref typ, _, body) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_ty_unambig(typ)); try_visit!(visitor.visit_ty_unambig(typ));
try_visit!(visitor.visit_nested_body(body)); try_visit!(visitor.visit_nested_body(body));
} }
ItemKind::Const(ref typ, ref generics, body) => { ItemKind::Const(ident, ref typ, ref generics, body) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_ty_unambig(typ)); try_visit!(visitor.visit_ty_unambig(typ));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_nested_body(body)); try_visit!(visitor.visit_nested_body(body));
} }
ItemKind::Fn { sig, generics, body: body_id, .. } => { ItemKind::Fn { ident, sig, generics, body: body_id, .. } => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_fn( try_visit!(visitor.visit_fn(
FnKind::ItemFn(item.ident, generics, sig.header), FnKind::ItemFn(ident, generics, sig.header),
sig.decl, sig.decl,
body_id, body_id,
item.span, item.span,
item.owner_id.def_id, item.owner_id.def_id,
)); ));
} }
ItemKind::Macro(..) => {} ItemKind::Macro(ident, _def, _kind) => {
ItemKind::Mod(ref module) => { try_visit!(visitor.visit_ident(ident));
}
ItemKind::Mod(ident, ref module) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_mod(module, item.span, item.hir_id())); try_visit!(visitor.visit_mod(module, item.span, item.hir_id()));
} }
ItemKind::ForeignMod { abi: _, items } => { ItemKind::ForeignMod { abi: _, items } => {
@ -573,11 +583,13 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
// typeck results set correctly. // typeck results set correctly.
try_visit!(visitor.visit_nested_body(fake_body)); try_visit!(visitor.visit_nested_body(fake_body));
} }
ItemKind::TyAlias(ref ty, ref generics) => { ItemKind::TyAlias(ident, ref ty, ref generics) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_ty_unambig(ty)); try_visit!(visitor.visit_ty_unambig(ty));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
} }
ItemKind::Enum(ref enum_definition, ref generics) => { ItemKind::Enum(ident, ref enum_definition, ref generics) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_enum_def(enum_definition)); try_visit!(visitor.visit_enum_def(enum_definition));
} }
@ -597,17 +609,20 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
try_visit!(visitor.visit_ty_unambig(self_ty)); try_visit!(visitor.visit_ty_unambig(self_ty));
walk_list!(visitor, visit_impl_item_ref, *items); walk_list!(visitor, visit_impl_item_ref, *items);
} }
ItemKind::Struct(ref struct_definition, ref generics) ItemKind::Struct(ident, ref struct_definition, ref generics)
| ItemKind::Union(ref struct_definition, ref generics) => { | ItemKind::Union(ident, ref struct_definition, ref generics) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_variant_data(struct_definition)); try_visit!(visitor.visit_variant_data(struct_definition));
} }
ItemKind::Trait(.., ref generics, bounds, trait_item_refs) => { ItemKind::Trait(_is_auto, _safety, ident, ref generics, bounds, trait_item_refs) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_trait_item_ref, trait_item_refs); walk_list!(visitor, visit_trait_item_ref, trait_item_refs);
} }
ItemKind::TraitAlias(ref generics, bounds) => { ItemKind::TraitAlias(ident, ref generics, bounds) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_param_bound, bounds);
} }

View file

@ -269,26 +269,26 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
} }
res res
} }
hir::ItemKind::Fn { sig, .. } => { hir::ItemKind::Fn { ident, sig, .. } => {
check_item_fn(tcx, def_id, item.ident, item.span, sig.decl) check_item_fn(tcx, def_id, ident, item.span, sig.decl)
} }
hir::ItemKind::Static(ty, ..) => { hir::ItemKind::Static(_, ty, ..) => {
check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid) check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid)
} }
hir::ItemKind::Const(ty, ..) => { hir::ItemKind::Const(_, ty, ..) => {
check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid) check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid)
} }
hir::ItemKind::Struct(_, hir_generics) => { hir::ItemKind::Struct(_, _, hir_generics) => {
let res = check_type_defn(tcx, item, false); let res = check_type_defn(tcx, item, false);
check_variances_for_type_defn(tcx, item, hir_generics); check_variances_for_type_defn(tcx, item, hir_generics);
res res
} }
hir::ItemKind::Union(_, hir_generics) => { hir::ItemKind::Union(_, _, hir_generics) => {
let res = check_type_defn(tcx, item, true); let res = check_type_defn(tcx, item, true);
check_variances_for_type_defn(tcx, item, hir_generics); check_variances_for_type_defn(tcx, item, hir_generics);
res res
} }
hir::ItemKind::Enum(_, hir_generics) => { hir::ItemKind::Enum(_, _, hir_generics) => {
let res = check_type_defn(tcx, item, true); let res = check_type_defn(tcx, item, true);
check_variances_for_type_defn(tcx, item, hir_generics); check_variances_for_type_defn(tcx, item, hir_generics);
res res
@ -297,7 +297,9 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
hir::ItemKind::TraitAlias(..) => check_trait(tcx, item), hir::ItemKind::TraitAlias(..) => check_trait(tcx, item),
// `ForeignItem`s are handled separately. // `ForeignItem`s are handled separately.
hir::ItemKind::ForeignMod { .. } => Ok(()), hir::ItemKind::ForeignMod { .. } => Ok(()),
hir::ItemKind::TyAlias(hir_ty, hir_generics) if tcx.type_alias_is_lazy(item.owner_id) => { hir::ItemKind::TyAlias(_, hir_ty, hir_generics)
if tcx.type_alias_is_lazy(item.owner_id) =>
{
let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| { let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| {
let ty = tcx.type_of(def_id).instantiate_identity(); let ty = tcx.type_of(def_id).instantiate_identity();
let item_ty = wfcx.normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty); let item_ty = wfcx.normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty);
@ -822,10 +824,10 @@ fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
/// ///
/// In such cases, suggest using `Self` instead. /// In such cases, suggest using `Self` instead.
fn check_dyn_incompatible_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) { fn check_dyn_incompatible_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) {
let (trait_name, trait_def_id) = let (trait_ident, trait_def_id) =
match tcx.hir_node_by_def_id(tcx.hir_get_parent_item(item.hir_id()).def_id) { match tcx.hir_node_by_def_id(tcx.hir_get_parent_item(item.hir_id()).def_id) {
hir::Node::Item(item) => match item.kind { hir::Node::Item(item) => match item.kind {
hir::ItemKind::Trait(..) => (item.ident, item.owner_id), hir::ItemKind::Trait(_, _, ident, ..) => (ident, item.owner_id),
_ => return, _ => return,
}, },
_ => return, _ => return,
@ -862,7 +864,7 @@ fn check_dyn_incompatible_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitI
trait_should_be_self, trait_should_be_self,
"associated item referring to unboxed trait object for its own trait", "associated item referring to unboxed trait object for its own trait",
) )
.with_span_label(trait_name.span, "in this trait") .with_span_label(trait_ident.span, "in this trait")
.with_multipart_suggestion( .with_multipart_suggestion(
"you might have meant to use `Self` to refer to the implementing type", "you might have meant to use `Self` to refer to the implementing type",
sugg, sugg,

View file

@ -247,13 +247,13 @@ fn reject_placeholder_type_signatures_in_item<'tcx>(
item: &'tcx hir::Item<'tcx>, item: &'tcx hir::Item<'tcx>,
) { ) {
let (generics, suggest) = match &item.kind { let (generics, suggest) = match &item.kind {
hir::ItemKind::Union(_, generics) hir::ItemKind::Union(_, _, generics)
| hir::ItemKind::Enum(_, generics) | hir::ItemKind::Enum(_, _, generics)
| hir::ItemKind::TraitAlias(generics, _) | hir::ItemKind::TraitAlias(_, generics, _)
| hir::ItemKind::Trait(_, _, generics, ..) | hir::ItemKind::Trait(_, _, _, generics, ..)
| hir::ItemKind::Impl(hir::Impl { generics, .. }) | hir::ItemKind::Impl(hir::Impl { generics, .. })
| hir::ItemKind::Struct(_, generics) => (generics, true), | hir::ItemKind::Struct(_, _, generics) => (generics, true),
hir::ItemKind::TyAlias(_, generics) => (generics, false), hir::ItemKind::TyAlias(_, _, generics) => (generics, false),
// `static`, `fn` and `const` are handled elsewhere to suggest appropriate type. // `static`, `fn` and `const` are handled elsewhere to suggest appropriate type.
_ => return, _ => return,
}; };
@ -470,9 +470,9 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
.tcx .tcx
.hir_expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id); .hir_expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id);
match &item.kind { match &item.kind {
hir::ItemKind::Enum(_, generics) hir::ItemKind::Enum(_, _, generics)
| hir::ItemKind::Struct(_, generics) | hir::ItemKind::Struct(_, _, generics)
| hir::ItemKind::Union(_, generics) => { | hir::ItemKind::Union(_, _, generics) => {
let lt_name = get_new_lifetime_name(self.tcx, poly_trait_ref, generics); let lt_name = get_new_lifetime_name(self.tcx, poly_trait_ref, generics);
let (lt_sp, sugg) = match generics.params { let (lt_sp, sugg) = match generics.params {
[] => (generics.span, format!("<{lt_name}>")), [] => (generics.span, format!("<{lt_name}>")),
@ -667,16 +667,16 @@ fn get_new_lifetime_name<'tcx>(
#[instrument(level = "debug", skip_all)] #[instrument(level = "debug", skip_all)]
fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
let it = tcx.hir_item(item_id); let it = tcx.hir_item(item_id);
debug!(item = %it.ident, id = %it.hir_id()); debug!(item = ?it.kind.ident(), id = %it.hir_id());
let def_id = item_id.owner_id.def_id; let def_id = item_id.owner_id.def_id;
let icx = ItemCtxt::new(tcx, def_id); let icx = ItemCtxt::new(tcx, def_id);
match &it.kind { match &it.kind {
// These don't define types. // These don't define types.
hir::ItemKind::ExternCrate(_) hir::ItemKind::ExternCrate(..)
| hir::ItemKind::Use(..) | hir::ItemKind::Use(..)
| hir::ItemKind::Macro(..) | hir::ItemKind::Macro(..)
| hir::ItemKind::Mod(_) | hir::ItemKind::Mod(..)
| hir::ItemKind::GlobalAsm { .. } => {} | hir::ItemKind::GlobalAsm { .. } => {}
hir::ItemKind::ForeignMod { items, .. } => { hir::ItemKind::ForeignMod { items, .. } => {
for item in *items { for item in *items {
@ -736,7 +736,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
tcx.at(it.span).explicit_super_predicates_of(def_id); tcx.at(it.span).explicit_super_predicates_of(def_id);
tcx.ensure_ok().predicates_of(def_id); tcx.ensure_ok().predicates_of(def_id);
} }
hir::ItemKind::Struct(struct_def, _) | hir::ItemKind::Union(struct_def, _) => { hir::ItemKind::Struct(_, struct_def, _) | hir::ItemKind::Union(_, struct_def, _) => {
tcx.ensure_ok().generics_of(def_id); tcx.ensure_ok().generics_of(def_id);
tcx.ensure_ok().type_of(def_id); tcx.ensure_ok().type_of(def_id);
tcx.ensure_ok().predicates_of(def_id); tcx.ensure_ok().predicates_of(def_id);
@ -758,7 +758,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
tcx.ensure_ok().predicates_of(def_id); tcx.ensure_ok().predicates_of(def_id);
} }
hir::ItemKind::Static(ty, ..) | hir::ItemKind::Const(ty, ..) => { hir::ItemKind::Static(_, ty, ..) | hir::ItemKind::Const(_, ty, ..) => {
tcx.ensure_ok().generics_of(def_id); tcx.ensure_ok().generics_of(def_id);
tcx.ensure_ok().type_of(def_id); tcx.ensure_ok().type_of(def_id);
tcx.ensure_ok().predicates_of(def_id); tcx.ensure_ok().predicates_of(def_id);
@ -1089,7 +1089,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
let repr = tcx.repr_options_of_def(def_id); let repr = tcx.repr_options_of_def(def_id);
let (kind, variants) = match &item.kind { let (kind, variants) = match &item.kind {
ItemKind::Enum(def, _) => { ItemKind::Enum(_, def, _) => {
let mut distance_from_explicit = 0; let mut distance_from_explicit = 0;
let variants = def let variants = def
.variants .variants
@ -1117,7 +1117,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
(AdtKind::Enum, variants) (AdtKind::Enum, variants)
} }
ItemKind::Struct(def, _) | ItemKind::Union(def, _) => { ItemKind::Struct(ident, def, _) | ItemKind::Union(ident, def, _) => {
let adt_kind = match item.kind { let adt_kind = match item.kind {
ItemKind::Struct(..) => AdtKind::Struct, ItemKind::Struct(..) => AdtKind::Struct,
_ => AdtKind::Union, _ => AdtKind::Union,
@ -1125,7 +1125,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
let variants = std::iter::once(lower_variant( let variants = std::iter::once(lower_variant(
tcx, tcx,
None, None,
item.ident, *ident,
ty::VariantDiscr::Relative(0), ty::VariantDiscr::Relative(0),
def, def,
adt_kind, adt_kind,

View file

@ -134,7 +134,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
}; };
tcx.vtable_entries(trait_ref) tcx.vtable_entries(trait_ref)
} }
hir::ItemKind::TyAlias(_, _) => { hir::ItemKind::TyAlias(..) => {
let ty = tcx.type_of(def_id).instantiate_identity(); let ty = tcx.type_of(def_id).instantiate_identity();
if ty.has_non_region_param() { if ty.has_non_region_param() {
tcx.dcx().span_err( tcx.dcx().span_err(

View file

@ -163,7 +163,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
} }
} }
ItemKind::Trait(_, _, _, self_bounds, ..) | ItemKind::TraitAlias(_, self_bounds) => { ItemKind::Trait(_, _, _, _, self_bounds, ..)
| ItemKind::TraitAlias(_, _, self_bounds) => {
is_trait = Some(self_bounds); is_trait = Some(self_bounds);
} }
_ => {} _ => {}
@ -615,7 +616,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
let (generics, superbounds) = match item.kind { let (generics, superbounds) = match item.kind {
hir::ItemKind::Trait(.., generics, supertraits, _) => (generics, supertraits), hir::ItemKind::Trait(.., generics, supertraits, _) => (generics, supertraits),
hir::ItemKind::TraitAlias(generics, supertraits) => (generics, supertraits), hir::ItemKind::TraitAlias(_, generics, supertraits) => (generics, supertraits),
_ => span_bug!(item.span, "super_predicates invoked on non-trait"), _ => span_bug!(item.span, "super_predicates invoked on non-trait"),
}; };
@ -959,7 +960,7 @@ pub(super) fn const_conditions<'tcx>(
Node::Item(item) => match item.kind { Node::Item(item) => match item.kind {
hir::ItemKind::Impl(impl_) => (impl_.generics, None, false), hir::ItemKind::Impl(impl_) => (impl_.generics, None, false),
hir::ItemKind::Fn { generics, .. } => (generics, None, false), hir::ItemKind::Fn { generics, .. } => (generics, None, false),
hir::ItemKind::Trait(_, _, generics, supertraits, _) => { hir::ItemKind::Trait(_, _, _, generics, supertraits, _) => {
(generics, Some((item.owner_id.def_id, supertraits)), false) (generics, Some((item.owner_id.def_id, supertraits)), false)
} }
_ => bug!("const_conditions called on wrong item: {def_id:?}"), _ => bug!("const_conditions called on wrong item: {def_id:?}"),

View file

@ -617,7 +617,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
}); });
} }
hir::ItemKind::ExternCrate(_) hir::ItemKind::ExternCrate(..)
| hir::ItemKind::Use(..) | hir::ItemKind::Use(..)
| hir::ItemKind::Macro(..) | hir::ItemKind::Macro(..)
| hir::ItemKind::Mod(..) | hir::ItemKind::Mod(..)
@ -627,13 +627,13 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
// These sorts of items have no lifetime parameters at all. // These sorts of items have no lifetime parameters at all.
intravisit::walk_item(self, item); intravisit::walk_item(self, item);
} }
hir::ItemKind::TyAlias(_, generics) hir::ItemKind::TyAlias(_, _, generics)
| hir::ItemKind::Const(_, generics, _) | hir::ItemKind::Const(_, _, generics, _)
| hir::ItemKind::Enum(_, generics) | hir::ItemKind::Enum(_, _, generics)
| hir::ItemKind::Struct(_, generics) | hir::ItemKind::Struct(_, _, generics)
| hir::ItemKind::Union(_, generics) | hir::ItemKind::Union(_, _, generics)
| hir::ItemKind::Trait(_, _, generics, ..) | hir::ItemKind::Trait(_, _, _, generics, ..)
| hir::ItemKind::TraitAlias(generics, ..) | hir::ItemKind::TraitAlias(_, generics, ..)
| hir::ItemKind::Impl(&hir::Impl { generics, .. }) => { | hir::ItemKind::Impl(&hir::Impl { generics, .. }) => {
// These kinds of items have only early-bound lifetime parameters. // These kinds of items have only early-bound lifetime parameters.
self.visit_early(item.hir_id(), generics, |this| intravisit::walk_item(this, item)); self.visit_early(item.hir_id(), generics, |this| intravisit::walk_item(this, item));

View file

@ -202,35 +202,35 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
}, },
Node::Item(item) => match item.kind { Node::Item(item) => match item.kind {
ItemKind::Static(ty, .., body_id) => { ItemKind::Static(ident, ty, .., body_id) => {
if ty.is_suggestable_infer_ty() { if ty.is_suggestable_infer_ty() {
infer_placeholder_type( infer_placeholder_type(
icx.lowerer(), icx.lowerer(),
def_id, def_id,
body_id, body_id,
ty.span, ty.span,
item.ident, ident,
"static variable", "static variable",
) )
} else { } else {
icx.lower_ty(ty) icx.lower_ty(ty)
} }
} }
ItemKind::Const(ty, _, body_id) => { ItemKind::Const(ident, ty, _, body_id) => {
if ty.is_suggestable_infer_ty() { if ty.is_suggestable_infer_ty() {
infer_placeholder_type( infer_placeholder_type(
icx.lowerer(), icx.lowerer(),
def_id, def_id,
body_id, body_id,
ty.span, ty.span,
item.ident, ident,
"constant", "constant",
) )
} else { } else {
icx.lower_ty(ty) icx.lower_ty(ty)
} }
} }
ItemKind::TyAlias(self_ty, _) => icx.lower_ty(self_ty), ItemKind::TyAlias(_, self_ty, _) => icx.lower_ty(self_ty),
ItemKind::Impl(hir::Impl { self_ty, .. }) => match self_ty.find_self_aliases() { ItemKind::Impl(hir::Impl { self_ty, .. }) => match self_ty.find_self_aliases() {
spans if spans.len() > 0 => { spans if spans.len() > 0 => {
let guar = tcx let guar = tcx
@ -479,5 +479,5 @@ pub(crate) fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) ->
} }
} }
} }
HasTait.visit_ty_unambig(tcx.hir_expect_item(def_id).expect_ty_alias().0).is_break() HasTait.visit_ty_unambig(tcx.hir_expect_item(def_id).expect_ty_alias().1).is_break()
} }

View file

@ -140,14 +140,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let generics = match tcx.hir_node_by_def_id(parent_item) { let generics = match tcx.hir_node_by_def_id(parent_item) {
hir::Node::Item(hir::Item { hir::Node::Item(hir::Item {
kind: hir::ItemKind::Struct(variant, generics), .. kind: hir::ItemKind::Struct(_, variant, generics),
..
}) => { }) => {
if !variant.fields().iter().any(|field| field.hir_id == parent_hir_id) { if !variant.fields().iter().any(|field| field.hir_id == parent_hir_id) {
return false; return false;
} }
generics generics
} }
hir::Node::Item(hir::Item { kind: hir::ItemKind::Enum(def, generics), .. }) => { hir::Node::Item(hir::Item { kind: hir::ItemKind::Enum(_, def, generics), .. }) => {
if !def if !def
.variants .variants
.iter() .iter()
@ -267,7 +268,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
hir::Node::Field(field) => { hir::Node::Field(field) => {
// Enums can't have unsized fields, fields can only have an unsized tail field. // Enums can't have unsized fields, fields can only have an unsized tail field.
if let hir::Node::Item(hir::Item { if let hir::Node::Item(hir::Item {
kind: hir::ItemKind::Struct(variant, _), .. kind: hir::ItemKind::Struct(_, variant, _), ..
}) = tcx.parent_hir_node(field.hir_id) }) = tcx.parent_hir_node(field.hir_id)
&& variant && variant
.fields() .fields()

View file

@ -136,9 +136,9 @@ fn diagnostic_hir_wf_check<'tcx>(
ref item => bug!("Unexpected TraitItem {:?}", item), ref item => bug!("Unexpected TraitItem {:?}", item),
}, },
hir::Node::Item(item) => match item.kind { hir::Node::Item(item) => match item.kind {
hir::ItemKind::TyAlias(ty, _) hir::ItemKind::TyAlias(_, ty, _)
| hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Static(_, ty, _, _)
| hir::ItemKind::Const(ty, _, _) => vec![ty], | hir::ItemKind::Const(_, ty, _, _) => vec![ty],
hir::ItemKind::Impl(impl_) => match &impl_.of_trait { hir::ItemKind::Impl(impl_) => match &impl_.of_trait {
Some(t) => t Some(t) => t
.path .path

View file

@ -559,7 +559,7 @@ impl<'a> State<'a> {
self.print_attrs_as_outer(attrs); self.print_attrs_as_outer(attrs);
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, ident) => {
self.head("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);
@ -567,7 +567,7 @@ impl<'a> State<'a> {
self.word("as"); self.word("as");
self.space(); self.space();
} }
self.print_ident(item.ident); self.print_ident(ident);
self.word(";"); self.word(";");
self.end(); // end inner head-block self.end(); // end inner head-block
self.end(); // end outer head-block self.end(); // end outer head-block
@ -577,11 +577,11 @@ impl<'a> State<'a> {
self.print_path(path, false); self.print_path(path, false);
match kind { match kind {
hir::UseKind::Single => { hir::UseKind::Single(ident) => {
if path.segments.last().unwrap().ident != item.ident { if path.segments.last().unwrap().ident != ident {
self.space(); self.space();
self.word_space("as"); self.word_space("as");
self.print_ident(item.ident); self.print_ident(ident);
} }
self.word(";"); self.word(";");
} }
@ -591,12 +591,12 @@ impl<'a> State<'a> {
self.end(); // end inner head-block self.end(); // end inner head-block
self.end(); // end outer head-block self.end(); // end outer head-block
} }
hir::ItemKind::Static(ty, m, expr) => { hir::ItemKind::Static(ident, ty, m, expr) => {
self.head("static"); self.head("static");
if m.is_mut() { if m.is_mut() {
self.word_space("mut"); self.word_space("mut");
} }
self.print_ident(item.ident); self.print_ident(ident);
self.word_space(":"); self.word_space(":");
self.print_type(ty); self.print_type(ty);
self.space(); self.space();
@ -607,9 +607,9 @@ impl<'a> State<'a> {
self.word(";"); self.word(";");
self.end(); // end the outer cbox self.end(); // end the outer cbox
} }
hir::ItemKind::Const(ty, generics, expr) => { hir::ItemKind::Const(ident, ty, generics, expr) => {
self.head("const"); self.head("const");
self.print_ident(item.ident); self.print_ident(ident);
self.print_generic_params(generics.params); self.print_generic_params(generics.params);
self.word_space(":"); self.word_space(":");
self.print_type(ty); self.print_type(ty);
@ -622,30 +622,23 @@ impl<'a> State<'a> {
self.word(";"); self.word(";");
self.end(); // end the outer cbox self.end(); // end the outer cbox
} }
hir::ItemKind::Fn { sig, generics, body, .. } => { hir::ItemKind::Fn { ident, sig, generics, body, .. } => {
self.head(""); self.head("");
self.print_fn( self.print_fn(sig.decl, sig.header, Some(ident.name), generics, &[], Some(body));
sig.decl,
sig.header,
Some(item.ident.name),
generics,
&[],
Some(body),
);
self.word(" "); self.word(" ");
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
self.ann.nested(self, Nested::Body(body)); self.ann.nested(self, Nested::Body(body));
} }
hir::ItemKind::Macro(macro_def, _) => { hir::ItemKind::Macro(ident, macro_def, _) => {
self.print_mac_def(macro_def, &item.ident, item.span, |_| {}); self.print_mac_def(macro_def, &ident, item.span, |_| {});
} }
hir::ItemKind::Mod(_mod) => { hir::ItemKind::Mod(ident, mod_) => {
self.head("mod"); self.head("mod");
self.print_ident(item.ident); self.print_ident(ident);
self.nbsp(); self.nbsp();
self.bopen(); self.bopen();
self.print_mod(_mod, attrs); self.print_mod(mod_, attrs);
self.bclose(item.span); self.bclose(item.span);
} }
hir::ItemKind::ForeignMod { abi, items } => { hir::ItemKind::ForeignMod { abi, items } => {
@ -663,9 +656,9 @@ impl<'a> State<'a> {
self.print_inline_asm(asm); self.print_inline_asm(asm);
self.end() self.end()
} }
hir::ItemKind::TyAlias(ty, generics) => { hir::ItemKind::TyAlias(ident, ty, generics) => {
self.head("type"); self.head("type");
self.print_ident(item.ident); self.print_ident(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
@ -676,16 +669,16 @@ impl<'a> State<'a> {
self.word(";"); self.word(";");
self.end(); // end the outer ibox self.end(); // end the outer ibox
} }
hir::ItemKind::Enum(ref enum_definition, params) => { hir::ItemKind::Enum(ident, ref enum_definition, params) => {
self.print_enum_def(enum_definition, params, item.ident.name, item.span); self.print_enum_def(enum_definition, params, ident.name, item.span);
} }
hir::ItemKind::Struct(ref struct_def, generics) => { hir::ItemKind::Struct(ident, ref struct_def, generics) => {
self.head("struct"); self.head("struct");
self.print_struct(struct_def, generics, item.ident.name, item.span, true); self.print_struct(struct_def, generics, ident.name, item.span, true);
} }
hir::ItemKind::Union(ref struct_def, generics) => { hir::ItemKind::Union(ident, ref struct_def, generics) => {
self.head("union"); self.head("union");
self.print_struct(struct_def, generics, item.ident.name, item.span, true); self.print_struct(struct_def, generics, ident.name, item.span, true);
} }
hir::ItemKind::Impl(&hir::Impl { hir::ItemKind::Impl(&hir::Impl {
constness, constness,
@ -733,12 +726,12 @@ impl<'a> State<'a> {
} }
self.bclose(item.span); self.bclose(item.span);
} }
hir::ItemKind::Trait(is_auto, safety, generics, bounds, trait_items) => { hir::ItemKind::Trait(is_auto, safety, ident, generics, bounds, trait_items) => {
self.head(""); self.head("");
self.print_is_auto(is_auto); self.print_is_auto(is_auto);
self.print_safety(safety); self.print_safety(safety);
self.word_nbsp("trait"); self.word_nbsp("trait");
self.print_ident(item.ident); self.print_ident(ident);
self.print_generic_params(generics.params); self.print_generic_params(generics.params);
self.print_bounds(":", bounds); self.print_bounds(":", bounds);
self.print_where_clause(generics); self.print_where_clause(generics);
@ -749,9 +742,9 @@ impl<'a> State<'a> {
} }
self.bclose(item.span); self.bclose(item.span);
} }
hir::ItemKind::TraitAlias(generics, bounds) => { hir::ItemKind::TraitAlias(ident, generics, bounds) => {
self.head("trait"); self.head("trait");
self.print_ident(item.ident); self.print_ident(ident);
self.print_generic_params(generics.params); self.print_generic_params(generics.params);
self.nbsp(); self.nbsp();
self.print_bounds("=", bounds); self.print_bounds("=", bounds);

View file

@ -713,8 +713,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
for id in self.tcx.hir_free_items() { for id in self.tcx.hir_free_items() {
if let Some(node) = self.tcx.hir_get_if_local(id.owner_id.into()) if let Some(node) = self.tcx.hir_get_if_local(id.owner_id.into())
&& let hir::Node::Item(item) = node && let hir::Node::Item(item) = node
&& let hir::ItemKind::Fn { .. } = item.kind && let hir::ItemKind::Fn { ident, .. } = item.kind
&& item.ident.name == segment.ident.name && ident.name == segment.ident.name
{ {
err.span_label( err.span_label(
self.tcx.def_span(id.owner_id), self.tcx.def_span(id.owner_id),

View file

@ -721,8 +721,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}, },
)) => { )) => {
if let Some(hir::Node::Item(hir::Item { if let Some(hir::Node::Item(hir::Item {
ident, kind:
kind: hir::ItemKind::Static(ty, ..) | hir::ItemKind::Const(ty, ..), hir::ItemKind::Static(ident, ty, ..)
| hir::ItemKind::Const(ident, ty, ..),
.. ..
})) = self.tcx.hir_get_if_local(*def_id) })) = self.tcx.hir_get_if_local(*def_id)
{ {

View file

@ -904,7 +904,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Assumes given function doesn't have a explicit return type. /// Assumes given function doesn't have a explicit return type.
fn can_add_return_type(&self, fn_id: LocalDefId) -> bool { fn can_add_return_type(&self, fn_id: LocalDefId) -> bool {
match self.tcx.hir_node_by_def_id(fn_id) { match self.tcx.hir_node_by_def_id(fn_id) {
Node::Item(&hir::Item { ident, .. }) => { Node::Item(item) => {
let (ident, _, _, _) = item.expect_fn();
// This is less than ideal, it will not suggest a return type span on any // This is less than ideal, it will not suggest a return type span on any
// method called `main`, regardless of whether it is actually the entry point, // method called `main`, regardless of whether it is actually the entry point,
// but it will still present it as the reason for the expected type. // but it will still present it as the reason for the expected type.

View file

@ -367,20 +367,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.collect(); .collect();
// Find an identifier with which this trait was imported (note that `_` doesn't count). // Find an identifier with which this trait was imported (note that `_` doesn't count).
let any_id = import_items.iter().find_map(|item| { for item in import_items.iter() {
if item.ident.name != kw::Underscore { Some(item.ident) } else { None } let (_, kind) = item.expect_use();
}); match kind {
if let Some(any_id) = any_id { hir::UseKind::Single(ident) => {
if any_id.name == kw::Empty { if ident.name != kw::Underscore {
// Glob import, so just use its name. return Some(format!("{}", ident.name));
return None; }
} else { }
return Some(format!("{any_id}")); hir::UseKind::Glob => return None, // Glob import, so just use its name.
hir::UseKind::ListStem => unreachable!(),
} }
} }
// All that is left is `_`! We need to use the full path. It doesn't matter which one we pick, // All that is left is `_`! We need to use the full path. It doesn't matter which one we
// so just take the first one. // pick, so just take the first one.
match import_items[0].kind { match import_items[0].kind {
ItemKind::Use(path, _) => Some( ItemKind::Use(path, _) => Some(
path.segments path.segments

View file

@ -1204,13 +1204,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
Some( Some(
Node::Item(hir::Item { Node::Item(hir::Item {
ident, kind:
kind: hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..), hir::ItemKind::Trait(_, _, ident, ..)
| hir::ItemKind::TraitAlias(ident, ..),
.. ..
}) })
// We may also encounter unsatisfied GAT or method bounds // We may also encounter unsatisfied GAT or method bounds
| Node::TraitItem(hir::TraitItem { ident, .. }) | Node::TraitItem(hir::TraitItem { ident, .. })
| Node::ImplItem(hir::ImplItem { ident, .. }), | Node::ImplItem(hir::ImplItem { ident, .. })
) => { ) => {
skip_list.insert(p); skip_list.insert(p);
let entry = spanned_predicates.entry(ident.span); let entry = spanned_predicates.entry(ident.span);
@ -3960,8 +3961,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return; return;
} }
Node::Item(hir::Item { Node::Item(hir::Item {
kind: hir::ItemKind::Trait(.., bounds, _), kind: hir::ItemKind::Trait(_, _, ident, _, bounds, _),
ident,
.. ..
}) => { }) => {
let (sp, sep, article) = if bounds.is_empty() { let (sp, sep, article) = if bounds.is_empty() {

View file

@ -1250,7 +1250,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match opt_def_id { match opt_def_id {
Some(def_id) => match self.tcx.hir_get_if_local(def_id) { Some(def_id) => match self.tcx.hir_get_if_local(def_id) {
Some(hir::Node::Item(hir::Item { Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Const(_, _, body_id), kind: hir::ItemKind::Const(_, _, _, body_id),
.. ..
})) => match self.tcx.hir_node(body_id.hir_id) { })) => match self.tcx.hir_node(body_id.hir_id) {
hir::Node::Expr(expr) => { hir::Node::Expr(expr) => {

View file

@ -441,7 +441,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
// so we will continue to exclude them for compatibility. // so we will continue to exclude them for compatibility.
// //
// The documentation on `ExternCrate` is not used at the moment so no need to warn for it. // The documentation on `ExternCrate` is not used at the moment so no need to warn for it.
if let hir::ItemKind::Impl(..) | hir::ItemKind::Use(..) | hir::ItemKind::ExternCrate(_) = if let hir::ItemKind::Impl(..) | hir::ItemKind::Use(..) | hir::ItemKind::ExternCrate(..) =
it.kind it.kind
{ {
return; return;
@ -545,21 +545,21 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
return; return;
} }
let (def, ty) = match item.kind { let (def, ty) = match item.kind {
hir::ItemKind::Struct(_, ast_generics) => { hir::ItemKind::Struct(_, _, ast_generics) => {
if !ast_generics.params.is_empty() { if !ast_generics.params.is_empty() {
return; return;
} }
let def = cx.tcx.adt_def(item.owner_id); let def = cx.tcx.adt_def(item.owner_id);
(def, Ty::new_adt(cx.tcx, def, ty::List::empty())) (def, Ty::new_adt(cx.tcx, def, ty::List::empty()))
} }
hir::ItemKind::Union(_, ast_generics) => { hir::ItemKind::Union(_, _, ast_generics) => {
if !ast_generics.params.is_empty() { if !ast_generics.params.is_empty() {
return; return;
} }
let def = cx.tcx.adt_def(item.owner_id); let def = cx.tcx.adt_def(item.owner_id);
(def, Ty::new_adt(cx.tcx, def, ty::List::empty())) (def, Ty::new_adt(cx.tcx, def, ty::List::empty()))
} }
hir::ItemKind::Enum(_, ast_generics) => { hir::ItemKind::Enum(_, _, ast_generics) => {
if !ast_generics.params.is_empty() { if !ast_generics.params.is_empty() {
return; return;
} }
@ -1416,7 +1416,7 @@ impl TypeAliasBounds {
impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) { fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
let hir::ItemKind::TyAlias(hir_ty, generics) = item.kind else { return }; let hir::ItemKind::TyAlias(_, hir_ty, generics) = item.kind else { return };
// There must not be a where clause. // There must not be a where clause.
if generics.predicates.is_empty() { if generics.predicates.is_empty() {
@ -2119,9 +2119,9 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
use rustc_middle::middle::resolve_bound_vars::ResolvedArg; use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
let def_id = item.owner_id.def_id; let def_id = item.owner_id.def_id;
if let hir::ItemKind::Struct(_, hir_generics) if let hir::ItemKind::Struct(_, _, hir_generics)
| hir::ItemKind::Enum(_, hir_generics) | hir::ItemKind::Enum(_, _, hir_generics)
| hir::ItemKind::Union(_, hir_generics) = item.kind | hir::ItemKind::Union(_, _, hir_generics) = item.kind
{ {
let inferred_outlives = cx.tcx.inferred_outlives_of(def_id); let inferred_outlives = cx.tcx.inferred_outlives_of(def_id);
if inferred_outlives.is_empty() { if inferred_outlives.is_empty() {
@ -2257,7 +2257,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
// generics, except for tuple struct, which have the `where` // generics, except for tuple struct, which have the `where`
// after the fields of the struct. // after the fields of the struct.
let full_where_span = let full_where_span =
if let hir::ItemKind::Struct(hir::VariantData::Tuple(..), _) = item.kind { if let hir::ItemKind::Struct(_, hir::VariantData::Tuple(..), _) = item.kind {
where_span where_span
} else { } else {
hir_generics.span.shrink_to_hi().to(where_span) hir_generics.span.shrink_to_hi().to(where_span)

View file

@ -93,7 +93,11 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived {
let orig_fields = match cx.tcx.hir_get_if_local(type_def_id) { let orig_fields = match cx.tcx.hir_get_if_local(type_def_id) {
Some(hir::Node::Item(hir::Item { Some(hir::Node::Item(hir::Item {
kind: kind:
hir::ItemKind::Struct(hir::VariantData::Struct { fields, recovered: _ }, _generics), hir::ItemKind::Struct(
_,
hir::VariantData::Struct { fields, recovered: _ },
_generics,
),
.. ..
})) => fields.iter().map(|f| (f.ident.name, f)).collect::<FxHashMap<_, _>>(), })) => fields.iter().map(|f| (f.ident.name, f)).collect::<FxHashMap<_, _>>(),
_ => return, _ => return,

View file

@ -308,18 +308,18 @@ impl<'tcx> LateLintPass<'tcx> for TypeIr {
[.., penultimate, segment] [.., penultimate, segment]
if penultimate.res.opt_def_id().is_some_and(is_mod_inherent) => if penultimate.res.opt_def_id().is_some_and(is_mod_inherent) =>
{ {
(segment.ident.span, item.ident.span, "*") (segment.ident.span, item.kind.ident().unwrap().span, "*")
} }
[.., segment] [.., segment]
if path.res.iter().flat_map(Res::opt_def_id).any(is_mod_inherent) if path.res.iter().flat_map(Res::opt_def_id).any(is_mod_inherent)
&& let rustc_hir::UseKind::Single = kind => && let rustc_hir::UseKind::Single(ident) = kind =>
{ {
let (lo, snippet) = let (lo, snippet) =
match cx.tcx.sess.source_map().span_to_snippet(path.span).as_deref() { match cx.tcx.sess.source_map().span_to_snippet(path.span).as_deref() {
Ok("self") => (path.span, "*"), Ok("self") => (path.span, "*"),
_ => (segment.ident.span.shrink_to_hi(), "::*"), _ => (segment.ident.span.shrink_to_hi(), "::*"),
}; };
(lo, if segment.ident == item.ident { lo } else { item.ident.span }, snippet) (lo, if segment.ident == ident { lo } else { ident.span }, snippet)
} }
_ => return, _ => return,
}; };

View file

@ -39,7 +39,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable {
let def_id = item.owner_id.to_def_id(); let def_id = item.owner_id.to_def_id();
// NOTE(nbdd0121): use `dyn_compatibility_violations` instead of `is_dyn_compatible` because // NOTE(nbdd0121): use `dyn_compatibility_violations` instead of `is_dyn_compatible` because
// the latter will report `where_clause_object_safety` lint. // the latter will report `where_clause_object_safety` lint.
if let hir::ItemKind::Trait(_, _, _, _, _) = item.kind if let hir::ItemKind::Trait(_, _, ident, ..) = item.kind
&& cx.tcx.is_dyn_compatible(def_id) && cx.tcx.is_dyn_compatible(def_id)
{ {
let direct_super_traits_iter = cx let direct_super_traits_iter = cx
@ -51,7 +51,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable {
cx.emit_span_lint( cx.emit_span_lint(
MULTIPLE_SUPERTRAIT_UPCASTABLE, MULTIPLE_SUPERTRAIT_UPCASTABLE,
cx.tcx.def_span(def_id), cx.tcx.def_span(def_id),
crate::lints::MultipleSupertraitUpcastable { ident: item.ident }, crate::lints::MultipleSupertraitUpcastable { ident },
); );
} }
} }

View file

@ -181,10 +181,10 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
&& parent_opt_item_name != Some(kw::Underscore) && parent_opt_item_name != Some(kw::Underscore)
&& let Some(parent) = parent.as_local() && let Some(parent) = parent.as_local()
&& let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent) && let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent)
&& let ItemKind::Const(ty, _, _) = item.kind && let ItemKind::Const(ident, ty, _, _) = item.kind
&& let TyKind::Tup(&[]) = ty.kind && let TyKind::Tup(&[]) = ty.kind
{ {
Some(item.ident.span) Some(ident.span)
} else { } else {
None None
}; };
@ -238,7 +238,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
}, },
) )
} }
ItemKind::Macro(_macro, MacroKind::Bang) ItemKind::Macro(_, _macro, MacroKind::Bang)
if cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) => if cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) =>
{ {
cx.emit_span_lint( cx.emit_span_lint(

View file

@ -415,8 +415,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
} }
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
if let hir::ItemKind::Mod(_) = it.kind { if let hir::ItemKind::Mod(ident, _) = it.kind {
self.check_snake_case(cx, "module", &it.ident); self.check_snake_case(cx, "module", &ident);
} }
} }
@ -498,11 +498,13 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
let attrs = cx.tcx.hir_attrs(it.hir_id()); let attrs = cx.tcx.hir_attrs(it.hir_id());
match it.kind { match it.kind {
hir::ItemKind::Static(..) if !ast::attr::contains_name(attrs, sym::no_mangle) => { hir::ItemKind::Static(ident, ..)
NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident); if !ast::attr::contains_name(attrs, sym::no_mangle) =>
{
NonUpperCaseGlobals::check_upper_case(cx, "static variable", &ident);
} }
hir::ItemKind::Const(..) => { hir::ItemKind::Const(ident, ..) => {
NonUpperCaseGlobals::check_upper_case(cx, "constant", &it.ident); NonUpperCaseGlobals::check_upper_case(cx, "constant", &ident);
} }
_ => {} _ => {}
} }

View file

@ -1664,7 +1664,7 @@ impl ImproperCTypesDefinitions {
&& cx.tcx.sess.target.os == "aix" && cx.tcx.sess.target.os == "aix"
&& !adt_def.all_fields().next().is_none() && !adt_def.all_fields().next().is_none()
{ {
let struct_variant_data = item.expect_struct().0; let struct_variant_data = item.expect_struct().1;
for (index, ..) in struct_variant_data.fields().iter().enumerate() { for (index, ..) in struct_variant_data.fields().iter().enumerate() {
// Struct fields (after the first field) are checked for the // Struct fields (after the first field) are checked for the
// power alignment rule, as fields after the first are likely // power alignment rule, as fields after the first are likely
@ -1696,9 +1696,9 @@ impl ImproperCTypesDefinitions {
impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions { impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
match item.kind { match item.kind {
hir::ItemKind::Static(ty, ..) hir::ItemKind::Static(_, ty, ..)
| hir::ItemKind::Const(ty, ..) | hir::ItemKind::Const(_, ty, ..)
| hir::ItemKind::TyAlias(ty, ..) => { | hir::ItemKind::TyAlias(_, ty, ..) => {
self.check_ty_maybe_containing_foreign_fnptr( self.check_ty_maybe_containing_foreign_fnptr(
cx, cx,
ty, ty,
@ -1765,7 +1765,7 @@ declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]);
impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences { impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences {
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
if let hir::ItemKind::Enum(ref enum_definition, _) = it.kind { if let hir::ItemKind::Enum(_, ref enum_definition, _) = it.kind {
let t = cx.tcx.type_of(it.owner_id).instantiate_identity(); let t = cx.tcx.type_of(it.owner_id).instantiate_identity();
let ty = cx.tcx.erase_regions(t); let ty = cx.tcx.erase_regions(t);
let Ok(layout) = cx.layout_of(ty) else { return }; let Ok(layout) = cx.layout_of(ty) else { return };

View file

@ -1836,7 +1836,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_info_for_macro(&mut self, def_id: LocalDefId) { fn encode_info_for_macro(&mut self, def_id: LocalDefId) {
let tcx = self.tcx; let tcx = self.tcx;
let hir::ItemKind::Macro(macro_def, _) = tcx.hir_expect_item(def_id).kind else { bug!() }; let (_, macro_def, _) = tcx.hir_expect_item(def_id).expect_macro();
self.tables.is_macro_rules.set(def_id.local_def_index, macro_def.macro_rules); self.tables.is_macro_rules.set(def_id.local_def_index, macro_def.macro_rules);
record!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body); record!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body);
} }

View file

@ -385,7 +385,7 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn hir_get_module(self, module: LocalModDefId) -> (&'tcx Mod<'tcx>, Span, HirId) { pub fn hir_get_module(self, module: LocalModDefId) -> (&'tcx Mod<'tcx>, Span, HirId) {
let hir_id = HirId::make_owner(module.to_local_def_id()); let hir_id = HirId::make_owner(module.to_local_def_id());
match self.hir_owner_node(hir_id.owner) { match self.hir_owner_node(hir_id.owner) {
OwnerNode::Item(&Item { span, kind: ItemKind::Mod(m), .. }) => (m, span, hir_id), OwnerNode::Item(&Item { span, kind: ItemKind::Mod(_, m), .. }) => (m, span, hir_id),
OwnerNode::Crate(item) => (item, item.spans.inner_span, hir_id), OwnerNode::Crate(item) => (item, item.spans.inner_span, hir_id),
node => panic!("not a module: {node:?}"), node => panic!("not a module: {node:?}"),
} }
@ -847,7 +847,7 @@ impl<'tcx> TyCtxt<'tcx> {
// A `Ctor` doesn't have an identifier itself, but its parent // A `Ctor` doesn't have an identifier itself, but its parent
// struct/variant does. Compare with `hir::Map::span`. // struct/variant does. Compare with `hir::Map::span`.
Node::Ctor(..) => match self.parent_hir_node(id) { Node::Ctor(..) => match self.parent_hir_node(id) {
Node::Item(item) => Some(item.ident), Node::Item(item) => Some(item.kind.ident().unwrap()),
Node::Variant(variant) => Some(variant.ident), Node::Variant(variant) => Some(variant.ident),
_ => unreachable!(), _ => unreachable!(),
}, },
@ -894,7 +894,6 @@ impl<'hir> Map<'hir> {
} }
fn named_span(item_span: Span, ident: Ident, generics: Option<&Generics<'_>>) -> Span { fn named_span(item_span: Span, ident: Ident, generics: Option<&Generics<'_>>) -> Span {
if ident.name != kw::Empty {
let mut span = until_within(item_span, ident.span); let mut span = until_within(item_span, ident.span);
if let Some(g) = generics if let Some(g) = generics
&& !g.span.is_dummy() && !g.span.is_dummy()
@ -903,9 +902,6 @@ impl<'hir> Map<'hir> {
span = span.to(g_span); span = span.to(g_span);
} }
span span
} else {
item_span
}
} }
let span = match self.tcx.hir_node(hir_id) { let span = match self.tcx.hir_node(hir_id) {
@ -936,7 +932,7 @@ impl<'hir> Map<'hir> {
}) => until_within(*outer_span, generics.where_clause_span), }) => until_within(*outer_span, generics.where_clause_span),
// Constants and Statics. // Constants and Statics.
Node::Item(Item { Node::Item(Item {
kind: ItemKind::Const(ty, ..) | ItemKind::Static(ty, ..), kind: ItemKind::Const(_, ty, ..) | ItemKind::Static(_, ty, ..),
span: outer_span, span: outer_span,
.. ..
}) })
@ -957,7 +953,7 @@ impl<'hir> Map<'hir> {
}) => until_within(*outer_span, ty.span), }) => until_within(*outer_span, ty.span),
// With generics and bounds. // With generics and bounds.
Node::Item(Item { Node::Item(Item {
kind: ItemKind::Trait(_, _, generics, bounds, _), kind: ItemKind::Trait(_, _, _, generics, bounds, _),
span: outer_span, span: outer_span,
.. ..
}) })
@ -977,7 +973,13 @@ impl<'hir> Map<'hir> {
// SyntaxContext of the path. // SyntaxContext of the path.
path.span.find_ancestor_in_same_ctxt(item.span).unwrap_or(item.span) path.span.find_ancestor_in_same_ctxt(item.span).unwrap_or(item.span)
} }
_ => named_span(item.span, item.ident, item.kind.generics()), _ => {
if let Some(ident) = item.kind.ident() {
named_span(item.span, ident, item.kind.generics())
} else {
item.span
}
}
}, },
Node::Variant(variant) => named_span(variant.span, variant.ident, None), Node::Variant(variant) => named_span(variant.span, variant.ident, None),
Node::ImplItem(item) => named_span(item.span, item.ident, Some(item.generics)), Node::ImplItem(item) => named_span(item.span, item.ident, Some(item.generics)),
@ -1327,7 +1329,7 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
self.items.push(item.item_id()); self.items.push(item.item_id());
// Items that are modules are handled here instead of in visit_mod. // Items that are modules are handled here instead of in visit_mod.
if let ItemKind::Mod(module) = &item.kind { if let ItemKind::Mod(_, module) = &item.kind {
self.submodules.push(item.owner_id); self.submodules.push(item.owner_id);
// A module collector does not recurse inside nested modules. // A module collector does not recurse inside nested modules.
if self.crate_collector { if self.crate_collector {

View file

@ -3406,20 +3406,18 @@ define_print_and_forward_display! {
} }
fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, Namespace, DefId)) { fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, Namespace, DefId)) {
// Iterate all local crate items no matter where they are defined. // Iterate all (non-anonymous) local crate items no matter where they are defined.
for id in tcx.hir_free_items() { for id in tcx.hir_free_items() {
if matches!(tcx.def_kind(id.owner_id), DefKind::Use) { if matches!(tcx.def_kind(id.owner_id), DefKind::Use) {
continue; continue;
} }
let item = tcx.hir_item(id); let item = tcx.hir_item(id);
if item.ident.name == kw::Empty { let Some(ident) = item.kind.ident() else { continue };
continue;
}
let def_id = item.owner_id.to_def_id(); let def_id = item.owner_id.to_def_id();
let ns = tcx.def_kind(def_id).ns().unwrap_or(Namespace::TypeNS); let ns = tcx.def_kind(def_id).ns().unwrap_or(Namespace::TypeNS);
collect_fn(&item.ident, ns, def_id); collect_fn(&ident, ns, def_id);
} }
// Now take care of extern crate items. // Now take care of extern crate items.

View file

@ -563,7 +563,7 @@ fn construct_const<'a, 'tcx>(
// Figure out what primary body this item has. // Figure out what primary body this item has.
let (span, const_ty_span) = match tcx.hir_node(hir_id) { let (span, const_ty_span) = match tcx.hir_node(hir_id) {
Node::Item(hir::Item { Node::Item(hir::Item {
kind: hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _, _), kind: hir::ItemKind::Static(_, ty, _, _) | hir::ItemKind::Const(_, ty, _, _),
span, span,
.. ..
}) })

View file

@ -1044,7 +1044,6 @@ fn find_fallback_pattern_typo<'tcx>(
if let DefKind::Use = cx.tcx.def_kind(item.owner_id) { if let DefKind::Use = cx.tcx.def_kind(item.owner_id) {
// Look for consts being re-exported. // Look for consts being re-exported.
let item = cx.tcx.hir_expect_item(item.owner_id.def_id); let item = cx.tcx.hir_expect_item(item.owner_id.def_id);
let use_name = item.ident.name;
let hir::ItemKind::Use(path, _) = item.kind else { let hir::ItemKind::Use(path, _) = item.kind else {
continue; continue;
}; };
@ -1064,8 +1063,9 @@ fn find_fallback_pattern_typo<'tcx>(
{ {
// The const is accessible only through the re-export, point at // The const is accessible only through the re-export, point at
// the `use`. // the `use`.
imported.push(use_name); let ident = item.kind.ident().unwrap();
imported_spans.push(item.ident.span); imported.push(ident.name);
imported_spans.push(ident.span);
} }
} }
} }

View file

@ -743,7 +743,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
match target { match target {
Target::Struct => { Target::Struct => {
if let Some(ItemLike::Item(hir::Item { if let Some(ItemLike::Item(hir::Item {
kind: hir::ItemKind::Struct(hir::VariantData::Struct { fields, .. }, _), kind: hir::ItemKind::Struct(_, hir::VariantData::Struct { fields, .. }, _),
.. ..
})) = item })) = item
&& !fields.is_empty() && !fields.is_empty()
@ -1019,7 +1019,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
_ => None, _ => None,
}; };
match item_kind { match item_kind {
Some(ItemKind::Mod(module)) => { Some(ItemKind::Mod(_, module)) => {
if !module.item_ids.is_empty() { if !module.item_ids.is_empty() {
self.dcx().emit_err(errors::DocKeywordEmptyMod { span: meta.span() }); self.dcx().emit_err(errors::DocKeywordEmptyMod { span: meta.span() });
return; return;
@ -1072,9 +1072,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
return; return;
}; };
match item.kind { match item.kind {
ItemKind::Enum(_, generics) | ItemKind::Struct(_, generics) ItemKind::Enum(_, _, generics) | ItemKind::Struct(_, _, generics)
if generics.params.len() != 0 => {} if generics.params.len() != 0 => {}
ItemKind::Trait(_, _, generics, _, items) ItemKind::Trait(_, _, _, generics, _, items)
if generics.params.len() != 0 if generics.params.len() != 0
|| items.iter().any(|item| matches!(item.kind, AssocItemKind::Type)) => {} || items.iter().any(|item| matches!(item.kind, AssocItemKind::Type)) => {}
_ => { _ => {
@ -2293,7 +2293,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
} }
} else { } else {
// special case when `#[macro_export]` is applied to a macro 2.0 // special case when `#[macro_export]` is applied to a macro 2.0
let (macro_definition, _) = self.tcx.hir_node(hir_id).expect_item().expect_macro(); let (_, macro_definition, _) = self.tcx.hir_node(hir_id).expect_item().expect_macro();
let is_decl_macro = !macro_definition.macro_rules; let is_decl_macro = !macro_definition.macro_rules;
if is_decl_macro { if is_decl_macro {
@ -2624,7 +2624,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
// Historically we've run more checks on non-exported than exported macros, // Historically we've run more checks on non-exported than exported macros,
// so this lets us continue to run them while maintaining backwards compatibility. // so this lets us continue to run them while maintaining backwards compatibility.
// In the long run, the checks should be harmonized. // In the long run, the checks should be harmonized.
if let ItemKind::Macro(macro_def, _) = item.kind { if let ItemKind::Macro(_, macro_def, _) = item.kind {
let def_id = item.owner_id.to_def_id(); let def_id = item.owner_id.to_def_id();
if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) { if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) {
check_non_exported_macro_for_invalid_attrs(self.tcx, item); check_non_exported_macro_for_invalid_attrs(self.tcx, item);
@ -2736,7 +2736,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
} }
fn is_c_like_enum(item: &Item<'_>) -> bool { fn is_c_like_enum(item: &Item<'_>) -> bool {
if let ItemKind::Enum(ref def, _) = item.kind { if let ItemKind::Enum(_, ref def, _) = item.kind {
for variant in def.variants { for variant in def.variants {
match variant.data { match variant.data {
hir::VariantData::Unit(..) => { /* continue */ } hir::VariantData::Unit(..) => { /* continue */ }
@ -2784,7 +2784,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
.map(|id| tcx.hir_item(id)) .map(|id| tcx.hir_item(id))
.find(|item| !item.span.is_dummy()) // Skip prelude `use`s .find(|item| !item.span.is_dummy()) // Skip prelude `use`s
.map(|item| errors::ItemFollowingInnerAttr { .map(|item| errors::ItemFollowingInnerAttr {
span: item.ident.span, span: if let Some(ident) = item.kind.ident() { ident.span } else { item.span },
kind: item.kind.descr(), kind: item.kind.descr(),
}); });
let err = tcx.dcx().create_err(errors::InvalidAttrAtCrateLevel { let err = tcx.dcx().create_err(errors::InvalidAttrAtCrateLevel {

View file

@ -751,7 +751,7 @@ fn check_item<'tcx>(
match tcx.def_kind(id.owner_id) { match tcx.def_kind(id.owner_id) {
DefKind::Enum => { DefKind::Enum => {
let item = tcx.hir_item(id); let item = tcx.hir_item(id);
if let hir::ItemKind::Enum(ref enum_def, _) = item.kind { if let hir::ItemKind::Enum(_, ref enum_def, _) = item.kind {
if let Some(comes_from_allow) = allow_dead_code { if let Some(comes_from_allow) = allow_dead_code {
worklist.extend( worklist.extend(
enum_def.variants.iter().map(|variant| (variant.def_id, comes_from_allow)), enum_def.variants.iter().map(|variant| (variant.def_id, comes_from_allow)),
@ -806,7 +806,7 @@ fn check_item<'tcx>(
} }
DefKind::Struct => { DefKind::Struct => {
let item = tcx.hir_item(id); let item = tcx.hir_item(id);
if let hir::ItemKind::Struct(ref variant_data, _) = item.kind if let hir::ItemKind::Struct(_, ref variant_data, _) = item.kind
&& let Some(ctor_def_id) = variant_data.ctor_def_id() && let Some(ctor_def_id) = variant_data.ctor_def_id()
{ {
struct_constructors.insert(ctor_def_id, item.owner_id.def_id); struct_constructors.insert(ctor_def_id, item.owner_id.def_id);
@ -987,7 +987,7 @@ impl<'tcx> DeadVisitor<'tcx> {
&& let Some(enum_did) = tcx.opt_parent(may_variant.to_def_id()) && let Some(enum_did) = tcx.opt_parent(may_variant.to_def_id())
&& let Some(enum_local_id) = enum_did.as_local() && let Some(enum_local_id) = enum_did.as_local()
&& let Node::Item(item) = tcx.hir_node_by_def_id(enum_local_id) && let Node::Item(item) = tcx.hir_node_by_def_id(enum_local_id)
&& let ItemKind::Enum(_, _) = item.kind && let ItemKind::Enum(..) = item.kind
{ {
enum_local_id enum_local_id
} else { } else {
@ -1062,7 +1062,7 @@ impl<'tcx> DeadVisitor<'tcx> {
let tuple_fields = if let Some(parent_id) = parent_item let tuple_fields = if let Some(parent_id) = parent_item
&& let node = tcx.hir_node_by_def_id(parent_id) && let node = tcx.hir_node_by_def_id(parent_id)
&& let hir::Node::Item(hir::Item { && let hir::Node::Item(hir::Item {
kind: hir::ItemKind::Struct(hir::VariantData::Tuple(fields, _, _), _), kind: hir::ItemKind::Struct(_, hir::VariantData::Tuple(fields, _, _), _),
.. ..
}) = node }) = node
{ {

View file

@ -206,7 +206,7 @@ impl<'tcx> ReachableContext<'tcx> {
} }
} }
hir::ItemKind::Const(_, _, init) => { hir::ItemKind::Const(_, _, _, init) => {
// Only things actually ending up in the final constant value are reachable // Only things actually ending up in the final constant value are reachable
// for codegen. Everything else is only needed during const-eval, so even if // for codegen. Everything else is only needed during const-eval, so even if
// const-eval happens in a downstream crate, all they need is // const-eval happens in a downstream crate, all they need is
@ -234,7 +234,7 @@ impl<'tcx> ReachableContext<'tcx> {
// These are normal, nothing reachable about these // These are normal, nothing reachable about these
// inherently and their children are already in the // inherently and their children are already in the
// worklist, as determined by the privacy pass // worklist, as determined by the privacy pass
hir::ItemKind::ExternCrate(_) hir::ItemKind::ExternCrate(..)
| hir::ItemKind::Use(..) | hir::ItemKind::Use(..)
| hir::ItemKind::TyAlias(..) | hir::ItemKind::TyAlias(..)
| hir::ItemKind::Macro(..) | hir::ItemKind::Macro(..)

View file

@ -430,7 +430,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
kind = AnnotationKind::DeprecationProhibited; kind = AnnotationKind::DeprecationProhibited;
const_stab_inherit = InheritConstStability::Yes; const_stab_inherit = InheritConstStability::Yes;
} }
hir::ItemKind::Struct(ref sd, _) => { hir::ItemKind::Struct(_, ref sd, _) => {
if let Some(ctor_def_id) = sd.ctor_def_id() { if let Some(ctor_def_id) = sd.ctor_def_id() {
self.annotate( self.annotate(
ctor_def_id, ctor_def_id,
@ -773,10 +773,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
match item.kind { match item.kind {
hir::ItemKind::ExternCrate(_) => { hir::ItemKind::ExternCrate(_, ident) => {
// compiler-generated `extern crate` items have a dummy span. // compiler-generated `extern crate` items have a dummy span.
// `std` is still checked for the `restricted-std` feature. // `std` is still checked for the `restricted-std` feature.
if item.span.is_dummy() && item.ident.name != sym::std { if item.span.is_dummy() && ident.name != sym::std {
return; return;
} }

View file

@ -574,7 +574,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
// privacy and mark them reachable. // privacy and mark them reachable.
DefKind::Macro(_) => { DefKind::Macro(_) => {
let item = self.tcx.hir_expect_item(def_id); let item = self.tcx.hir_expect_item(def_id);
if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }, _) = item.kind { if let hir::ItemKind::Macro(_, MacroDef { macro_rules: false, .. }, _) = item.kind {
if vis.is_accessible_from(module, self.tcx) { if vis.is_accessible_from(module, self.tcx) {
self.update(def_id, macro_ev, Level::Reachable); self.update(def_id, macro_ev, Level::Reachable);
} }
@ -598,8 +598,8 @@ impl<'tcx> EmbargoVisitor<'tcx> {
DefKind::Struct | DefKind::Union => { DefKind::Struct | DefKind::Union => {
// While structs and unions have type privacy, their fields do not. // While structs and unions have type privacy, their fields do not.
let item = self.tcx.hir_expect_item(def_id); let item = self.tcx.hir_expect_item(def_id);
if let hir::ItemKind::Struct(ref struct_def, _) if let hir::ItemKind::Struct(_, ref struct_def, _)
| hir::ItemKind::Union(ref struct_def, _) = item.kind | hir::ItemKind::Union(_, ref struct_def, _) = item.kind
{ {
for field in struct_def.fields() { for field in struct_def.fields() {
let field_vis = self.tcx.local_visibility(field.def_id); let field_vis = self.tcx.local_visibility(field.def_id);
@ -653,7 +653,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
| hir::ItemKind::GlobalAsm { .. } => {} | hir::ItemKind::GlobalAsm { .. } => {}
// The interface is empty, and all nested items are processed by `visit_item`. // The interface is empty, and all nested items are processed by `visit_item`.
hir::ItemKind::Mod(..) => {} hir::ItemKind::Mod(..) => {}
hir::ItemKind::Macro(macro_def, _) => { hir::ItemKind::Macro(_, macro_def, _) => {
if let Some(item_ev) = item_ev { if let Some(item_ev) = item_ev {
self.update_reachability_from_macro(item.owner_id.def_id, macro_def, item_ev); self.update_reachability_from_macro(item.owner_id.def_id, macro_def, item_ev);
} }
@ -724,7 +724,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
} }
} }
} }
hir::ItemKind::Enum(ref def, _) => { hir::ItemKind::Enum(_, ref def, _) => {
if let Some(item_ev) = item_ev { if let Some(item_ev) = item_ev {
self.reach(item.owner_id.def_id, item_ev).generics().predicates(); self.reach(item.owner_id.def_id, item_ev).generics().predicates();
} }
@ -762,7 +762,8 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
} }
} }
} }
hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => { hir::ItemKind::Struct(_, ref struct_def, _)
| hir::ItemKind::Union(_, ref struct_def, _) => {
if let Some(item_ev) = item_ev { if let Some(item_ev) = item_ev {
self.reach(item.owner_id.def_id, item_ev).generics().predicates(); self.reach(item.owner_id.def_id, item_ev).generics().predicates();
for field in struct_def.fields() { for field in struct_def.fields() {
@ -866,7 +867,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TestReachabilityVisitor<'a, 'tcx> {
self.effective_visibility_diagnostic(item.owner_id.def_id); self.effective_visibility_diagnostic(item.owner_id.def_id);
match item.kind { match item.kind {
hir::ItemKind::Enum(ref def, _) => { hir::ItemKind::Enum(_, ref def, _) => {
for variant in def.variants.iter() { for variant in def.variants.iter() {
self.effective_visibility_diagnostic(variant.def_id); self.effective_visibility_diagnostic(variant.def_id);
if let Some(ctor_def_id) = variant.data.ctor_def_id() { if let Some(ctor_def_id) = variant.data.ctor_def_id() {
@ -877,7 +878,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TestReachabilityVisitor<'a, 'tcx> {
} }
} }
} }
hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => { hir::ItemKind::Struct(_, ref def, _) | hir::ItemKind::Union(_, ref def, _) => {
if let Some(ctor_def_id) = def.ctor_def_id() { if let Some(ctor_def_id) = def.ctor_def_id() {
self.effective_visibility_diagnostic(ctor_def_id); self.effective_visibility_diagnostic(ctor_def_id);
} }
@ -1636,7 +1637,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
} }
DefKind::Enum => { DefKind::Enum => {
let item = tcx.hir_item(id); let item = tcx.hir_item(id);
if let hir::ItemKind::Enum(ref def, _) = item.kind { if let hir::ItemKind::Enum(_, ref def, _) = item.kind {
self.check_unnameable(item.owner_id.def_id, effective_vis); self.check_unnameable(item.owner_id.def_id, effective_vis);
self.check(item.owner_id.def_id, item_visibility, effective_vis) self.check(item.owner_id.def_id, item_visibility, effective_vis)
@ -1674,8 +1675,8 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
// Subitems of structs and unions have their own publicity. // Subitems of structs and unions have their own publicity.
DefKind::Struct | DefKind::Union => { DefKind::Struct | DefKind::Union => {
let item = tcx.hir_item(id); let item = tcx.hir_item(id);
if let hir::ItemKind::Struct(ref struct_def, _) if let hir::ItemKind::Struct(_, ref struct_def, _)
| hir::ItemKind::Union(ref struct_def, _) = item.kind | hir::ItemKind::Union(_, ref struct_def, _) = item.kind
{ {
self.check_unnameable(item.owner_id.def_id, effective_vis); self.check_unnameable(item.owner_id.def_id, effective_vis);
self.check(item.owner_id.def_id, item_visibility, effective_vis) self.check(item.owner_id.def_id, item_visibility, effective_vis)

View file

@ -2026,7 +2026,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
} }
LetVisitor { span }.visit_body(body).break_value() LetVisitor { span }.visit_body(body).break_value()
} }
hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _, _), .. }) => { hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(_, ty, _, _), .. }) => {
Some(&ty.peel_refs().kind) Some(&ty.peel_refs().kind)
} }
_ => None, _ => None,

View file

@ -338,7 +338,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
.. ..
}, },
hir::PathSegment { hir::PathSegment {
ident: assoc_item_name, ident: assoc_item_ident,
res: Res::Def(_, item_id), res: Res::Def(_, item_id),
.. ..
}, },
@ -368,17 +368,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
if let Some(local_def_id) = data.trait_ref.def_id.as_local() if let Some(local_def_id) = data.trait_ref.def_id.as_local()
&& let hir::Node::Item(hir::Item { && let hir::Node::Item(hir::Item {
ident: trait_name, kind: hir::ItemKind::Trait(_, _, trait_ident, _, _, trait_item_refs),
kind: hir::ItemKind::Trait(_, _, _, _, trait_item_refs),
.. ..
}) = self.tcx.hir_node_by_def_id(local_def_id) }) = self.tcx.hir_node_by_def_id(local_def_id)
&& let Some(method_ref) = trait_item_refs && let Some(method_ref) = trait_item_refs
.iter() .iter()
.find(|item_ref| item_ref.ident == *assoc_item_name) .find(|item_ref| item_ref.ident == *assoc_item_ident)
{ {
err.span_label( err.span_label(
method_ref.span, method_ref.span,
format!("`{trait_name}::{assoc_item_name}` defined here"), format!("`{trait_ident}::{assoc_item_ident}` defined here"),
); );
} }

View file

@ -419,7 +419,12 @@ pub fn report_dyn_incompatibility<'tcx>(
) -> Diag<'tcx> { ) -> Diag<'tcx> {
let trait_str = tcx.def_path_str(trait_def_id); let trait_str = tcx.def_path_str(trait_def_id);
let trait_span = tcx.hir_get_if_local(trait_def_id).and_then(|node| match node { let trait_span = tcx.hir_get_if_local(trait_def_id).and_then(|node| match node {
hir::Node::Item(item) => Some(item.ident.span), hir::Node::Item(item) => match item.kind {
hir::ItemKind::Trait(_, _, ident, ..) | hir::ItemKind::TraitAlias(ident, _, _) => {
Some(ident.span)
}
_ => unreachable!(),
},
_ => None, _ => None,
}); });

View file

@ -267,8 +267,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let node = self.tcx.hir_node_by_def_id(body_id); let node = self.tcx.hir_node_by_def_id(body_id);
match node { match node {
hir::Node::Item(hir::Item { hir::Node::Item(hir::Item {
ident, kind: hir::ItemKind::Trait(_, _, ident, generics, bounds, _),
kind: hir::ItemKind::Trait(_, _, generics, bounds, _),
.. ..
}) if self_ty == self.tcx.types.self_param => { }) if self_ty == self.tcx.types.self_param => {
assert!(param_ty); assert!(param_ty);
@ -282,7 +281,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
None, None,
projection, projection,
trait_pred, trait_pred,
Some((ident, bounds)), Some((&ident, bounds)),
); );
return; return;
} }
@ -331,7 +330,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
} }
hir::Node::Item(hir::Item { hir::Node::Item(hir::Item {
kind: kind:
hir::ItemKind::Trait(_, _, generics, ..) hir::ItemKind::Trait(_, _, _, generics, ..)
| hir::ItemKind::Impl(hir::Impl { generics, .. }), | hir::ItemKind::Impl(hir::Impl { generics, .. }),
.. ..
}) if projection.is_some() => { }) if projection.is_some() => {
@ -352,15 +351,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
hir::Node::Item(hir::Item { hir::Node::Item(hir::Item {
kind: kind:
hir::ItemKind::Struct(_, generics) hir::ItemKind::Struct(_, _, generics)
| hir::ItemKind::Enum(_, generics) | hir::ItemKind::Enum(_, _, generics)
| hir::ItemKind::Union(_, generics) | hir::ItemKind::Union(_, _, generics)
| hir::ItemKind::Trait(_, _, generics, ..) | hir::ItemKind::Trait(_, _, _, generics, ..)
| hir::ItemKind::Impl(hir::Impl { generics, .. }) | hir::ItemKind::Impl(hir::Impl { generics, .. })
| hir::ItemKind::Fn { generics, .. } | hir::ItemKind::Fn { generics, .. }
| hir::ItemKind::TyAlias(_, generics) | hir::ItemKind::TyAlias(_, _, generics)
| hir::ItemKind::Const(_, generics, _) | hir::ItemKind::Const(_, _, generics, _)
| hir::ItemKind::TraitAlias(generics, _), | hir::ItemKind::TraitAlias(_, generics, _),
.. ..
}) })
| hir::Node::TraitItem(hir::TraitItem { generics, .. }) | hir::Node::TraitItem(hir::TraitItem { generics, .. })
@ -417,15 +416,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
hir::Node::Item(hir::Item { hir::Node::Item(hir::Item {
kind: kind:
hir::ItemKind::Struct(_, generics) hir::ItemKind::Struct(_, _, generics)
| hir::ItemKind::Enum(_, generics) | hir::ItemKind::Enum(_, _, generics)
| hir::ItemKind::Union(_, generics) | hir::ItemKind::Union(_, _, generics)
| hir::ItemKind::Trait(_, _, generics, ..) | hir::ItemKind::Trait(_, _, _, generics, ..)
| hir::ItemKind::Impl(hir::Impl { generics, .. }) | hir::ItemKind::Impl(hir::Impl { generics, .. })
| hir::ItemKind::Fn { generics, .. } | hir::ItemKind::Fn { generics, .. }
| hir::ItemKind::TyAlias(_, generics) | hir::ItemKind::TyAlias(_, _, generics)
| hir::ItemKind::Const(_, generics, _) | hir::ItemKind::Const(_, _, generics, _)
| hir::ItemKind::TraitAlias(generics, _), | hir::ItemKind::TraitAlias(_, generics, _),
.. ..
}) if !param_ty => { }) if !param_ty => {
// Missing generic type parameter bound. // Missing generic type parameter bound.
@ -847,7 +846,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
name.to_string() name.to_string()
} }
Some(hir::Node::Item(hir::Item { Some(hir::Node::Item(hir::Item {
ident, kind: hir::ItemKind::Fn { .. }, .. kind: hir::ItemKind::Fn { ident, .. }, ..
})) => { })) => {
err.span_label(ident.span, "consider calling this function"); err.span_label(ident.span, "consider calling this function");
ident.to_string() ident.to_string()
@ -1593,20 +1592,20 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
if let Some(typeck_results) = &self.typeck_results if let Some(typeck_results) = &self.typeck_results
&& let ty = typeck_results.expr_ty_adjusted(base) && let ty = typeck_results.expr_ty_adjusted(base)
&& let ty::FnDef(def_id, _args) = ty.kind() && let ty::FnDef(def_id, _args) = ty.kind()
&& let Some(hir::Node::Item(hir::Item { ident, span, vis_span, .. })) = && let Some(hir::Node::Item(item)) = self.tcx.hir_get_if_local(*def_id)
self.tcx.hir_get_if_local(*def_id)
{ {
let (ident, _, _, _) = item.expect_fn();
let msg = format!("alternatively, consider making `fn {ident}` asynchronous"); let msg = format!("alternatively, consider making `fn {ident}` asynchronous");
if vis_span.is_empty() { if item.vis_span.is_empty() {
err.span_suggestion_verbose( err.span_suggestion_verbose(
span.shrink_to_lo(), item.span.shrink_to_lo(),
msg, msg,
"async ", "async ",
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
); );
} else { } else {
err.span_suggestion_verbose( err.span_suggestion_verbose(
vis_span.shrink_to_hi(), item.vis_span.shrink_to_hi(),
msg, msg,
" async", " async",
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
@ -3308,8 +3307,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let mut is_auto_trait = false; let mut is_auto_trait = false;
match tcx.hir_get_if_local(data.impl_or_alias_def_id) { match tcx.hir_get_if_local(data.impl_or_alias_def_id) {
Some(Node::Item(hir::Item { Some(Node::Item(hir::Item {
kind: hir::ItemKind::Trait(is_auto, ..), kind: hir::ItemKind::Trait(is_auto, _, ident, ..),
ident,
.. ..
})) => { })) => {
// FIXME: we should do something else so that it works even on crate foreign // FIXME: we should do something else so that it works even on crate foreign

View file

@ -516,7 +516,7 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
match self.tcx.parent_hir_node(self.tcx.local_def_id_to_hir_id(anon_reg.scope)) match self.tcx.parent_hir_node(self.tcx.local_def_id_to_hir_id(anon_reg.scope))
{ {
hir::Node::Item(hir::Item { hir::Node::Item(hir::Item {
kind: hir::ItemKind::Trait(_, _, generics, ..), kind: hir::ItemKind::Trait(_, _, _, generics, ..),
.. ..
}) })
| hir::Node::Item(hir::Item { | hir::Node::Item(hir::Item {

View file

@ -125,7 +125,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
items.extend(doc.items.values().flat_map(|(item, renamed, _)| { items.extend(doc.items.values().flat_map(|(item, renamed, _)| {
// Now we actually lower the imports, skipping everything else. // Now we actually lower the imports, skipping everything else.
if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind { if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind {
let name = renamed.unwrap_or_else(|| cx.tcx.hir_name(item.hir_id())); let name = renamed.unwrap_or(kw::Empty); // using kw::Empty is a bit of a hack
clean_use_statement(item, name, path, hir::UseKind::Glob, cx, &mut inserted) clean_use_statement(item, name, path, hir::UseKind::Glob, cx, &mut inserted)
} else { } else {
// skip everything else // skip everything else
@ -1629,8 +1629,7 @@ fn first_non_private<'tcx>(
if let Some(use_def_id) = reexp.id() if let Some(use_def_id) = reexp.id()
&& let Some(local_use_def_id) = use_def_id.as_local() && let Some(local_use_def_id) = use_def_id.as_local()
&& let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(local_use_def_id) && let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(local_use_def_id)
&& !item.ident.name.is_empty() && let hir::ItemKind::Use(path, hir::UseKind::Single(_)) = item.kind
&& let hir::ItemKind::Use(path, _) = item.kind
{ {
for res in &path.res { for res in &path.res {
if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res { if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res {
@ -1775,7 +1774,7 @@ fn maybe_expand_private_type_alias<'tcx>(
} else { } else {
return None; return None;
}; };
let hir::ItemKind::TyAlias(ty, generics) = alias else { return None }; let hir::ItemKind::TyAlias(_, ty, generics) = alias else { return None };
let final_seg = &path.segments.last().expect("segments were empty"); let final_seg = &path.segments.last().expect("segments were empty");
let mut args = DefIdMap::default(); let mut args = DefIdMap::default();
@ -2794,20 +2793,24 @@ fn clean_maybe_renamed_item<'tcx>(
use hir::ItemKind; use hir::ItemKind;
let def_id = item.owner_id.to_def_id(); let def_id = item.owner_id.to_def_id();
let mut name = renamed.unwrap_or_else(|| cx.tcx.hir_name(item.hir_id())); let mut name = renamed.unwrap_or_else(|| {
// FIXME: using kw::Empty is a bit of a hack
cx.tcx.hir_opt_name(item.hir_id()).unwrap_or(kw::Empty)
});
cx.with_param_env(def_id, |cx| { cx.with_param_env(def_id, |cx| {
let kind = match item.kind { let kind = match item.kind {
ItemKind::Static(ty, mutability, body_id) => StaticItem(Static { ItemKind::Static(_, ty, mutability, body_id) => StaticItem(Static {
type_: Box::new(clean_ty(ty, cx)), type_: Box::new(clean_ty(ty, cx)),
mutability, mutability,
expr: Some(body_id), expr: Some(body_id),
}), }),
ItemKind::Const(ty, generics, body_id) => ConstantItem(Box::new(Constant { ItemKind::Const(_, ty, generics, body_id) => ConstantItem(Box::new(Constant {
generics: clean_generics(generics, cx), generics: clean_generics(generics, cx),
type_: clean_ty(ty, cx), type_: clean_ty(ty, cx),
kind: ConstantKind::Local { body: body_id, def_id }, kind: ConstantKind::Local { body: body_id, def_id },
})), })),
ItemKind::TyAlias(hir_ty, generics) => { ItemKind::TyAlias(_, hir_ty, generics) => {
*cx.current_type_aliases.entry(def_id).or_insert(0) += 1; *cx.current_type_aliases.entry(def_id).or_insert(0) += 1;
let rustdoc_ty = clean_ty(hir_ty, cx); let rustdoc_ty = clean_ty(hir_ty, cx);
let type_ = let type_ =
@ -2840,34 +2843,34 @@ fn clean_maybe_renamed_item<'tcx>(
)); ));
return ret; return ret;
} }
ItemKind::Enum(ref def, generics) => EnumItem(Enum { ItemKind::Enum(_, ref def, generics) => EnumItem(Enum {
variants: def.variants.iter().map(|v| clean_variant(v, cx)).collect(), variants: def.variants.iter().map(|v| clean_variant(v, cx)).collect(),
generics: clean_generics(generics, cx), generics: clean_generics(generics, cx),
}), }),
ItemKind::TraitAlias(generics, bounds) => TraitAliasItem(TraitAlias { ItemKind::TraitAlias(_, generics, bounds) => TraitAliasItem(TraitAlias {
generics: clean_generics(generics, cx), generics: clean_generics(generics, cx),
bounds: bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(), bounds: bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(),
}), }),
ItemKind::Union(ref variant_data, generics) => UnionItem(Union { ItemKind::Union(_, ref variant_data, generics) => UnionItem(Union {
generics: clean_generics(generics, cx), generics: clean_generics(generics, cx),
fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(), fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(),
}), }),
ItemKind::Struct(ref variant_data, generics) => StructItem(Struct { ItemKind::Struct(_, ref variant_data, generics) => StructItem(Struct {
ctor_kind: variant_data.ctor_kind(), ctor_kind: variant_data.ctor_kind(),
generics: clean_generics(generics, cx), generics: clean_generics(generics, cx),
fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(), fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(),
}), }),
ItemKind::Impl(impl_) => return clean_impl(impl_, item.owner_id.def_id, cx), ItemKind::Impl(impl_) => return clean_impl(impl_, item.owner_id.def_id, cx),
ItemKind::Macro(macro_def, MacroKind::Bang) => MacroItem(Macro { ItemKind::Macro(_, macro_def, MacroKind::Bang) => MacroItem(Macro {
source: display_macro_source(cx, name, macro_def), source: display_macro_source(cx, name, macro_def),
macro_rules: macro_def.macro_rules, macro_rules: macro_def.macro_rules,
}), }),
ItemKind::Macro(_, macro_kind) => clean_proc_macro(item, &mut name, macro_kind, cx), ItemKind::Macro(_, _, macro_kind) => clean_proc_macro(item, &mut name, macro_kind, cx),
// proc macros can have a name set by attributes // proc macros can have a name set by attributes
ItemKind::Fn { ref sig, generics, body: body_id, .. } => { ItemKind::Fn { ref sig, generics, body: body_id, .. } => {
clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx) clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
} }
ItemKind::Trait(_, _, generics, bounds, item_ids) => { ItemKind::Trait(_, _, _, generics, bounds, item_ids) => {
let items = item_ids let items = item_ids
.iter() .iter()
.map(|ti| clean_trait_item(cx.tcx.hir_trait_item(ti.id), cx)) .map(|ti| clean_trait_item(cx.tcx.hir_trait_item(ti.id), cx))
@ -2880,7 +2883,7 @@ fn clean_maybe_renamed_item<'tcx>(
bounds: bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(), bounds: bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(),
})) }))
} }
ItemKind::ExternCrate(orig_name) => { ItemKind::ExternCrate(orig_name, _) => {
return clean_extern_crate(item, name, orig_name, cx); return clean_extern_crate(item, name, orig_name, cx);
} }
ItemKind::Use(path, kind) => { ItemKind::Use(path, kind) => {

View file

@ -226,7 +226,7 @@ impl ExternalCrate {
.filter_map(|&id| { .filter_map(|&id| {
let item = tcx.hir_item(id); let item = tcx.hir_item(id);
match item.kind { match item.kind {
hir::ItemKind::Mod(_) => { hir::ItemKind::Mod(..) => {
as_keyword(Res::Def(DefKind::Mod, id.owner_id.to_def_id())) as_keyword(Res::Def(DefKind::Mod, id.owner_id.to_def_id()))
} }
_ => None, _ => None,
@ -282,7 +282,7 @@ impl ExternalCrate {
.filter_map(|&id| { .filter_map(|&id| {
let item = tcx.hir_item(id); let item = tcx.hir_item(id);
match item.kind { match item.kind {
hir::ItemKind::Mod(_) => { hir::ItemKind::Mod(..) => {
as_primitive(Res::Def(DefKind::Mod, id.owner_id.to_def_id())) as_primitive(Res::Def(DefKind::Mod, id.owner_id.to_def_id()))
} }
_ => None, _ => None,

View file

@ -80,7 +80,7 @@ impl<'tcx> HirCollector<'tcx> {
pub fn collect_crate(mut self) -> Vec<ScrapedDocTest> { pub fn collect_crate(mut self) -> Vec<ScrapedDocTest> {
let tcx = self.tcx; let tcx = self.tcx;
self.visit_testable("".to_string(), CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID), |this| { self.visit_testable(None, CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID), |this| {
tcx.hir_walk_toplevel_module(this) tcx.hir_walk_toplevel_module(this)
}); });
self.collector.tests self.collector.tests
@ -90,7 +90,7 @@ impl<'tcx> HirCollector<'tcx> {
impl HirCollector<'_> { impl HirCollector<'_> {
fn visit_testable<F: FnOnce(&mut Self)>( fn visit_testable<F: FnOnce(&mut Self)>(
&mut self, &mut self,
name: String, name: Option<String>,
def_id: LocalDefId, def_id: LocalDefId,
sp: Span, sp: Span,
nested: F, nested: F,
@ -103,9 +103,10 @@ impl HirCollector<'_> {
return; return;
} }
let has_name = !name.is_empty(); let mut has_name = false;
if has_name { if let Some(name) = name {
self.collector.cur_path.push(name); self.collector.cur_path.push(name);
has_name = true;
} }
// The collapse-docs pass won't combine sugared/raw doc attributes, or included files with // The collapse-docs pass won't combine sugared/raw doc attributes, or included files with
@ -153,9 +154,9 @@ impl<'tcx> intravisit::Visitor<'tcx> for HirCollector<'tcx> {
fn visit_item(&mut self, item: &'tcx hir::Item<'_>) { fn visit_item(&mut self, item: &'tcx hir::Item<'_>) {
let name = match &item.kind { let name = match &item.kind {
hir::ItemKind::Impl(impl_) => { hir::ItemKind::Impl(impl_) => {
rustc_hir_pretty::id_to_string(&self.tcx, impl_.self_ty.hir_id) Some(rustc_hir_pretty::id_to_string(&self.tcx, impl_.self_ty.hir_id))
} }
_ => item.ident.to_string(), _ => item.kind.ident().map(|ident| ident.to_string()),
}; };
self.visit_testable(name, item.owner_id.def_id, item.span, |this| { self.visit_testable(name, item.owner_id.def_id, item.span, |this| {
@ -164,31 +165,46 @@ impl<'tcx> intravisit::Visitor<'tcx> for HirCollector<'tcx> {
} }
fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem<'_>) { fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem<'_>) {
self.visit_testable(item.ident.to_string(), item.owner_id.def_id, item.span, |this| { self.visit_testable(
Some(item.ident.to_string()),
item.owner_id.def_id,
item.span,
|this| {
intravisit::walk_trait_item(this, item); intravisit::walk_trait_item(this, item);
}); },
);
} }
fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem<'_>) { fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem<'_>) {
self.visit_testable(item.ident.to_string(), item.owner_id.def_id, item.span, |this| { self.visit_testable(
Some(item.ident.to_string()),
item.owner_id.def_id,
item.span,
|this| {
intravisit::walk_impl_item(this, item); intravisit::walk_impl_item(this, item);
}); },
);
} }
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'_>) { fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'_>) {
self.visit_testable(item.ident.to_string(), item.owner_id.def_id, item.span, |this| { self.visit_testable(
Some(item.ident.to_string()),
item.owner_id.def_id,
item.span,
|this| {
intravisit::walk_foreign_item(this, item); intravisit::walk_foreign_item(this, item);
}); },
);
} }
fn visit_variant(&mut self, v: &'tcx hir::Variant<'_>) { fn visit_variant(&mut self, v: &'tcx hir::Variant<'_>) {
self.visit_testable(v.ident.to_string(), v.def_id, v.span, |this| { self.visit_testable(Some(v.ident.to_string()), v.def_id, v.span, |this| {
intravisit::walk_variant(this, v); intravisit::walk_variant(this, v);
}); });
} }
fn visit_field_def(&mut self, f: &'tcx hir::FieldDef<'_>) { fn visit_field_def(&mut self, f: &'tcx hir::FieldDef<'_>) {
self.visit_testable(f.ident.to_string(), f.def_id, f.span, |this| { self.visit_testable(Some(f.ident.to_string()), f.def_id, f.span, |this| {
intravisit::walk_field_def(this, f); intravisit::walk_field_def(this, f);
}); });
} }

View file

@ -242,10 +242,9 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
// Now that we confirmed it's a file import, we want to get the span for the module // Now that we confirmed it's a file import, we want to get the span for the module
// name only and not all the "mod foo;". // name only and not all the "mod foo;".
if let Node::Item(item) = self.tcx.hir_node(id) { if let Node::Item(item) = self.tcx.hir_node(id) {
self.matches.insert( let (ident, _) = item.expect_mod();
item.ident.span, self.matches
LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)), .insert(ident.span, LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)));
);
} }
} else { } else {
// If it's a "mod foo {}", we want to look to its documentation page. // If it's a "mod foo {}", we want to look to its documentation page.
@ -273,22 +272,22 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
fn visit_item(&mut self, item: &'tcx Item<'tcx>) { fn visit_item(&mut self, item: &'tcx Item<'tcx>) {
match item.kind { match item.kind {
ItemKind::Static(..) ItemKind::Static(..)
| ItemKind::Const(_, _, _) | ItemKind::Const(..)
| ItemKind::Fn { .. } | ItemKind::Fn { .. }
| ItemKind::Macro(_, _) | ItemKind::Macro(..)
| ItemKind::TyAlias(_, _) | ItemKind::TyAlias(..)
| ItemKind::Enum(_, _) | ItemKind::Enum(..)
| ItemKind::Struct(_, _) | ItemKind::Struct(..)
| ItemKind::Union(_, _) | ItemKind::Union(..)
| ItemKind::Trait(_, _, _, _, _) | ItemKind::Trait(..)
| ItemKind::TraitAlias(_, _) => self.extract_info_from_hir_id(item.hir_id()), | ItemKind::TraitAlias(..) => self.extract_info_from_hir_id(item.hir_id()),
ItemKind::Impl(_) ItemKind::Impl(_)
| ItemKind::Use(_, _) | ItemKind::Use(..)
| ItemKind::ExternCrate(_) | ItemKind::ExternCrate(..)
| ItemKind::ForeignMod { .. } | ItemKind::ForeignMod { .. }
| ItemKind::GlobalAsm { .. } | ItemKind::GlobalAsm { .. }
// We already have "visit_mod" above so no need to check it here. // We already have "visit_mod" above so no need to check it here.
| ItemKind::Mod(_) => {} | ItemKind::Mod(..) => {}
} }
intravisit::walk_item(self, item); intravisit::walk_item(self, item);
} }

View file

@ -240,7 +240,7 @@ impl DocVisitor<'_> for CoverageCalculator<'_, '_> {
data: hir::VariantData::Tuple(_, _, _), data: hir::VariantData::Tuple(_, _, _),
.. ..
}) | hir::Node::Item(hir::Item { }) | hir::Node::Item(hir::Item {
kind: hir::ItemKind::Struct(hir::VariantData::Tuple(_, _, _), _), kind: hir::ItemKind::Struct(_, hir::VariantData::Tuple(_, _, _), _),
.. ..
}) })
) )

View file

@ -144,9 +144,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
&& inserted.insert(def_id) && inserted.insert(def_id)
{ {
let item = self.cx.tcx.hir_expect_item(local_def_id); let item = self.cx.tcx.hir_expect_item(local_def_id);
top_level_module let (ident, _, _) = item.expect_macro();
.items top_level_module.items.insert((local_def_id, Some(ident.name)), (item, None, None));
.insert((local_def_id, Some(item.ident.name)), (item, None, None));
} }
} }
@ -224,11 +223,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
def_id: LocalDefId, def_id: LocalDefId,
res: Res, res: Res,
renamed: Option<Symbol>, renamed: Option<Symbol>,
glob: bool,
please_inline: bool, please_inline: bool,
) -> bool { ) -> bool {
debug!("maybe_inline_local (renamed: {renamed:?}) res: {res:?}"); debug!("maybe_inline_local (renamed: {renamed:?}) res: {res:?}");
let glob = renamed.is_none();
if renamed == Some(kw::Underscore) { if renamed == Some(kw::Underscore) {
// We never inline `_` reexports. // We never inline `_` reexports.
return false; return false;
@ -286,7 +285,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
is_hidden && is_hidden &&
// If it's a doc hidden module, we need to keep it in case some of its inner items // If it's a doc hidden module, we need to keep it in case some of its inner items
// are re-exported. // are re-exported.
!matches!(item, Node::Item(&hir::Item { kind: hir::ItemKind::Mod(_), .. })) !matches!(item, Node::Item(&hir::Item { kind: hir::ItemKind::Mod(..), .. }))
) || ) ||
// The imported item is public and not `doc(hidden)` so no need to inline it. // The imported item is public and not `doc(hidden)` so no need to inline it.
self.reexport_public_and_not_hidden(def_id, res_did) self.reexport_public_and_not_hidden(def_id, res_did)
@ -297,7 +296,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
let is_bang_macro = matches!( let is_bang_macro = matches!(
item, item,
Node::Item(&hir::Item { kind: hir::ItemKind::Macro(_, MacroKind::Bang), .. }) Node::Item(&hir::Item { kind: hir::ItemKind::Macro(_, _, MacroKind::Bang), .. })
); );
if !self.view_item_stack.insert(res_did) && !is_bang_macro { if !self.view_item_stack.insert(res_did) && !is_bang_macro {
@ -311,7 +310,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
Node::Item(_) if is_bang_macro && !please_inline && renamed.is_some() && is_hidden => { Node::Item(_) if is_bang_macro && !please_inline && renamed.is_some() && is_hidden => {
return false; return false;
} }
Node::Item(&hir::Item { kind: hir::ItemKind::Mod(m), .. }) if glob => { Node::Item(&hir::Item { kind: hir::ItemKind::Mod(_, m), .. }) if glob => {
let prev = mem::replace(&mut self.inlining, true); let prev = mem::replace(&mut self.inlining, true);
for &i in m.item_ids { for &i in m.item_ids {
let i = tcx.hir_item(i); let i = tcx.hir_item(i);
@ -378,7 +377,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
// attribute can still be visible. // attribute can still be visible.
|| match item.kind { || match item.kind {
hir::ItemKind::Impl(..) => true, hir::ItemKind::Impl(..) => true,
hir::ItemKind::Macro(_, MacroKind::Bang) => { hir::ItemKind::Macro(_, _, MacroKind::Bang) => {
self.cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) self.cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export)
} }
_ => false, _ => false,
@ -419,7 +418,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
} }
return; return;
} }
let name = renamed.unwrap_or(item.ident.name); let get_name = || renamed.unwrap_or(item.kind.ident().unwrap().name);
let tcx = self.cx.tcx; let tcx = self.cx.tcx;
let def_id = item.owner_id.to_def_id(); let def_id = item.owner_id.to_def_id();
@ -459,15 +458,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
} }
_ => false, _ => false,
}); });
let is_glob = kind == hir::UseKind::Glob; let ident = match kind {
let ident = if is_glob { None } else { Some(name) }; hir::UseKind::Single(ident) => Some(renamed.unwrap_or(ident.name)),
if self.maybe_inline_local( hir::UseKind::Glob => None,
item.owner_id.def_id, hir::UseKind::ListStem => unreachable!(),
res, };
ident, if self.maybe_inline_local(item.owner_id.def_id, res, ident, please_inline)
is_glob, {
please_inline,
) {
debug!("Inlining {:?}", item.owner_id.def_id); debug!("Inlining {:?}", item.owner_id.def_id);
continue; continue;
} }
@ -475,7 +472,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
self.add_to_current_mod(item, renamed, import_id); self.add_to_current_mod(item, renamed, import_id);
} }
} }
hir::ItemKind::Macro(macro_def, _) => { hir::ItemKind::Macro(_, macro_def, _) => {
// `#[macro_export] macro_rules!` items are handled separately in `visit()`, // `#[macro_export] macro_rules!` items are handled separately in `visit()`,
// above, since they need to be documented at the module top level. Accordingly, // above, since they need to be documented at the module top level. Accordingly,
// we only want to handle macros if one of three conditions holds: // we only want to handle macros if one of three conditions holds:
@ -495,8 +492,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
self.add_to_current_mod(item, renamed, import_id); self.add_to_current_mod(item, renamed, import_id);
} }
} }
hir::ItemKind::Mod(m) => { hir::ItemKind::Mod(_, m) => {
self.enter_mod(item.owner_id.def_id, m, name, renamed, import_id); self.enter_mod(item.owner_id.def_id, m, get_name(), renamed, import_id);
} }
hir::ItemKind::Fn { .. } hir::ItemKind::Fn { .. }
| hir::ItemKind::ExternCrate(..) | hir::ItemKind::ExternCrate(..)
@ -512,7 +509,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
hir::ItemKind::Const(..) => { hir::ItemKind::Const(..) => {
// Underscore constants do not correspond to a nameable item and // Underscore constants do not correspond to a nameable item and
// so are never useful in documentation. // so are never useful in documentation.
if name != kw::Underscore { if get_name() != kw::Underscore {
self.add_to_current_mod(item, renamed, import_id); self.add_to_current_mod(item, renamed, import_id);
} }
} }

View file

@ -5,7 +5,7 @@ use clippy_config::types::{
}; };
use clippy_utils::diagnostics::span_lint_and_note; use clippy_utils::diagnostics::span_lint_and_note;
use rustc_hir::{ use rustc_hir::{
AssocItemKind, FieldDef, HirId, ImplItemRef, IsAuto, Item, ItemKind, Mod, QPath, TraitItemRef, TyKind, UseKind, AssocItemKind, FieldDef, HirId, ImplItemRef, IsAuto, Item, ItemKind, Mod, QPath, TraitItemRef, TyKind,
Variant, VariantData, Variant, VariantData,
}; };
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
@ -178,8 +178,8 @@ impl ArbitrarySourceItemOrdering {
/// Produces a linting warning for incorrectly ordered item members. /// Produces a linting warning for incorrectly ordered item members.
fn lint_member_name<T: LintContext>( fn lint_member_name<T: LintContext>(
cx: &T, cx: &T,
ident: &rustc_span::symbol::Ident, ident: &rustc_span::Ident,
before_ident: &rustc_span::symbol::Ident, before_ident: &rustc_span::Ident,
) { ) {
span_lint_and_note( span_lint_and_note(
cx, cx,
@ -192,21 +192,21 @@ impl ArbitrarySourceItemOrdering {
} }
fn lint_member_item<T: LintContext>(cx: &T, item: &Item<'_>, before_item: &Item<'_>) { fn lint_member_item<T: LintContext>(cx: &T, item: &Item<'_>, before_item: &Item<'_>) {
let span = if item.ident.as_str().is_empty() { let span = if let Some(ident) = item.kind.ident() {
&item.span ident.span
} else { } else {
&item.ident.span item.span
}; };
let (before_span, note) = if before_item.ident.as_str().is_empty() { let (before_span, note) = if let Some(ident) = before_item.kind.ident() {
( (
&before_item.span, ident.span,
"should be placed before the following item".to_owned(), format!("should be placed before `{}`", ident.as_str(),),
) )
} else { } else {
( (
&before_item.ident.span, before_item.span,
format!("should be placed before `{}`", before_item.ident.as_str(),), "should be placed before the following item".to_owned(),
) )
}; };
@ -218,9 +218,9 @@ impl ArbitrarySourceItemOrdering {
span_lint_and_note( span_lint_and_note(
cx, cx,
ARBITRARY_SOURCE_ITEM_ORDERING, ARBITRARY_SOURCE_ITEM_ORDERING,
*span, span,
"incorrect ordering of items (must be alphabetically ordered)", "incorrect ordering of items (must be alphabetically ordered)",
Some(*before_span), Some(before_span),
note, note,
); );
} }
@ -244,7 +244,7 @@ impl ArbitrarySourceItemOrdering {
impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
match &item.kind { match &item.kind {
ItemKind::Enum(enum_def, _generics) if self.enable_ordering_for_enum => { ItemKind::Enum(_, enum_def, _generics) if self.enable_ordering_for_enum => {
let mut cur_v: Option<&Variant<'_>> = None; let mut cur_v: Option<&Variant<'_>> = None;
for variant in enum_def.variants { for variant in enum_def.variants {
if variant.span.in_external_macro(cx.sess().source_map()) { if variant.span.in_external_macro(cx.sess().source_map()) {
@ -259,7 +259,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
cur_v = Some(variant); cur_v = Some(variant);
} }
}, },
ItemKind::Struct(VariantData::Struct { fields, .. }, _generics) if self.enable_ordering_for_struct => { ItemKind::Struct(_, VariantData::Struct { fields, .. }, _generics) if self.enable_ordering_for_struct => {
let mut cur_f: Option<&FieldDef<'_>> = None; let mut cur_f: Option<&FieldDef<'_>> = None;
for field in *fields { for field in *fields {
if field.span.in_external_macro(cx.sess().source_map()) { if field.span.in_external_macro(cx.sess().source_map()) {
@ -274,7 +274,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
cur_f = Some(field); cur_f = Some(field);
} }
}, },
ItemKind::Trait(is_auto, _safety, _generics, _generic_bounds, item_ref) ItemKind::Trait(is_auto, _safety, _ident, _generics, _generic_bounds, item_ref)
if self.enable_ordering_for_trait && *is_auto == IsAuto::No => if self.enable_ordering_for_trait && *is_auto == IsAuto::No =>
{ {
let mut cur_t: Option<&TraitItemRef> = None; let mut cur_t: Option<&TraitItemRef> = None;
@ -351,50 +351,24 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
continue; continue;
} }
// The following exceptions (skipping with `continue;`) may not be let ident = if let Some(ident) = item.kind.ident() {
// complete, edge cases have not been explored further than what ident
// appears in the existing code base. } else if let ItemKind::Impl(_) = item.kind
if item.ident.name == rustc_span::symbol::kw::Empty { && !get_item_name(item).is_empty()
if let ItemKind::Impl(_) = item.kind {
// Sorting trait impls for unnamed types makes no sense.
if get_item_name(item).is_empty() {
continue;
}
} else if let ItemKind::ForeignMod { .. } = item.kind {
continue;
} else if let ItemKind::GlobalAsm { .. } = item.kind {
continue;
} else if let ItemKind::Use(path, use_kind) = item.kind {
if path.segments.is_empty() {
// Use statements that contain braces get caught here.
// They will still be linted internally.
continue;
} else if path.segments.len() >= 2
&& (path.segments[0].ident.name == rustc_span::sym::std
|| path.segments[0].ident.name == rustc_span::sym::core)
&& path.segments[1].ident.name == rustc_span::sym::prelude
{ {
// Filters the autogenerated prelude use statement. rustc_span::Ident::empty() // FIXME: a bit strange, is there a better way to do it?
// e.g. `use std::prelude::rustc_2021`
} else if use_kind == UseKind::Glob {
// Filters glob kinds of uses.
// e.g. `use std::sync::*`
} else { } else {
// This can be used for debugging.
// println!("Unknown autogenerated use statement: {:?}", item);
}
continue; continue;
} };
}
if item.ident.name.as_str().starts_with('_') { if ident.name.as_str().starts_with('_') {
// Filters out unnamed macro-like impls for various derives, // Filters out unnamed macro-like impls for various derives,
// e.g. serde::Serialize or num_derive::FromPrimitive. // e.g. serde::Serialize or num_derive::FromPrimitive.
continue; continue;
} }
if item.ident.name == rustc_span::sym::std && item.span.is_dummy() { if ident.name == rustc_span::sym::std && item.span.is_dummy() {
if let ItemKind::ExternCrate(None) = item.kind { if let ItemKind::ExternCrate(None, _) = item.kind {
// Filters the auto-included Rust standard library. // Filters the auto-included Rust standard library.
continue; continue;
} }
@ -525,6 +499,8 @@ fn get_item_name(item: &Item<'_>) -> String {
String::new() String::new()
} }
}, },
_ => item.ident.name.as_str().to_owned(), // FIXME: `Ident::empty` for anonymous items is a bit strange, is there
// a better way to do it?
_ => item.kind.ident().unwrap_or(rustc_span::Ident::empty()).name.as_str().to_owned(),
} }
} }

View file

@ -16,7 +16,7 @@ mod utils;
use clippy_config::Conf; use clippy_config::Conf;
use clippy_utils::msrvs::{self, Msrv, MsrvStack}; use clippy_utils::msrvs::{self, Msrv, MsrvStack};
use rustc_ast::{self as ast, Attribute, MetaItemInner, MetaItemKind}; use rustc_ast::{self as ast, Attribute, MetaItemInner, MetaItemKind};
use rustc_hir::{ImplItem, Item, TraitItem}; use rustc_hir::{ImplItem, Item, ItemKind, TraitItem};
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
use rustc_session::impl_lint_pass; use rustc_session::impl_lint_pass;
use rustc_span::sym; use rustc_span::sym;
@ -466,8 +466,8 @@ impl Attributes {
impl<'tcx> LateLintPass<'tcx> for Attributes { impl<'tcx> LateLintPass<'tcx> for Attributes {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
let attrs = cx.tcx.hir_attrs(item.hir_id()); let attrs = cx.tcx.hir_attrs(item.hir_id());
if is_relevant_item(cx, item) { if let ItemKind::Fn { ident, .. } = item.kind && is_relevant_item(cx, item) {
inline_always::check(cx, item.span, item.ident.name, attrs); inline_always::check(cx, item.span, ident.name, attrs);
} }
repr_attributes::check(cx, item.span, attrs, self.msrv); repr_attributes::check(cx, item.span, attrs, self.msrv);
} }

View file

@ -99,7 +99,7 @@ impl_lint_pass!(DisallowedTypes => [DISALLOWED_TYPES]);
impl<'tcx> LateLintPass<'tcx> for DisallowedTypes { impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {
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 ItemKind::Use(path, UseKind::Single) = &item.kind { if let ItemKind::Use(path, UseKind::Single(_)) = &item.kind {
for res in &path.res { for res in &path.res {
self.check_res_emit(cx, res, item.span); self.check_res_emit(cx, res, item.span);
} }

View file

@ -38,7 +38,7 @@ impl<'tcx> LateLintPass<'tcx> for UnportableVariant {
if cx.tcx.data_layout.pointer_size.bits() != 64 { if cx.tcx.data_layout.pointer_size.bits() != 64 {
return; return;
} }
if let ItemKind::Enum(def, _) = &item.kind { if let ItemKind::Enum(_, def, _) = &item.kind {
for var in def.variants { for var in def.variants {
if let Some(anon_const) = &var.disr_expr { if let Some(anon_const) = &var.disr_expr {
let def_id = cx.tcx.hir_body_owner_def_id(anon_const.body); let def_id = cx.tcx.hir_body_owner_def_id(anon_const.body);

View file

@ -37,8 +37,8 @@ declare_lint_pass!(ErrorImplError => [ERROR_IMPL_ERROR]);
impl<'tcx> LateLintPass<'tcx> for ErrorImplError { impl<'tcx> LateLintPass<'tcx> for ErrorImplError {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
match item.kind { match item.kind {
ItemKind::TyAlias(..) ItemKind::TyAlias(ident, ..)
if item.ident.name == sym::Error if ident.name == sym::Error
&& is_visible_outside_module(cx, item.owner_id.def_id) && is_visible_outside_module(cx, item.owner_id.def_id)
&& let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
&& let Some(error_def_id) = cx.tcx.get_diagnostic_item(sym::Error) && let Some(error_def_id) = cx.tcx.get_diagnostic_item(sym::Error)
@ -47,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for ErrorImplError {
span_lint( span_lint(
cx, cx,
ERROR_IMPL_ERROR, ERROR_IMPL_ERROR,
item.ident.span, ident.span,
"exported type alias named `Error` that implements `Error`", "exported type alias named `Error` that implements `Error`",
); );
}, },

View file

@ -91,7 +91,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
} }
// find `self` ty for this trait if relevant // find `self` ty for this trait if relevant
if let ItemKind::Trait(_, _, _, _, items) = item.kind { if let ItemKind::Trait(_, _, _, _, _, items) = item.kind {
for trait_item in items { for trait_item in items {
if trait_item.id.owner_id.def_id == fn_def_id { if trait_item.id.owner_id.def_id == fn_def_id {
// be sure we have `self` parameter in this function // be sure we have `self` parameter in this function

View file

@ -122,7 +122,7 @@ fn check_fn_decl(cx: &LateContext<'_>, decl: &FnDecl<'_>, sp: Span, max: u64) {
impl<'tcx> LateLintPass<'tcx> for ExcessiveBools { impl<'tcx> LateLintPass<'tcx> for ExcessiveBools {
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 ItemKind::Struct(variant_data, _) = &item.kind if let ItemKind::Struct(_, variant_data, _) = &item.kind
&& variant_data.fields().len() as u64 > self.max_struct_bools && variant_data.fields().len() as u64 > self.max_struct_bools
&& has_n_bools( && has_n_bools(
variant_data.fields().iter().map(|field| field.ty), variant_data.fields().iter().map(|field| field.ty),

View file

@ -76,7 +76,7 @@ impl LateLintPass<'_> for ExhaustiveItems {
"exported enums should not be exhaustive", "exported enums should not be exhaustive",
[].as_slice(), [].as_slice(),
), ),
ItemKind::Struct(v, ..) => ( ItemKind::Struct(_, v, ..) => (
EXHAUSTIVE_STRUCTS, EXHAUSTIVE_STRUCTS,
"exported structs should not be exhaustive", "exported structs should not be exhaustive",
v.fields(), v.fields(),

View file

@ -103,7 +103,7 @@ fn check_result_large_err<'tcx>(cx: &LateContext<'tcx>, err_ty: Ty<'tcx>, hir_ty
.did() .did()
.as_local() .as_local()
&& let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(local_def_id) && let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(local_def_id)
&& let hir::ItemKind::Enum(ref def, _) = item.kind && let hir::ItemKind::Enum(_, ref def, _) = item.kind
{ {
let variants_size = AdtVariantInfo::new(cx, *adt, subst); let variants_size = AdtVariantInfo::new(cx, *adt, subst);
if let Some((first_variant, variants)) = variants_size.split_first() if let Some((first_variant, variants)) = variants_size.split_first()

View file

@ -8,7 +8,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_hir::{EnumDef, FieldDef, Item, ItemKind, OwnerId, Variant, VariantData}; use rustc_hir::{EnumDef, FieldDef, Item, ItemKind, OwnerId, Variant, VariantData};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::impl_lint_pass; use rustc_session::impl_lint_pass;
use rustc_span::Span; use rustc_span::{Ident, Span};
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
declare_clippy_lint! { declare_clippy_lint! {
@ -196,16 +196,16 @@ fn have_no_extra_prefix(prefixes: &[&str]) -> bool {
prefixes.iter().all(|p| p == &"" || p == &"_") prefixes.iter().all(|p| p == &"" || p == &"_")
} }
fn check_fields(cx: &LateContext<'_>, threshold: u64, item: &Item<'_>, fields: &[FieldDef<'_>]) { fn check_fields(cx: &LateContext<'_>, threshold: u64, ident: Ident, span: Span, fields: &[FieldDef<'_>]) {
if (fields.len() as u64) < threshold { if (fields.len() as u64) < threshold {
return; return;
} }
check_struct_name_repetition(cx, item, fields); check_struct_name_repetition(cx, ident, fields);
// if the SyntaxContext of the identifiers of the fields and struct differ dont lint them. // if the SyntaxContext of the identifiers of the fields and struct differ dont lint them.
// this prevents linting in macros in which the location of the field identifier names differ // this prevents linting in macros in which the location of the field identifier names differ
if !fields.iter().all(|field| item.ident.span.eq_ctxt(field.ident.span)) { if !fields.iter().all(|field| ident.span.eq_ctxt(field.ident.span)) {
return; return;
} }
@ -256,7 +256,7 @@ fn check_fields(cx: &LateContext<'_>, threshold: u64, item: &Item<'_>, fields: &
span_lint_and_help( span_lint_and_help(
cx, cx,
STRUCT_FIELD_NAMES, STRUCT_FIELD_NAMES,
item.span, span,
format!("all fields have the same {what}fix: `{value}`"), format!("all fields have the same {what}fix: `{value}`"),
None, None,
format!("remove the {what}fixes"), format!("remove the {what}fixes"),
@ -264,11 +264,11 @@ fn check_fields(cx: &LateContext<'_>, threshold: u64, item: &Item<'_>, fields: &
} }
} }
fn check_struct_name_repetition(cx: &LateContext<'_>, item: &Item<'_>, fields: &[FieldDef<'_>]) { fn check_struct_name_repetition(cx: &LateContext<'_>, ident: Ident, fields: &[FieldDef<'_>]) {
let snake_name = to_snake_case(item.ident.name.as_str()); let snake_name = to_snake_case(ident.name.as_str());
let item_name_words: Vec<&str> = snake_name.split('_').collect(); let item_name_words: Vec<&str> = snake_name.split('_').collect();
for field in fields { for field in fields {
if field.ident.span.eq_ctxt(item.ident.span) { if field.ident.span.eq_ctxt(ident.span) {
//consider linting only if the field identifier has the same SyntaxContext as the item(struct) //consider linting only if the field identifier has the same SyntaxContext as the item(struct)
let field_words: Vec<&str> = field.ident.name.as_str().split('_').collect(); let field_words: Vec<&str> = field.ident.name.as_str().split('_').collect();
if field_words.len() >= item_name_words.len() { if field_words.len() >= item_name_words.len() {
@ -397,19 +397,23 @@ fn check_variant(cx: &LateContext<'_>, threshold: u64, def: &EnumDef<'_>, item_n
} }
impl LateLintPass<'_> for ItemNameRepetitions { impl LateLintPass<'_> for ItemNameRepetitions {
fn check_item_post(&mut self, _cx: &LateContext<'_>, _item: &Item<'_>) { fn check_item_post(&mut self, _cx: &LateContext<'_>, item: &Item<'_>) {
let Some(_ident) = item.kind.ident() else { return };
let last = self.modules.pop(); let last = self.modules.pop();
assert!(last.is_some()); assert!(last.is_some());
} }
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
let item_name = item.ident.name.as_str(); let Some(ident) = item.kind.ident() else { return };
let item_name = ident.name.as_str();
let item_camel = to_camel_case(item_name); let item_camel = to_camel_case(item_name);
if !item.span.from_expansion() && is_present_in_source(cx, item.span) { if !item.span.from_expansion() && is_present_in_source(cx, item.span) {
if let [.., (mod_name, mod_camel, mod_owner_id)] = &*self.modules { if let [.., (mod_name, mod_camel, mod_owner_id)] = &*self.modules {
// constants don't have surrounding modules // constants don't have surrounding modules
if !mod_camel.is_empty() { if !mod_camel.is_empty() {
if mod_name == &item.ident.name if mod_name == &ident.name
&& let ItemKind::Mod(..) = item.kind && let ItemKind::Mod(..) = item.kind
&& (!self.allow_private_module_inception || cx.tcx.visibility(mod_owner_id.def_id).is_public()) && (!self.allow_private_module_inception || cx.tcx.visibility(mod_owner_id.def_id).is_public())
{ {
@ -438,7 +442,7 @@ impl LateLintPass<'_> for ItemNameRepetitions {
Some(c) if is_word_beginning(c) => span_lint( Some(c) if is_word_beginning(c) => span_lint(
cx, cx,
MODULE_NAME_REPETITIONS, MODULE_NAME_REPETITIONS,
item.ident.span, ident.span,
"item name starts with its containing module's name", "item name starts with its containing module's name",
), ),
_ => (), _ => (),
@ -450,7 +454,7 @@ impl LateLintPass<'_> for ItemNameRepetitions {
span_lint( span_lint(
cx, cx,
MODULE_NAME_REPETITIONS, MODULE_NAME_REPETITIONS,
item.ident.span, ident.span,
"item name ends with its containing module's name", "item name ends with its containing module's name",
); );
} }
@ -462,13 +466,13 @@ impl LateLintPass<'_> for ItemNameRepetitions {
&& span_is_local(item.span) && span_is_local(item.span)
{ {
match item.kind { match item.kind {
ItemKind::Enum(def, _) => check_variant(cx, self.enum_threshold, &def, item_name, item.span), ItemKind::Enum(_, def, _) => check_variant(cx, self.enum_threshold, &def, item_name, item.span),
ItemKind::Struct(VariantData::Struct { fields, .. }, _) => { ItemKind::Struct(_, VariantData::Struct { fields, .. }, _) => {
check_fields(cx, self.struct_threshold, item, fields); check_fields(cx, self.struct_threshold, ident, item.span, fields);
}, },
_ => (), _ => (),
} }
} }
self.modules.push((item.ident.name, item_camel, item.owner_id)); self.modules.push((ident.name, item_camel, item.owner_id));
} }
} }

View file

@ -44,7 +44,7 @@ declare_clippy_lint! {
declare_lint_pass!(ItemsAfterTestModule => [ITEMS_AFTER_TEST_MODULE]); declare_lint_pass!(ItemsAfterTestModule => [ITEMS_AFTER_TEST_MODULE]);
fn cfg_test_module<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool { fn cfg_test_module<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool {
if let ItemKind::Mod(test_mod) = item.kind if let ItemKind::Mod(_, test_mod) = item.kind
&& item.span.hi() == test_mod.spans.inner_span.hi() && item.span.hi() == test_mod.spans.inner_span.hi()
&& is_cfg_test(cx.tcx, item.hir_id()) && is_cfg_test(cx.tcx, item.hir_id())
&& !item.span.from_expansion() && !item.span.from_expansion()
@ -67,14 +67,20 @@ impl LateLintPass<'_> for ItemsAfterTestModule {
let after: Vec<_> = items let after: Vec<_> = items
.filter(|item| { .filter(|item| {
// Ignore the generated test main function // Ignore the generated test main function
!(item.ident.name == sym::main if let ItemKind::Fn { ident, .. } = item.kind
&& item.span.ctxt().outer_expn_data().kind == ExpnKind::AstPass(AstPass::TestHarness)) && ident.name == sym::main
&& item.span.ctxt().outer_expn_data().kind == ExpnKind::AstPass(AstPass::TestHarness)
{
false
} else {
true
}
}) })
.collect(); .collect();
if let Some(last) = after.last() if let Some(last) = after.last()
&& after.iter().all(|&item| { && after.iter().all(|&item| {
!matches!(item.kind, ItemKind::Mod(_)) && !item.span.from_expansion() && !is_from_proc_macro(cx, item) !matches!(item.kind, ItemKind::Mod(..)) && !item.span.from_expansion() && !is_from_proc_macro(cx, item)
}) })
&& !fulfill_or_allowed(cx, ITEMS_AFTER_TEST_MODULE, after.iter().map(|item| item.hir_id())) && !fulfill_or_allowed(cx, ITEMS_AFTER_TEST_MODULE, after.iter().map(|item| item.hir_id()))
{ {

View file

@ -48,7 +48,7 @@ impl_lint_pass!(LargeConstArrays => [LARGE_CONST_ARRAYS]);
impl<'tcx> LateLintPass<'tcx> for LargeConstArrays { impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
if let ItemKind::Const(_, generics, _) = &item.kind if let ItemKind::Const(ident, _, generics, _) = &item.kind
// Since static items may not have generics, skip generic const items. // Since static items may not have generics, skip generic const items.
// FIXME(generic_const_items): I don't think checking `generics.hwcp` suffices as it // FIXME(generic_const_items): I don't think checking `generics.hwcp` suffices as it
// doesn't account for empty where-clauses that only consist of keyword `where` IINM. // doesn't account for empty where-clauses that only consist of keyword `where` IINM.
@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
&& let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()) && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())
&& u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size) && u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size)
{ {
let hi_pos = item.ident.span.lo() - BytePos::from_usize(1); let hi_pos = ident.span.lo() - BytePos::from_usize(1);
let sugg_span = Span::new( let sugg_span = Span::new(
hi_pos - BytePos::from_usize("const".len()), hi_pos - BytePos::from_usize("const".len()),
hi_pos, hi_pos,

View file

@ -73,7 +73,7 @@ impl_lint_pass!(LargeEnumVariant => [LARGE_ENUM_VARIANT]);
impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant { impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &Item<'tcx>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &Item<'tcx>) {
if let ItemKind::Enum(ref def, _) = item.kind if let ItemKind::Enum(ident, ref def, _) = item.kind
&& let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
&& let ty::Adt(adt, subst) = ty.kind() && let ty::Adt(adt, subst) = ty.kind()
&& adt.variants().len() > 1 && adt.variants().len() > 1
@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
let mut applicability = Applicability::MaybeIncorrect; let mut applicability = Applicability::MaybeIncorrect;
if is_copy(cx, ty) || maybe_copy(cx, ty) { if is_copy(cx, ty) || maybe_copy(cx, ty) {
diag.span_note( diag.span_note(
item.ident.span, ident.span,
"boxing a variant would require the type no longer be `Copy`", "boxing a variant would require the type no longer be `Copy`",
); );
} else { } else {

View file

@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
// Integer modules are "TBD" deprecated, and the contents are too, // Integer modules are "TBD" deprecated, and the contents are too,
// so lint on the `use` statement directly. // so lint on the `use` statement directly.
if let ItemKind::Use(path, kind @ (UseKind::Single | UseKind::Glob)) = item.kind if let ItemKind::Use(path, kind @ (UseKind::Single(_) | UseKind::Glob)) = item.kind
&& !item.span.in_external_macro(cx.sess().source_map()) && !item.span.in_external_macro(cx.sess().source_map())
&& let Some(def_id) = path.res[0].opt_def_id() && let Some(def_id) = path.res[0].opt_def_id()
&& self.msrv.meets(cx, msrvs::NUMERIC_ASSOCIATED_CONSTANTS) && self.msrv.meets(cx, msrvs::NUMERIC_ASSOCIATED_CONSTANTS)
@ -72,7 +72,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
"importing a legacy numeric constant" "importing a legacy numeric constant"
}, },
|diag| { |diag| {
if item.ident.name == kw::Underscore { if let UseKind::Single(ident) = kind && ident.name == kw::Underscore {
diag.help("remove this import"); diag.help("remove this import");
return; return;
} }

View file

@ -17,7 +17,7 @@ use rustc_middle::ty::{self, AssocKind, FnSig, Ty};
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol}; use rustc_span::{Ident, Span, Symbol};
use rustc_trait_selection::traits::supertrait_def_ids; use rustc_trait_selection::traits::supertrait_def_ids;
declare_clippy_lint! { declare_clippy_lint! {
@ -123,10 +123,10 @@ declare_lint_pass!(LenZero => [LEN_ZERO, LEN_WITHOUT_IS_EMPTY, COMPARISON_TO_EMP
impl<'tcx> LateLintPass<'tcx> for LenZero { impl<'tcx> LateLintPass<'tcx> for LenZero {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
if let ItemKind::Trait(_, _, _, _, trait_items) = item.kind if let ItemKind::Trait(_, _, ident, _, _, trait_items) = item.kind
&& !item.span.from_expansion() && !item.span.from_expansion()
{ {
check_trait_items(cx, item, trait_items); check_trait_items(cx, item, ident, trait_items);
} }
} }
@ -150,10 +150,10 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
let (name, kind) = match cx.tcx.hir_node(ty_hir_id) { let (name, kind) = match cx.tcx.hir_node(ty_hir_id) {
Node::ForeignItem(x) => (x.ident.name, "extern type"), Node::ForeignItem(x) => (x.ident.name, "extern type"),
Node::Item(x) => match x.kind { Node::Item(x) => match x.kind {
ItemKind::Struct(..) => (x.ident.name, "struct"), ItemKind::Struct(ident, ..) => (ident.name, "struct"),
ItemKind::Enum(..) => (x.ident.name, "enum"), ItemKind::Enum(ident, ..) => (ident.name, "enum"),
ItemKind::Union(..) => (x.ident.name, "union"), ItemKind::Union(ident, ..) => (ident.name, "union"),
_ => (x.ident.name, "type"), _ => (x.kind.ident().unwrap().name, "type"),
}, },
_ => return, _ => return,
}; };
@ -250,7 +250,7 @@ fn span_without_enclosing_paren(cx: &LateContext<'_>, span: Span) -> Span {
} }
} }
fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items: &[TraitItemRef]) { fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Ident, trait_items: &[TraitItemRef]) {
fn is_named_self(cx: &LateContext<'_>, item: &TraitItemRef, name: Symbol) -> bool { fn is_named_self(cx: &LateContext<'_>, item: &TraitItemRef, name: Symbol) -> bool {
item.ident.name == name item.ident.name == name
&& if let AssocItemKind::Fn { has_self } = item.kind { && if let AssocItemKind::Fn { has_self } = item.kind {
@ -300,7 +300,7 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items
visited_trait.span, visited_trait.span,
format!( format!(
"trait `{}` has a `len` method but no (possibly inherited) `is_empty` method", "trait `{}` has a `len` method but no (possibly inherited) `is_empty` method",
visited_trait.ident.name ident.name
), ),
); );
} }

View file

@ -87,7 +87,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive {
} }
match item.kind { match item.kind {
ItemKind::Enum(def, _) if def.variants.len() > 1 => { ItemKind::Enum(_, def, _) if def.variants.len() > 1 => {
let iter = def.variants.iter().filter_map(|v| { let iter = def.variants.iter().filter_map(|v| {
(matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir_attrs(v.hir_id))) (matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir_attrs(v.hir_id)))
.then_some((v.def_id, v.span)) .then_some((v.def_id, v.span))
@ -98,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive {
self.potential_enums.push((item.owner_id.def_id, id, item.span, span)); self.potential_enums.push((item.owner_id.def_id, id, item.span, span));
} }
}, },
ItemKind::Struct(variant_data, _) => { ItemKind::Struct(_, variant_data, _) => {
let fields = variant_data.fields(); let fields = variant_data.fields();
let private_fields = fields let private_fields = fields
.iter() .iter()

View file

@ -192,17 +192,17 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) { fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
match it.kind { match it.kind {
hir::ItemKind::Fn { .. } => { hir::ItemKind::Fn { ident, .. } => {
// ignore main() // ignore main()
if it.ident.name == sym::main { if ident.name == sym::main {
let at_root = cx.tcx.local_parent(it.owner_id.def_id) == CRATE_DEF_ID; let at_root = cx.tcx.local_parent(it.owner_id.def_id) == CRATE_DEF_ID;
if at_root { if at_root {
note_prev_span_then_ret!(self.prev_span, it.span); note_prev_span_then_ret!(self.prev_span, it.span);
} }
} }
}, },
hir::ItemKind::Const(..) => { hir::ItemKind::Const(ident, ..) => {
if it.ident.name == kw::Underscore { if ident.name == kw::Underscore {
note_prev_span_then_ret!(self.prev_span, it.span); note_prev_span_then_ret!(self.prev_span, it.span);
} }
}, },

View file

@ -67,7 +67,7 @@ impl_lint_pass!(ImportRename => [MISSING_ENFORCED_IMPORT_RENAMES]);
impl LateLintPass<'_> for ImportRename { impl LateLintPass<'_> for ImportRename {
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
if let ItemKind::Use(path, UseKind::Single) = &item.kind { if let ItemKind::Use(path, UseKind::Single(_)) = &item.kind {
for &res in &path.res { for &res in &path.res {
if let Res::Def(_, id) = res if let Res::Def(_, id) = res
&& let Some(name) = self.renames.get(&id) && let Some(name) = self.renames.get(&id)

View file

@ -226,7 +226,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug {
&& should_lint(cx, typeck_results, block) && should_lint(cx, typeck_results, block)
{ {
// we intentionally only lint structs, see lint description // we intentionally only lint structs, see lint description
if let ItemKind::Struct(data, _) = &self_item.kind { if let ItemKind::Struct(_, data, _) = &self_item.kind {
check_struct(cx, typeck_results, block, self_ty, item, data); check_struct(cx, typeck_results, block, self_ty, item, data);
} }
} }

View file

@ -101,7 +101,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
let attrs = cx.tcx.hir_attrs(it.hir_id()); let attrs = cx.tcx.hir_attrs(it.hir_id());
check_missing_inline_attrs(cx, attrs, it.span, desc); check_missing_inline_attrs(cx, attrs, it.span, desc);
}, },
hir::ItemKind::Trait(ref _is_auto, ref _unsafe, _generics, _bounds, trait_items) => { hir::ItemKind::Trait(ref _is_auto, ref _unsafe, _ident, _generics, _bounds, trait_items) => {
// note: we need to check if the trait is exported so we can't use // note: we need to check if the trait is exported so we can't use
// `LateLintPass::check_trait_item` here. // `LateLintPass::check_trait_item` here.
for tit in trait_items { for tit in trait_items {

View file

@ -37,12 +37,12 @@ declare_lint_pass!(NoMangleWithRustAbi => [NO_MANGLE_WITH_RUST_ABI]);
impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi { impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi {
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 ItemKind::Fn { sig: fn_sig, .. } = &item.kind if let ItemKind::Fn { ident, sig: fn_sig, .. } = &item.kind
&& !item.span.from_expansion() && !item.span.from_expansion()
{ {
let attrs = cx.tcx.hir_attrs(item.hir_id()); let attrs = cx.tcx.hir_attrs(item.hir_id());
let mut app = Applicability::MaybeIncorrect; let mut app = Applicability::MaybeIncorrect;
let fn_snippet = snippet_with_applicability(cx, fn_sig.span.with_hi(item.ident.span.lo()), "..", &mut app); let fn_snippet = snippet_with_applicability(cx, fn_sig.span.with_hi(ident.span.lo()), "..", &mut app);
for attr in attrs { for attr in attrs {
if let Some(ident) = attr.ident() if let Some(ident) = attr.ident()
&& ident.name == rustc_span::sym::no_mangle && ident.name == rustc_span::sym::no_mangle

View file

@ -192,7 +192,7 @@ struct LazyInfo {
impl LazyInfo { impl LazyInfo {
fn from_item(state: &NonStdLazyStatic, cx: &LateContext<'_>, item: &Item<'_>) -> Option<Self> { fn from_item(state: &NonStdLazyStatic, cx: &LateContext<'_>, item: &Item<'_>) -> Option<Self> {
// Check if item is a `once_cell:sync::Lazy` static. // Check if item is a `once_cell:sync::Lazy` static.
if let ItemKind::Static(ty, _, body_id) = item.kind if let ItemKind::Static(_, ty, _, body_id) = item.kind
&& let Some(path_def_id) = path_def_id(cx, ty) && let Some(path_def_id) = path_def_id(cx, ty)
&& let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
&& state.once_cell_sync_lazy.contains(&path_def_id) && state.once_cell_sync_lazy.contains(&path_def_id)

View file

@ -58,7 +58,7 @@ impl PubUnderscoreFields {
impl<'tcx> LateLintPass<'tcx> for PubUnderscoreFields { impl<'tcx> LateLintPass<'tcx> for PubUnderscoreFields {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
// This lint only pertains to structs. // This lint only pertains to structs.
let ItemKind::Struct(variant_data, _) = &item.kind else { let ItemKind::Struct(_, variant_data, _) = &item.kind else {
return; return;
}; };

View file

@ -52,7 +52,11 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
&& is_not_macro_export(item) && is_not_macro_export(item)
&& !item.span.in_external_macro(cx.sess().source_map()) && !item.span.in_external_macro(cx.sess().source_map())
{ {
let span = item.span.with_hi(item.ident.span.hi()); // FIXME: `DUMMY_SP` isn't right here, because it causes the
// resulting span to begin at the start of the file.
let span = item.span.with_hi(
item.kind.ident().map(|ident| ident.span.hi()).unwrap_or(rustc_span::DUMMY_SP.hi())
);
let descr = cx.tcx.def_kind(item.owner_id).descr(item.owner_id.to_def_id()); let descr = cx.tcx.def_kind(item.owner_id).descr(item.owner_id.to_def_id());
span_lint_and_then( span_lint_and_then(
cx, cx,

View file

@ -73,7 +73,8 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors {
if let Some(self_def) = self_ty.ty_adt_def() if let Some(self_def) = self_ty.ty_adt_def()
&& let Some(self_local_did) = self_def.did().as_local() && let Some(self_local_did) = self_def.did().as_local()
&& let Node::Item(x) = cx.tcx.hir_node_by_def_id(self_local_did) && let Node::Item(x) = cx.tcx.hir_node_by_def_id(self_local_did)
&& let type_name = x.ident.name.as_str().to_lowercase() && let Some(type_ident) = x.kind.ident()
&& let type_name = type_ident.name.as_str().to_lowercase()
&& (impl_item.ident.name.as_str() == type_name && (impl_item.ident.name.as_str() == type_name
|| impl_item.ident.name.as_str().replace('_', "") == type_name) || impl_item.ident.name.as_str().replace('_', "") == type_name)
{ {

View file

@ -57,7 +57,7 @@ impl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray {
} }
fn is_struct_with_trailing_zero_sized_array<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool { fn is_struct_with_trailing_zero_sized_array<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool {
if let ItemKind::Struct(data, _) = &item.kind if let ItemKind::Struct(_, data, _) = &item.kind
&& let Some(last_field) = data.fields().last() && let Some(last_field) = data.fields().last()
&& let field_ty = cx.tcx.normalize_erasing_regions( && let field_ty = cx.tcx.normalize_erasing_regions(
cx.typing_env(), cx.typing_env(),

View file

@ -112,7 +112,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
// special handling for self trait bounds as these are not considered generics // special handling for self trait bounds as these are not considered generics
// ie. trait Foo: Display {} // ie. trait Foo: Display {}
if let Item { if let Item {
kind: ItemKind::Trait(_, _, _, bounds, ..), kind: ItemKind::Trait(_, _, _, _, bounds, ..),
.. ..
} = item } = item
{ {
@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
.. ..
}) = segments.first() }) = segments.first()
&& let Some(Node::Item(Item { && let Some(Node::Item(Item {
kind: ItemKind::Trait(_, _, _, self_bounds, _), kind: ItemKind::Trait(_, _, _, _, self_bounds, _),
.. ..
})) = cx.tcx.hir_get_if_local(*def_id) })) = cx.tcx.hir_get_if_local(*def_id)
{ {

View file

@ -451,7 +451,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id); let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id);
match item.kind { match item.kind {
ItemKind::Static(ty, _, _) | ItemKind::Const(ty, _, _) => self.check_ty( ItemKind::Static(_, ty, _, _) | ItemKind::Const(_, ty, _, _) => self.check_ty(
cx, cx,
ty, ty,
CheckTyContext { CheckTyContext {

View file

@ -454,7 +454,7 @@ fn item_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) -> HasSaf
let comment_start = match cx.tcx.parent_hir_node(item.hir_id()) { let comment_start = match cx.tcx.parent_hir_node(item.hir_id()) {
Node::Crate(parent_mod) => comment_start_before_item_in_mod(cx, parent_mod, parent_mod.spans.inner_span, item), Node::Crate(parent_mod) => comment_start_before_item_in_mod(cx, parent_mod, parent_mod.spans.inner_span, item),
Node::Item(parent_item) => { Node::Item(parent_item) => {
if let ItemKind::Mod(parent_mod) = &parent_item.kind { if let ItemKind::Mod(_, parent_mod) = &parent_item.kind {
comment_start_before_item_in_mod(cx, parent_mod, parent_item.span, item) comment_start_before_item_in_mod(cx, parent_mod, parent_item.span, item)
} else { } else {
// Doesn't support impls in this position. Pretend a comment was found. // Doesn't support impls in this position. Pretend a comment was found.
@ -614,7 +614,7 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> {
.. ..
}) => maybe_global_var = true, }) => maybe_global_var = true,
Node::Item(hir::Item { Node::Item(hir::Item {
kind: ItemKind::Mod(_), kind: ItemKind::Mod(..),
span: item_span, span: item_span,
.. ..
}) => { }) => {

View file

@ -130,9 +130,9 @@ impl LateLintPass<'_> for UnnecessaryBoxReturns {
} }
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
let ItemKind::Fn { sig, .. } = &item.kind else { let ItemKind::Fn { ident, sig, .. } = &item.kind else {
return; return;
}; };
self.check_fn_item(cx, sig.decl, item.owner_id.def_id, item.ident.name); self.check_fn_item(cx, sig.decl, item.owner_id.def_id, ident.name);
} }
} }

View file

@ -60,9 +60,9 @@ impl_lint_pass!(UnusedTraitNames => [UNUSED_TRAIT_NAMES]);
impl<'tcx> LateLintPass<'tcx> for UnusedTraitNames { impl<'tcx> LateLintPass<'tcx> for UnusedTraitNames {
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 !item.span.in_external_macro(cx.sess().source_map()) if !item.span.in_external_macro(cx.sess().source_map())
&& let ItemKind::Use(path, UseKind::Single) = item.kind && let ItemKind::Use(path, UseKind::Single(ident)) = item.kind
// Ignore imports that already use Underscore // Ignore imports that already use Underscore
&& item.ident.name != kw::Underscore && ident.name != kw::Underscore
// Only check traits // Only check traits
&& let Some(Res::Def(DefKind::Trait, _)) = path.res.first() && let Some(Res::Def(DefKind::Trait, _)) = path.res.first()
&& cx.tcx.maybe_unused_trait_imports(()).contains(&item.owner_id.def_id) && cx.tcx.maybe_unused_trait_imports(()).contains(&item.owner_id.def_id)
@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedTraitNames {
&& self.msrv.meets(cx, msrvs::UNDERSCORE_IMPORTS) && self.msrv.meets(cx, msrvs::UNDERSCORE_IMPORTS)
&& !is_from_proc_macro(cx, &last_segment.ident) && !is_from_proc_macro(cx, &last_segment.ident)
{ {
let complete_span = last_segment.ident.span.to(item.ident.span); let complete_span = last_segment.ident.span.to(ident.span);
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,
UNUSED_TRAIT_NAMES, UNUSED_TRAIT_NAMES,

View file

@ -131,11 +131,11 @@ impl LateLintPass<'_> for UpperCaseAcronyms {
return; return;
} }
match it.kind { match it.kind {
ItemKind::TyAlias(..) | ItemKind::Struct(..) | ItemKind::Trait(..) => { ItemKind::TyAlias(ident, ..) | ItemKind::Struct(ident, ..) | ItemKind::Trait(_, _, ident, ..) => {
check_ident(cx, &it.ident, it.hir_id(), self.upper_case_acronyms_aggressive); check_ident(cx, &ident, it.hir_id(), self.upper_case_acronyms_aggressive);
}, },
ItemKind::Enum(ref enumdef, _) => { ItemKind::Enum(ident, ref enumdef, _) => {
check_ident(cx, &it.ident, it.hir_id(), self.upper_case_acronyms_aggressive); check_ident(cx, &ident, it.hir_id(), self.upper_case_acronyms_aggressive);
// check enum variants separately because again we only want to lint on private enums and // check enum variants separately because again we only want to lint on private enums and
// the fn check_variant does not know about the vis of the enum of its variants // the fn check_variant does not know about the vis of the enum of its variants
enumdef.variants.iter().for_each(|variant| { enumdef.variants.iter().for_each(|variant| {

View file

@ -242,14 +242,14 @@ fn fn_header_search_pat(header: FnHeader) -> Pat {
fn item_search_pat(item: &Item<'_>) -> (Pat, Pat) { fn item_search_pat(item: &Item<'_>) -> (Pat, Pat) {
let (start_pat, end_pat) = match &item.kind { let (start_pat, end_pat) = match &item.kind {
ItemKind::ExternCrate(_) => (Pat::Str("extern"), Pat::Str(";")), ItemKind::ExternCrate(..) => (Pat::Str("extern"), Pat::Str(";")),
ItemKind::Static(..) => (Pat::Str("static"), Pat::Str(";")), ItemKind::Static(..) => (Pat::Str("static"), Pat::Str(";")),
ItemKind::Const(..) => (Pat::Str("const"), Pat::Str(";")), ItemKind::Const(..) => (Pat::Str("const"), Pat::Str(";")),
ItemKind::Fn { sig, .. } => (fn_header_search_pat(sig.header), Pat::Str("")), ItemKind::Fn { sig, .. } => (fn_header_search_pat(sig.header), Pat::Str("")),
ItemKind::ForeignMod { .. } => (Pat::Str("extern"), Pat::Str("}")), ItemKind::ForeignMod { .. } => (Pat::Str("extern"), Pat::Str("}")),
ItemKind::TyAlias(..) => (Pat::Str("type"), Pat::Str(";")), ItemKind::TyAlias(..) => (Pat::Str("type"), Pat::Str(";")),
ItemKind::Enum(..) => (Pat::Str("enum"), Pat::Str("}")), ItemKind::Enum(..) => (Pat::Str("enum"), Pat::Str("}")),
ItemKind::Struct(VariantData::Struct { .. }, _) => (Pat::Str("struct"), Pat::Str("}")), ItemKind::Struct(_, VariantData::Struct { .. }, _) => (Pat::Str("struct"), Pat::Str("}")),
ItemKind::Struct(..) => (Pat::Str("struct"), Pat::Str(";")), ItemKind::Struct(..) => (Pat::Str("struct"), Pat::Str(";")),
ItemKind::Union(..) => (Pat::Str("union"), Pat::Str("}")), ItemKind::Union(..) => (Pat::Str("union"), Pat::Str("}")),
ItemKind::Trait(_, Safety::Unsafe, ..) ItemKind::Trait(_, Safety::Unsafe, ..)

View file

@ -644,7 +644,7 @@ fn local_item_children_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, name: Symb
let root_mod; let root_mod;
let item_kind = match tcx.hir_node_by_def_id(local_id) { let item_kind = match tcx.hir_node_by_def_id(local_id) {
Node::Crate(r#mod) => { Node::Crate(r#mod) => {
root_mod = ItemKind::Mod(r#mod); root_mod = ItemKind::Mod(Ident::dummy(), r#mod);
&root_mod &root_mod
}, },
Node::Item(item) => &item.kind, Node::Item(item) => &item.kind,
@ -661,10 +661,13 @@ fn local_item_children_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, name: Symb
}; };
match item_kind { match item_kind {
ItemKind::Mod(r#mod) => r#mod ItemKind::Mod(_, r#mod) => r#mod
.item_ids .item_ids
.iter() .iter()
.filter_map(|&item_id| res(tcx.hir_item(item_id).ident, item_id.owner_id)) .filter_map(|&item_id| {
let ident = tcx.hir_item(item_id).kind.ident()?;
res(ident, item_id.owner_id)
})
.collect(), .collect(),
ItemKind::Impl(r#impl) => r#impl ItemKind::Impl(r#impl) => r#impl
.items .items
@ -1416,8 +1419,8 @@ pub fn is_in_panic_handler(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> { pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> {
let parent_id = cx.tcx.hir_get_parent_item(expr.hir_id).def_id; let parent_id = cx.tcx.hir_get_parent_item(expr.hir_id).def_id;
match cx.tcx.hir_node_by_def_id(parent_id) { match cx.tcx.hir_node_by_def_id(parent_id) {
Node::Item(Item { ident, .. }) Node::Item(item) => item.kind.ident().map(|ident| ident.name),
| Node::TraitItem(TraitItem { ident, .. }) Node::TraitItem(TraitItem { ident, .. })
| Node::ImplItem(ImplItem { ident, .. }) => Some(ident.name), | Node::ImplItem(ImplItem { ident, .. }) => Some(ident.name),
_ => None, _ => None,
} }
@ -2634,7 +2637,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym
for id in tcx.hir_module_free_items(module) { for id in tcx.hir_module_free_items(module) {
if matches!(tcx.def_kind(id.owner_id), DefKind::Const) if matches!(tcx.def_kind(id.owner_id), DefKind::Const)
&& let item = tcx.hir_item(id) && let item = tcx.hir_item(id)
&& let ItemKind::Const(ty, _generics, _body) = item.kind && let ItemKind::Const(ident, ty, _generics, _body) = item.kind
{ {
if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind { if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind {
// We could also check for the type name `test::TestDescAndFn` // We could also check for the type name `test::TestDescAndFn`
@ -2644,7 +2647,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym
.iter() .iter()
.any(|a| a.has_name(sym::rustc_test_marker)); .any(|a| a.has_name(sym::rustc_test_marker));
if has_test_marker { if has_test_marker {
names.push(item.ident.name); names.push(ident.name);
} }
} }
} }
@ -2668,10 +2671,10 @@ pub fn is_in_test_function(tcx: TyCtxt<'_>, id: HirId) -> bool {
// function scope // function scope
.any(|(_id, node)| { .any(|(_id, node)| {
if let Node::Item(item) = node { if let Node::Item(item) = node {
if let ItemKind::Fn { .. } = item.kind { if let ItemKind::Fn { ident, .. } = item.kind {
// Note that we have sorted the item names in the visitor, // Note that we have sorted the item names in the visitor,
// so the binary_search gets the same as `contains`, but faster. // so the binary_search gets the same as `contains`, but faster.
return names.binary_search(&item.ident.name).is_ok(); return names.binary_search(&ident.name).is_ok();
} }
} }
false false