Rollup merge of #138384 - nnethercote:hir-ItemKind-idents, r=fmease
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.
This is step towards `kw::Empty` elimination (#137978).
r? `@fmease`
This commit is contained in:
commit
e1acc68c9d
83 changed files with 667 additions and 556 deletions
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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`",
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
..
|
||||
}) => {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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| {
|
||||
|
|
|
|||
|
|
@ -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, ..)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue