Auto merge of #138630 - matthiaskrgr:rollup-kk1gogr, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #138384 (Move `hir::Item::ident` into `hir::ItemKind`.)
 - #138508 (Clarify "owned data" in E0515.md)
 - #138531 (Store test diffs in job summaries and improve analysis formatting)
 - #138533 (Only use `DIST_TRY_BUILD` for try jobs that were not selected explicitly)
 - #138556 (Fix ICE: attempted to remap an already remapped filename)
 - #138608 (rustc_target: Add target feature constraints for LoongArch)
 - #138619 (Flatten `if`s in `rustc_codegen_ssa`)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-03-18 05:58:46 +00:00
commit 259fdb5212
105 changed files with 1345 additions and 1150 deletions

View file

@ -5,7 +5,7 @@ use clippy_config::types::{
};
use clippy_utils::diagnostics::span_lint_and_note;
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,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
@ -178,8 +178,8 @@ impl ArbitrarySourceItemOrdering {
/// Produces a linting warning for incorrectly ordered item members.
fn lint_member_name<T: LintContext>(
cx: &T,
ident: &rustc_span::symbol::Ident,
before_ident: &rustc_span::symbol::Ident,
ident: &rustc_span::Ident,
before_ident: &rustc_span::Ident,
) {
span_lint_and_note(
cx,
@ -192,21 +192,21 @@ impl ArbitrarySourceItemOrdering {
}
fn lint_member_item<T: LintContext>(cx: &T, item: &Item<'_>, before_item: &Item<'_>) {
let span = if item.ident.as_str().is_empty() {
&item.span
let span = if let Some(ident) = item.kind.ident() {
ident.span
} 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,
"should be placed before the following item".to_owned(),
ident.span,
format!("should be placed before `{}`", ident.as_str(),),
)
} else {
(
&before_item.ident.span,
format!("should be placed before `{}`", before_item.ident.as_str(),),
before_item.span,
"should be placed before the following item".to_owned(),
)
};
@ -218,9 +218,9 @@ impl ArbitrarySourceItemOrdering {
span_lint_and_note(
cx,
ARBITRARY_SOURCE_ITEM_ORDERING,
*span,
span,
"incorrect ordering of items (must be alphabetically ordered)",
Some(*before_span),
Some(before_span),
note,
);
}
@ -244,7 +244,7 @@ impl ArbitrarySourceItemOrdering {
impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
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;
for variant in enum_def.variants {
if variant.span.in_external_macro(cx.sess().source_map()) {
@ -259,7 +259,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
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;
for field in *fields {
if field.span.in_external_macro(cx.sess().source_map()) {
@ -274,7 +274,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
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 =>
{
let mut cur_t: Option<&TraitItemRef> = None;
@ -351,50 +351,24 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
continue;
}
// The following exceptions (skipping with `continue;`) may not be
// complete, edge cases have not been explored further than what
// appears in the existing code base.
if item.ident.name == rustc_span::symbol::kw::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.
// e.g. `use std::prelude::rustc_2021`
} else if use_kind == UseKind::Glob {
// Filters glob kinds of uses.
// e.g. `use std::sync::*`
} else {
// This can be used for debugging.
// println!("Unknown autogenerated use statement: {:?}", item);
}
continue;
}
}
let ident = if let Some(ident) = item.kind.ident() {
ident
} else if let ItemKind::Impl(_) = item.kind
&& !get_item_name(item).is_empty()
{
rustc_span::Ident::empty() // FIXME: a bit strange, is there a better way to do it?
} else {
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,
// e.g. serde::Serialize or num_derive::FromPrimitive.
continue;
}
if item.ident.name == rustc_span::sym::std && item.span.is_dummy() {
if let ItemKind::ExternCrate(None) = item.kind {
if ident.name == rustc_span::sym::std && item.span.is_dummy() {
if let ItemKind::ExternCrate(None, _) = item.kind {
// Filters the auto-included Rust standard library.
continue;
}
@ -525,6 +499,8 @@ fn get_item_name(item: &Item<'_>) -> String {
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_utils::msrvs::{self, Msrv, MsrvStack};
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_session::impl_lint_pass;
use rustc_span::sym;
@ -466,8 +466,8 @@ impl Attributes {
impl<'tcx> LateLintPass<'tcx> for Attributes {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
let attrs = cx.tcx.hir_attrs(item.hir_id());
if is_relevant_item(cx, item) {
inline_always::check(cx, item.span, item.ident.name, attrs);
if let ItemKind::Fn { ident, .. } = item.kind && is_relevant_item(cx, item) {
inline_always::check(cx, item.span, ident.name, attrs);
}
repr_attributes::check(cx, item.span, attrs, self.msrv);
}

View file

@ -24,7 +24,7 @@ pub(super) fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
if let ItemKind::Fn { body: eid, .. } = item.kind {
is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir_body(eid).value)
} else {
true
false
}
}

View file

@ -99,7 +99,7 @@ impl_lint_pass!(DisallowedTypes => [DISALLOWED_TYPES]);
impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
if let ItemKind::Use(path, UseKind::Single) = &item.kind {
if let ItemKind::Use(path, UseKind::Single(_)) = &item.kind {
for res in &path.res {
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 {
return;
}
if let ItemKind::Enum(def, _) = &item.kind {
if let ItemKind::Enum(_, def, _) = &item.kind {
for var in def.variants {
if let Some(anon_const) = &var.disr_expr {
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 {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
match item.kind {
ItemKind::TyAlias(..)
if item.ident.name == sym::Error
ItemKind::TyAlias(ident, ..)
if ident.name == sym::Error
&& is_visible_outside_module(cx, item.owner_id.def_id)
&& let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
&& let Some(error_def_id) = cx.tcx.get_diagnostic_item(sym::Error)
@ -47,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for ErrorImplError {
span_lint(
cx,
ERROR_IMPL_ERROR,
item.ident.span,
ident.span,
"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
if let ItemKind::Trait(_, _, _, _, items) = item.kind {
if let ItemKind::Trait(_, _, _, _, _, items) = item.kind {
for trait_item in items {
if trait_item.id.owner_id.def_id == fn_def_id {
// 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 {
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
&& has_n_bools(
variant_data.fields().iter().map(|field| field.ty),

View file

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

View file

@ -103,7 +103,7 @@ fn check_result_large_err<'tcx>(cx: &LateContext<'tcx>, err_ty: Ty<'tcx>, hir_ty
.did()
.as_local()
&& 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);
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_lint::{LateContext, LateLintPass};
use rustc_session::impl_lint_pass;
use rustc_span::Span;
use rustc_span::{Ident, Span};
use rustc_span::symbol::Symbol;
declare_clippy_lint! {
@ -196,16 +196,16 @@ fn have_no_extra_prefix(prefixes: &[&str]) -> bool {
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 {
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.
// 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;
}
@ -256,7 +256,7 @@ fn check_fields(cx: &LateContext<'_>, threshold: u64, item: &Item<'_>, fields: &
span_lint_and_help(
cx,
STRUCT_FIELD_NAMES,
item.span,
span,
format!("all fields have the same {what}fix: `{value}`"),
None,
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<'_>]) {
let snake_name = to_snake_case(item.ident.name.as_str());
fn check_struct_name_repetition(cx: &LateContext<'_>, ident: Ident, fields: &[FieldDef<'_>]) {
let snake_name = to_snake_case(ident.name.as_str());
let item_name_words: Vec<&str> = snake_name.split('_').collect();
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)
let field_words: Vec<&str> = field.ident.name.as_str().split('_').collect();
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 {
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();
assert!(last.is_some());
}
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);
if !item.span.from_expansion() && is_present_in_source(cx, item.span) {
if let [.., (mod_name, mod_camel, mod_owner_id)] = &*self.modules {
// constants don't have surrounding modules
if !mod_camel.is_empty() {
if mod_name == &item.ident.name
if mod_name == &ident.name
&& let ItemKind::Mod(..) = item.kind
&& (!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(
cx,
MODULE_NAME_REPETITIONS,
item.ident.span,
ident.span,
"item name starts with its containing module's name",
),
_ => (),
@ -450,7 +454,7 @@ impl LateLintPass<'_> for ItemNameRepetitions {
span_lint(
cx,
MODULE_NAME_REPETITIONS,
item.ident.span,
ident.span,
"item name ends with its containing module's name",
);
}
@ -462,13 +466,13 @@ impl LateLintPass<'_> for ItemNameRepetitions {
&& span_is_local(item.span)
{
match item.kind {
ItemKind::Enum(def, _) => check_variant(cx, self.enum_threshold, &def, item_name, item.span),
ItemKind::Struct(VariantData::Struct { fields, .. }, _) => {
check_fields(cx, self.struct_threshold, item, fields);
ItemKind::Enum(_, def, _) => check_variant(cx, self.enum_threshold, &def, item_name, item.span),
ItemKind::Struct(_, VariantData::Struct { 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]);
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()
&& is_cfg_test(cx.tcx, item.hir_id())
&& !item.span.from_expansion()
@ -67,14 +67,20 @@ impl LateLintPass<'_> for ItemsAfterTestModule {
let after: Vec<_> = items
.filter(|item| {
// Ignore the generated test main function
!(item.ident.name == sym::main
&& item.span.ctxt().outer_expn_data().kind == ExpnKind::AstPass(AstPass::TestHarness))
if let ItemKind::Fn { ident, .. } = item.kind
&& ident.name == sym::main
&& item.span.ctxt().outer_expn_data().kind == ExpnKind::AstPass(AstPass::TestHarness)
{
false
} else {
true
}
})
.collect();
if let Some(last) = after.last()
&& 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()))
{

View file

@ -48,7 +48,7 @@ impl_lint_pass!(LargeConstArrays => [LARGE_CONST_ARRAYS]);
impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
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.
// 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.
@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
&& 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)
{
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(
hi_pos - BytePos::from_usize("const".len()),
hi_pos,

View file

@ -73,7 +73,7 @@ impl_lint_pass!(LargeEnumVariant => [LARGE_ENUM_VARIANT]);
impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
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::Adt(adt, subst) = ty.kind()
&& adt.variants().len() > 1
@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
let mut applicability = Applicability::MaybeIncorrect;
if is_copy(cx, ty) || maybe_copy(cx, ty) {
diag.span_note(
item.ident.span,
ident.span,
"boxing a variant would require the type no longer be `Copy`",
);
} 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>) {
// Integer modules are "TBD" deprecated, and the contents are too,
// 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())
&& let Some(def_id) = path.res[0].opt_def_id()
&& self.msrv.meets(cx, msrvs::NUMERIC_ASSOCIATED_CONSTANTS)
@ -72,7 +72,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
"importing a legacy numeric constant"
},
|diag| {
if item.ident.name == kw::Underscore {
if let UseKind::Single(ident) = kind && ident.name == kw::Underscore {
diag.help("remove this import");
return;
}

View file

@ -17,7 +17,7 @@ use rustc_middle::ty::{self, AssocKind, FnSig, Ty};
use rustc_session::declare_lint_pass;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol};
use rustc_span::{Ident, Span, Symbol};
use rustc_trait_selection::traits::supertrait_def_ids;
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 {
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()
{
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) {
Node::ForeignItem(x) => (x.ident.name, "extern type"),
Node::Item(x) => match x.kind {
ItemKind::Struct(..) => (x.ident.name, "struct"),
ItemKind::Enum(..) => (x.ident.name, "enum"),
ItemKind::Union(..) => (x.ident.name, "union"),
_ => (x.ident.name, "type"),
ItemKind::Struct(ident, ..) => (ident.name, "struct"),
ItemKind::Enum(ident, ..) => (ident.name, "enum"),
ItemKind::Union(ident, ..) => (ident.name, "union"),
_ => (x.kind.ident().unwrap().name, "type"),
},
_ => 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 {
item.ident.name == name
&& 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,
format!(
"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 {
ItemKind::Enum(def, _) if def.variants.len() > 1 => {
ItemKind::Enum(_, def, _) if def.variants.len() > 1 => {
let iter = def.variants.iter().filter_map(|v| {
(matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir_attrs(v.hir_id)))
.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));
}
},
ItemKind::Struct(variant_data, _) => {
ItemKind::Struct(_, variant_data, _) => {
let fields = variant_data.fields();
let private_fields = fields
.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<'_>) {
match it.kind {
hir::ItemKind::Fn { .. } => {
hir::ItemKind::Fn { ident, .. } => {
// 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;
if at_root {
note_prev_span_then_ret!(self.prev_span, it.span);
}
}
},
hir::ItemKind::Const(..) => {
if it.ident.name == kw::Underscore {
hir::ItemKind::Const(ident, ..) => {
if ident.name == kw::Underscore {
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 {
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 {
if let Res::Def(_, id) = res
&& 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)
{
// 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);
}
}

View file

@ -101,7 +101,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
let attrs = cx.tcx.hir_attrs(it.hir_id());
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
// `LateLintPass::check_trait_item` here.
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 {
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()
{
let attrs = cx.tcx.hir_attrs(item.hir_id());
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 {
if let Some(ident) = attr.ident()
&& ident.name == rustc_span::sym::no_mangle

View file

@ -192,7 +192,7 @@ struct LazyInfo {
impl LazyInfo {
fn from_item(state: &NonStdLazyStatic, cx: &LateContext<'_>, item: &Item<'_>) -> Option<Self> {
// 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 hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
&& state.once_cell_sync_lazy.contains(&path_def_id)

View file

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

View file

@ -52,7 +52,11 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
&& is_not_macro_export(item)
&& !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());
span_lint_and_then(
cx,

View file

@ -73,7 +73,8 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors {
if let Some(self_def) = self_ty.ty_adt_def()
&& 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 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().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 {
if let ItemKind::Struct(data, _) = &item.kind
if let ItemKind::Struct(_, data, _) = &item.kind
&& let Some(last_field) = data.fields().last()
&& let field_ty = cx.tcx.normalize_erasing_regions(
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
// ie. trait Foo: Display {}
if let Item {
kind: ItemKind::Trait(_, _, _, bounds, ..),
kind: ItemKind::Trait(_, _, _, _, bounds, ..),
..
} = item
{
@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
..
}) = segments.first()
&& let Some(Node::Item(Item {
kind: ItemKind::Trait(_, _, _, self_bounds, _),
kind: ItemKind::Trait(_, _, _, _, self_bounds, _),
..
})) = 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);
match item.kind {
ItemKind::Static(ty, _, _) | ItemKind::Const(ty, _, _) => self.check_ty(
ItemKind::Static(_, ty, _, _) | ItemKind::Const(_, ty, _, _) => self.check_ty(
cx,
ty,
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()) {
Node::Crate(parent_mod) => comment_start_before_item_in_mod(cx, parent_mod, parent_mod.spans.inner_span, 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)
} else {
// 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,
Node::Item(hir::Item {
kind: ItemKind::Mod(_),
kind: ItemKind::Mod(..),
span: item_span,
..
}) => {

View file

@ -130,9 +130,9 @@ impl LateLintPass<'_> for UnnecessaryBoxReturns {
}
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;
};
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 {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
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
&& item.ident.name != kw::Underscore
&& ident.name != kw::Underscore
// Only check traits
&& let Some(Res::Def(DefKind::Trait, _)) = path.res.first()
&& 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)
&& !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(
cx,
UNUSED_TRAIT_NAMES,

View file

@ -131,11 +131,11 @@ impl LateLintPass<'_> for UpperCaseAcronyms {
return;
}
match it.kind {
ItemKind::TyAlias(..) | ItemKind::Struct(..) | ItemKind::Trait(..) => {
check_ident(cx, &it.ident, it.hir_id(), self.upper_case_acronyms_aggressive);
ItemKind::TyAlias(ident, ..) | ItemKind::Struct(ident, ..) | ItemKind::Trait(_, _, ident, ..) => {
check_ident(cx, &ident, it.hir_id(), self.upper_case_acronyms_aggressive);
},
ItemKind::Enum(ref enumdef, _) => {
check_ident(cx, &it.ident, it.hir_id(), self.upper_case_acronyms_aggressive);
ItemKind::Enum(ident, ref enumdef, _) => {
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
// the fn check_variant does not know about the vis of the enum of its variants
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) {
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::Const(..) => (Pat::Str("const"), Pat::Str(";")),
ItemKind::Fn { sig, .. } => (fn_header_search_pat(sig.header), Pat::Str("")),
ItemKind::ForeignMod { .. } => (Pat::Str("extern"), Pat::Str("}")),
ItemKind::TyAlias(..) => (Pat::Str("type"), 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::Union(..) => (Pat::Str("union"), Pat::Str("}")),
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 item_kind = match tcx.hir_node_by_def_id(local_id) {
Node::Crate(r#mod) => {
root_mod = ItemKind::Mod(r#mod);
root_mod = ItemKind::Mod(Ident::dummy(), r#mod);
&root_mod
},
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 {
ItemKind::Mod(r#mod) => r#mod
ItemKind::Mod(_, r#mod) => r#mod
.item_ids
.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(),
ItemKind::Impl(r#impl) => r#impl
.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> {
let parent_id = cx.tcx.hir_get_parent_item(expr.hir_id).def_id;
match cx.tcx.hir_node_by_def_id(parent_id) {
Node::Item(Item { ident, .. })
| Node::TraitItem(TraitItem { ident, .. })
Node::Item(item) => item.kind.ident().map(|ident| ident.name),
Node::TraitItem(TraitItem { ident, .. })
| Node::ImplItem(ImplItem { ident, .. }) => Some(ident.name),
_ => 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) {
if matches!(tcx.def_kind(id.owner_id), DefKind::Const)
&& 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 {
// 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()
.any(|a| a.has_name(sym::rustc_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
.any(|(_id, 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,
// 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