mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
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:
@@ -164,7 +164,7 @@ fn visit_param(&mut self, param: &'hir Param<'hir>) {
|
||||
fn visit_item(&mut self, i: &'hir Item<'hir>) {
|
||||
debug_assert_eq!(i.owner_id, self.owner);
|
||||
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 let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
|
||||
this.insert(i.span, ctor_hir_id, Node::Ctor(struct_def));
|
||||
|
||||
@@ -111,6 +111,7 @@ fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) {
|
||||
}
|
||||
|
||||
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)))
|
||||
}
|
||||
}
|
||||
@@ -154,14 +155,12 @@ pub(super) fn lower_mod(
|
||||
}
|
||||
|
||||
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 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 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 {
|
||||
owner_id: hir_id.expect_owner(),
|
||||
ident: self.lower_ident(ident),
|
||||
kind,
|
||||
vis_span,
|
||||
span: self.lower_span(i.span),
|
||||
@@ -174,25 +173,34 @@ fn lower_item_kind(
|
||||
span: Span,
|
||||
id: NodeId,
|
||||
hir_id: hir::HirId,
|
||||
ident: &mut Ident,
|
||||
ident: Ident,
|
||||
attrs: &'hir [hir::Attribute],
|
||||
vis_span: Span,
|
||||
i: &ItemKind,
|
||||
) -> hir::ItemKind<'hir> {
|
||||
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) => {
|
||||
debug_assert_eq!(ident.name, kw::Empty);
|
||||
// Start with an empty prefix.
|
||||
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 }) => {
|
||||
debug_assert_ne!(ident.name, kw::Empty);
|
||||
let ident = self.lower_ident(ident);
|
||||
let (ty, body_id) =
|
||||
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, .. }) => {
|
||||
debug_assert_ne!(ident.name, kw::Empty);
|
||||
let ident = self.lower_ident(ident);
|
||||
let (generics, (ty, body_id)) = self.lower_generics(
|
||||
generics,
|
||||
id,
|
||||
@@ -201,7 +209,7 @@ fn lower_item_kind(
|
||||
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 {
|
||||
sig: FnSig { decl, header, span: fn_sig_span },
|
||||
@@ -211,6 +219,7 @@ fn lower_item_kind(
|
||||
define_opaque,
|
||||
..
|
||||
}) => {
|
||||
debug_assert_ne!(ident.name, kw::Empty);
|
||||
self.with_new_scopes(*fn_sig_span, |this| {
|
||||
// Note: we don't need to change the return type from `T` to
|
||||
// `impl Future<Output = T>` here because lower_body
|
||||
@@ -238,28 +247,44 @@ fn lower_item_kind(
|
||||
span: this.lower_span(*fn_sig_span),
|
||||
};
|
||||
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 {
|
||||
ModKind::Loaded(items, _, spans, _) => {
|
||||
hir::ItemKind::Mod(self.lower_mod(items, spans))
|
||||
ItemKind::Mod(_, mod_kind) => {
|
||||
debug_assert_ne!(ident.name, kw::Empty);
|
||||
let ident = self.lower_ident(ident);
|
||||
match mod_kind {
|
||||
ModKind::Loaded(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 {
|
||||
abi: fm.abi.map_or(ExternAbi::FALLBACK, |abi| self.lower_abi(abi)),
|
||||
items: self
|
||||
.arena
|
||||
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
|
||||
},
|
||||
}
|
||||
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)),
|
||||
items: self
|
||||
.arena
|
||||
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
|
||||
}
|
||||
}
|
||||
ItemKind::GlobalAsm(asm) => {
|
||||
debug_assert_eq!(ident.name, kw::Empty);
|
||||
let asm = self.lower_inline_asm(span, asm);
|
||||
let fake_body =
|
||||
self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm))));
|
||||
hir::ItemKind::GlobalAsm { asm, fake_body }
|
||||
}
|
||||
ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => {
|
||||
debug_assert_ne!(ident.name, kw::Empty);
|
||||
// We lower
|
||||
//
|
||||
// type Foo = impl Trait
|
||||
@@ -268,6 +293,7 @@ fn lower_item_kind(
|
||||
//
|
||||
// type Foo = Foo1
|
||||
// opaque type Foo1: Trait
|
||||
let ident = self.lower_ident(ident);
|
||||
let mut generics = generics.clone();
|
||||
add_ty_alias_where_clause(&mut generics, *where_clauses, true);
|
||||
let (generics, ty) = self.lower_generics(
|
||||
@@ -293,9 +319,11 @@ fn lower_item_kind(
|
||||
),
|
||||
},
|
||||
);
|
||||
hir::ItemKind::TyAlias(ty, generics)
|
||||
hir::ItemKind::TyAlias(ident, ty, 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(
|
||||
generics,
|
||||
id,
|
||||
@@ -306,25 +334,29 @@ fn lower_item_kind(
|
||||
)
|
||||
},
|
||||
);
|
||||
hir::ItemKind::Enum(hir::EnumDef { variants }, generics)
|
||||
hir::ItemKind::Enum(ident, hir::EnumDef { variants }, 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(
|
||||
generics,
|
||||
id,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|
||||
|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) => {
|
||||
debug_assert_ne!(ident.name, kw::Empty);
|
||||
let ident = self.lower_ident(ident);
|
||||
let (generics, vdata) = self.lower_generics(
|
||||
generics,
|
||||
id,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|
||||
|this| this.lower_variant_data(hir_id, vdata),
|
||||
);
|
||||
hir::ItemKind::Union(vdata, generics)
|
||||
hir::ItemKind::Union(ident, vdata, generics)
|
||||
}
|
||||
ItemKind::Impl(box Impl {
|
||||
safety,
|
||||
@@ -336,6 +368,7 @@ fn lower_item_kind(
|
||||
self_ty: ty,
|
||||
items: impl_items,
|
||||
}) => {
|
||||
debug_assert_eq!(ident.name, kw::Empty);
|
||||
// Lower the "impl header" first. This ordering is important
|
||||
// for in-band lifetimes! Consider `'a` here:
|
||||
//
|
||||
@@ -401,6 +434,8 @@ fn lower_item_kind(
|
||||
}))
|
||||
}
|
||||
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(
|
||||
generics,
|
||||
id,
|
||||
@@ -417,9 +452,11 @@ fn lower_item_kind(
|
||||
(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) => {
|
||||
debug_assert_ne!(ident.name, kw::Empty);
|
||||
let ident = self.lower_ident(ident);
|
||||
let (generics, bounds) = self.lower_generics(
|
||||
generics,
|
||||
id,
|
||||
@@ -431,9 +468,11 @@ fn lower_item_kind(
|
||||
)
|
||||
},
|
||||
);
|
||||
hir::ItemKind::TraitAlias(generics, bounds)
|
||||
hir::ItemKind::TraitAlias(ident, generics, bounds)
|
||||
}
|
||||
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 def_id = self.local_def_id(id);
|
||||
let def_kind = self.tcx.def_kind(def_id);
|
||||
@@ -444,11 +483,14 @@ fn lower_item_kind(
|
||||
);
|
||||
};
|
||||
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) => {
|
||||
debug_assert_ne!(ident.name, kw::Empty);
|
||||
let ident = self.lower_ident(ident);
|
||||
let delegation_results = self.lower_delegation(delegation, id);
|
||||
hir::ItemKind::Fn {
|
||||
ident,
|
||||
sig: delegation_results.sig,
|
||||
generics: delegation_results.generics,
|
||||
body: delegation_results.body_id,
|
||||
@@ -479,7 +521,6 @@ fn lower_use_tree(
|
||||
prefix: &Path,
|
||||
id: NodeId,
|
||||
vis_span: Span,
|
||||
ident: &mut Ident,
|
||||
attrs: &'hir [hir::Attribute],
|
||||
) -> hir::ItemKind<'hir> {
|
||||
let path = &tree.prefix;
|
||||
@@ -487,7 +528,7 @@ fn lower_use_tree(
|
||||
|
||||
match tree.kind {
|
||||
UseTreeKind::Simple(rename) => {
|
||||
*ident = tree.ident();
|
||||
let mut ident = tree.ident();
|
||||
|
||||
// First, apply the prefix to the path.
|
||||
let mut path = Path { segments, span: path.span, tokens: None };
|
||||
@@ -498,13 +539,14 @@ fn lower_use_tree(
|
||||
{
|
||||
let _ = path.segments.pop();
|
||||
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 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 => {
|
||||
let res = self.expect_full_res(id);
|
||||
@@ -551,20 +593,16 @@ fn lower_use_tree(
|
||||
// own its own names, we have to adjust the owner before
|
||||
// lowering the rest of the import.
|
||||
self.with_hir_id_owner(id, |this| {
|
||||
let mut ident = *ident;
|
||||
|
||||
// `prefix` is lowered multiple times, but in different HIR owners.
|
||||
// So each segment gets renewed `HirId` with the same
|
||||
// `ItemLocalId` and the new owner. (See `lower_node_id`)
|
||||
let kind =
|
||||
this.lower_use_tree(use_tree, &prefix, id, vis_span, &mut ident, attrs);
|
||||
let kind = this.lower_use_tree(use_tree, &prefix, id, vis_span, attrs);
|
||||
if !attrs.is_empty() {
|
||||
this.attrs.insert(hir::ItemLocalId::ZERO, attrs);
|
||||
}
|
||||
|
||||
let item = hir::Item {
|
||||
owner_id: hir::OwnerId { def_id: new_hir_id },
|
||||
ident: this.lower_ident(ident),
|
||||
kind,
|
||||
vis_span,
|
||||
span: this.lower_span(use_tree.span),
|
||||
@@ -604,7 +642,7 @@ fn lower_assoc_item(
|
||||
hir::ItemKind::Impl(impl_) => {
|
||||
self.is_in_trait_impl = impl_.of_trait.is_some();
|
||||
}
|
||||
hir::ItemKind::Trait(_, _, _, _, _) => {}
|
||||
hir::ItemKind::Trait(..) => {}
|
||||
kind => {
|
||||
span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr())
|
||||
}
|
||||
@@ -760,6 +798,7 @@ pub(super) fn lower_field_def(
|
||||
}
|
||||
|
||||
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 attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
|
||||
let trait_item_def_id = hir_id.expect_owner();
|
||||
@@ -907,6 +946,7 @@ pub(crate) fn expr_err(&mut self, span: Span, guar: ErrorGuaranteed) -> hir::Exp
|
||||
}
|
||||
|
||||
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.
|
||||
let has_value = true;
|
||||
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
|
||||
|
||||
@@ -691,7 +691,9 @@ fn is_error_in_trait(&self, local: Local) -> (bool, bool, Option<Span>) {
|
||||
true,
|
||||
td.is_local(),
|
||||
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;
|
||||
for hir::TraitItemRef { id: fi, kind: k, .. } in *items {
|
||||
let hi = fi.hir_id();
|
||||
@@ -980,7 +982,7 @@ fn expected_fn_found_fn_mut_call(&self, err: &mut Diag<'_>, sp: Span, act: &str)
|
||||
let arg = match tcx.hir_get_if_local(callee_def_id) {
|
||||
Some(
|
||||
hir::Node::Item(hir::Item {
|
||||
ident, kind: hir::ItemKind::Fn { sig, .. }, ..
|
||||
kind: hir::ItemKind::Fn { ident, sig, .. }, ..
|
||||
})
|
||||
| hir::Node::TraitItem(hir::TraitItem {
|
||||
ident,
|
||||
@@ -1021,7 +1023,7 @@ fn expected_fn_found_fn_mut_call(&self, err: &mut Diag<'_>, sp: Span, act: &str)
|
||||
// return type.
|
||||
match tcx.hir_node_by_def_id(tcx.hir_get_parent_item(fn_call_id).def_id) {
|
||||
hir::Node::Item(hir::Item {
|
||||
ident, kind: hir::ItemKind::Fn { sig, .. }, ..
|
||||
kind: hir::ItemKind::Fn { ident, sig, .. }, ..
|
||||
})
|
||||
| hir::Node::TraitItem(hir::TraitItem {
|
||||
ident,
|
||||
|
||||
@@ -3755,7 +3755,10 @@ pub enum UseKind {
|
||||
/// One import, e.g., `use foo::bar` or `use foo::bar as baz`.
|
||||
/// Also produced for each element of a list `use`, e.g.
|
||||
/// `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,
|
||||
@@ -3897,8 +3900,6 @@ pub fn hir_id(&self) -> HirId {
|
||||
|
||||
/// An item
|
||||
///
|
||||
/// The name might be a dummy name in case of anonymous items
|
||||
///
|
||||
/// For more details, see the [rust lang reference].
|
||||
/// 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
|
||||
@@ -3907,7 +3908,6 @@ pub fn hir_id(&self) -> HirId {
|
||||
/// [rust lang reference]: https://doc.rust-lang.org/reference/items.html
|
||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||
pub struct Item<'hir> {
|
||||
pub ident: Ident,
|
||||
pub owner_id: OwnerId,
|
||||
pub kind: ItemKind<'hir>,
|
||||
pub span: Span,
|
||||
@@ -3937,46 +3937,56 @@ pub fn is_struct_or_union(&self) -> bool {
|
||||
}
|
||||
|
||||
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_static, (&'hir Ty<'hir>, Mutability, BodyId),
|
||||
ItemKind::Static(ty, mutbl, body), (ty, *mutbl, *body);
|
||||
expect_static, (Ident, &'hir Ty<'hir>, Mutability, BodyId),
|
||||
ItemKind::Static(ident, ty, mutbl, body), (*ident, ty, *mutbl, *body);
|
||||
|
||||
expect_const, (&'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
|
||||
ItemKind::Const(ty, generics, body), (ty, generics, *body);
|
||||
expect_const, (Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
|
||||
ItemKind::Const(ident, ty, generics, body), (*ident, ty, generics, *body);
|
||||
|
||||
expect_fn, (&FnSig<'hir>, &'hir Generics<'hir>, BodyId),
|
||||
ItemKind::Fn { sig, generics, body, .. }, (sig, generics, *body);
|
||||
expect_fn, (Ident, &FnSig<'hir>, &'hir Generics<'hir>, BodyId),
|
||||
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]),
|
||||
ItemKind::ForeignMod { abi, items }, (*abi, items);
|
||||
|
||||
expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm;
|
||||
|
||||
expect_ty_alias, (&'hir Ty<'hir>, &'hir Generics<'hir>),
|
||||
ItemKind::TyAlias(ty, generics), (ty, generics);
|
||||
expect_ty_alias, (Ident, &'hir Ty<'hir>, &'hir Generics<'hir>),
|
||||
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>),
|
||||
ItemKind::Struct(data, generics), (data, generics);
|
||||
expect_struct, (Ident, &VariantData<'hir>, &'hir Generics<'hir>),
|
||||
ItemKind::Struct(ident, data, generics), (*ident, data, generics);
|
||||
|
||||
expect_union, (&VariantData<'hir>, &'hir Generics<'hir>),
|
||||
ItemKind::Union(data, generics), (data, generics);
|
||||
expect_union, (Ident, &VariantData<'hir>, &'hir Generics<'hir>),
|
||||
ItemKind::Union(ident, data, generics), (*ident, data, generics);
|
||||
|
||||
expect_trait,
|
||||
(IsAuto, Safety, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]),
|
||||
ItemKind::Trait(is_auto, safety, generics, bounds, items),
|
||||
(*is_auto, *safety, generics, bounds, items);
|
||||
(
|
||||
IsAuto,
|
||||
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>),
|
||||
ItemKind::TraitAlias(generics, bounds), (generics, bounds);
|
||||
expect_trait_alias, (Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
|
||||
ItemKind::TraitAlias(ident, generics, bounds), (*ident, generics, bounds);
|
||||
|
||||
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.
|
||||
///
|
||||
/// 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;`
|
||||
///
|
||||
@@ -4104,11 +4114,12 @@ pub enum ItemKind<'hir> {
|
||||
Use(&'hir UsePath<'hir>, UseKind),
|
||||
|
||||
/// A `static` item.
|
||||
Static(&'hir Ty<'hir>, Mutability, BodyId),
|
||||
Static(Ident, &'hir Ty<'hir>, Mutability, BodyId),
|
||||
/// A `const` item.
|
||||
Const(&'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
|
||||
Const(Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
|
||||
/// A function declaration.
|
||||
Fn {
|
||||
ident: Ident,
|
||||
sig: FnSig<'hir>,
|
||||
generics: &'hir Generics<'hir>,
|
||||
body: BodyId,
|
||||
@@ -4118,9 +4129,9 @@ pub enum ItemKind<'hir> {
|
||||
has_body: bool,
|
||||
},
|
||||
/// A MBE macro definition (`macro_rules!` or `macro`).
|
||||
Macro(&'hir ast::MacroDef, MacroKind),
|
||||
Macro(Ident, &'hir ast::MacroDef, MacroKind),
|
||||
/// A module.
|
||||
Mod(&'hir Mod<'hir>),
|
||||
Mod(Ident, &'hir Mod<'hir>),
|
||||
/// An external module, e.g. `extern { .. }`.
|
||||
ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemRef] },
|
||||
/// Module-level inline assembly (from `global_asm!`).
|
||||
@@ -4134,17 +4145,17 @@ pub enum ItemKind<'hir> {
|
||||
fake_body: BodyId,
|
||||
},
|
||||
/// A type alias, e.g., `type Foo = Bar<u8>`.
|
||||
TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>),
|
||||
/// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`.
|
||||
Enum(EnumDef<'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> }`.
|
||||
Enum(Ident, EnumDef<'hir>, &'hir Generics<'hir>),
|
||||
/// 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}`.
|
||||
Union(VariantData<'hir>, &'hir Generics<'hir>),
|
||||
Union(Ident, VariantData<'hir>, &'hir Generics<'hir>),
|
||||
/// 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.
|
||||
TraitAlias(&'hir Generics<'hir>, GenericBounds<'hir>),
|
||||
TraitAlias(Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
|
||||
|
||||
/// An implementation, e.g., `impl<A> Trait for Foo { .. }`.
|
||||
Impl(&'hir Impl<'hir>),
|
||||
@@ -4173,16 +4184,39 @@ pub struct Impl<'hir> {
|
||||
}
|
||||
|
||||
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<'_>> {
|
||||
Some(match self {
|
||||
ItemKind::Fn { generics, .. }
|
||||
| ItemKind::TyAlias(_, generics)
|
||||
| ItemKind::Const(_, generics, _)
|
||||
| ItemKind::Enum(_, generics)
|
||||
| ItemKind::Struct(_, generics)
|
||||
| ItemKind::Union(_, generics)
|
||||
| ItemKind::Trait(_, _, generics, _, _)
|
||||
| ItemKind::TraitAlias(generics, _)
|
||||
| ItemKind::TyAlias(_, _, generics)
|
||||
| ItemKind::Const(_, _, generics, _)
|
||||
| ItemKind::Enum(_, _, generics)
|
||||
| ItemKind::Struct(_, _, generics)
|
||||
| ItemKind::Union(_, _, generics)
|
||||
| ItemKind::Trait(_, _, _, generics, _, _)
|
||||
| ItemKind::TraitAlias(_, generics, _)
|
||||
| ItemKind::Impl(Impl { generics, .. }) => generics,
|
||||
_ => return None,
|
||||
})
|
||||
@@ -4374,8 +4408,8 @@ pub fn body_id(&self) -> Option<BodyId> {
|
||||
match self {
|
||||
OwnerNode::Item(Item {
|
||||
kind:
|
||||
ItemKind::Static(_, _, body)
|
||||
| ItemKind::Const(_, _, body)
|
||||
ItemKind::Static(_, _, _, body)
|
||||
| ItemKind::Const(_, _, _, body)
|
||||
| ItemKind::Fn { body, .. },
|
||||
..
|
||||
})
|
||||
@@ -4518,12 +4552,12 @@ impl<'hir> Node<'hir> {
|
||||
/// ```
|
||||
pub fn ident(&self) -> Option<Ident> {
|
||||
match self {
|
||||
Node::Item(item) => item.kind.ident(),
|
||||
Node::TraitItem(TraitItem { ident, .. })
|
||||
| Node::ImplItem(ImplItem { ident, .. })
|
||||
| Node::ForeignItem(ForeignItem { ident, .. })
|
||||
| Node::Field(FieldDef { ident, .. })
|
||||
| Node::Variant(Variant { ident, .. })
|
||||
| Node::Item(Item { ident, .. })
|
||||
| Node::PathSegment(PathSegment { ident, .. }) => Some(*ident),
|
||||
Node::Lifetime(lt) => Some(lt.ident),
|
||||
Node::GenericParam(p) => Some(p.name.ident()),
|
||||
@@ -4599,9 +4633,9 @@ pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> {
|
||||
pub fn ty(self) -> Option<&'hir Ty<'hir>> {
|
||||
match self {
|
||||
Node::Item(it) => match it.kind {
|
||||
ItemKind::TyAlias(ty, _)
|
||||
| ItemKind::Static(ty, _, _)
|
||||
| ItemKind::Const(ty, _, _) => Some(ty),
|
||||
ItemKind::TyAlias(_, ty, _)
|
||||
| ItemKind::Static(_, ty, _, _)
|
||||
| ItemKind::Const(_, ty, _, _) => Some(ty),
|
||||
ItemKind::Impl(impl_item) => Some(&impl_item.self_ty),
|
||||
_ => None,
|
||||
},
|
||||
@@ -4621,7 +4655,7 @@ pub fn ty(self) -> Option<&'hir Ty<'hir>> {
|
||||
|
||||
pub fn alias_ty(self) -> Option<&'hir Ty<'hir>> {
|
||||
match self {
|
||||
Node::Item(Item { kind: ItemKind::TyAlias(ty, ..), .. }) => Some(ty),
|
||||
Node::Item(Item { kind: ItemKind::TyAlias(_, ty, _), .. }) => Some(ty),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -4632,7 +4666,9 @@ pub fn associated_body(&self) -> Option<(LocalDefId, BodyId)> {
|
||||
Node::Item(Item {
|
||||
owner_id,
|
||||
kind:
|
||||
ItemKind::Const(_, _, body) | ItemKind::Static(.., body) | ItemKind::Fn { body, .. },
|
||||
ItemKind::Const(_, _, _, body)
|
||||
| ItemKind::Static(.., body)
|
||||
| ItemKind::Fn { body, .. },
|
||||
..
|
||||
})
|
||||
| Node::TraitItem(TraitItem {
|
||||
@@ -4693,8 +4729,8 @@ pub fn as_owner(self) -> Option<OwnerNode<'hir>> {
|
||||
pub fn fn_kind(self) -> Option<FnKind<'hir>> {
|
||||
match self {
|
||||
Node::Item(i) => match i.kind {
|
||||
ItemKind::Fn { sig, generics, .. } => {
|
||||
Some(FnKind::ItemFn(i.ident, generics, sig.header))
|
||||
ItemKind::Fn { ident, sig, generics, .. } => {
|
||||
Some(FnKind::ItemFn(ident, generics, sig.header))
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
@@ -4767,7 +4803,7 @@ mod size_asserts {
|
||||
static_assert_size!(ImplItem<'_>, 88);
|
||||
static_assert_size!(ImplItemKind<'_>, 40);
|
||||
static_assert_size!(Item<'_>, 88);
|
||||
static_assert_size!(ItemKind<'_>, 56);
|
||||
static_assert_size!(ItemKind<'_>, 64);
|
||||
static_assert_size!(LetStmt<'_>, 64);
|
||||
static_assert_size!(Param<'_>, 32);
|
||||
static_assert_size!(Pat<'_>, 72);
|
||||
|
||||
@@ -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 {
|
||||
try_visit!(visitor.visit_id(item.hir_id()));
|
||||
try_visit!(visitor.visit_ident(item.ident));
|
||||
match item.kind {
|
||||
ItemKind::ExternCrate(orig_name) => {
|
||||
ItemKind::ExternCrate(orig_name, ident) => {
|
||||
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()));
|
||||
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_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_generics(generics));
|
||||
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(
|
||||
FnKind::ItemFn(item.ident, generics, sig.header),
|
||||
FnKind::ItemFn(ident, generics, sig.header),
|
||||
sig.decl,
|
||||
body_id,
|
||||
item.span,
|
||||
item.owner_id.def_id,
|
||||
));
|
||||
}
|
||||
ItemKind::Macro(..) => {}
|
||||
ItemKind::Mod(ref module) => {
|
||||
ItemKind::Macro(ident, _def, _kind) => {
|
||||
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()));
|
||||
}
|
||||
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.
|
||||
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_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_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));
|
||||
walk_list!(visitor, visit_impl_item_ref, *items);
|
||||
}
|
||||
ItemKind::Struct(ref struct_definition, ref generics)
|
||||
| ItemKind::Union(ref struct_definition, ref generics) => {
|
||||
ItemKind::Struct(ident, 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_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));
|
||||
walk_list!(visitor, visit_param_bound, bounds);
|
||||
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));
|
||||
walk_list!(visitor, visit_param_bound, bounds);
|
||||
}
|
||||
|
||||
@@ -269,26 +269,26 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
|
||||
}
|
||||
res
|
||||
}
|
||||
hir::ItemKind::Fn { sig, .. } => {
|
||||
check_item_fn(tcx, def_id, item.ident, item.span, sig.decl)
|
||||
hir::ItemKind::Fn { ident, sig, .. } => {
|
||||
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)
|
||||
}
|
||||
hir::ItemKind::Const(ty, ..) => {
|
||||
hir::ItemKind::Const(_, ty, ..) => {
|
||||
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);
|
||||
check_variances_for_type_defn(tcx, item, hir_generics);
|
||||
res
|
||||
}
|
||||
hir::ItemKind::Union(_, hir_generics) => {
|
||||
hir::ItemKind::Union(_, _, hir_generics) => {
|
||||
let res = check_type_defn(tcx, item, true);
|
||||
check_variances_for_type_defn(tcx, item, hir_generics);
|
||||
res
|
||||
}
|
||||
hir::ItemKind::Enum(_, hir_generics) => {
|
||||
hir::ItemKind::Enum(_, _, hir_generics) => {
|
||||
let res = check_type_defn(tcx, item, true);
|
||||
check_variances_for_type_defn(tcx, item, hir_generics);
|
||||
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),
|
||||
// `ForeignItem`s are handled separately.
|
||||
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 ty = tcx.type_of(def_id).instantiate_identity();
|
||||
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.
|
||||
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) {
|
||||
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,
|
||||
@@ -862,7 +864,7 @@ fn check_dyn_incompatible_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitI
|
||||
trait_should_be_self,
|
||||
"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(
|
||||
"you might have meant to use `Self` to refer to the implementing type",
|
||||
sugg,
|
||||
|
||||
@@ -247,13 +247,13 @@ fn reject_placeholder_type_signatures_in_item<'tcx>(
|
||||
item: &'tcx hir::Item<'tcx>,
|
||||
) {
|
||||
let (generics, suggest) = match &item.kind {
|
||||
hir::ItemKind::Union(_, generics)
|
||||
| hir::ItemKind::Enum(_, generics)
|
||||
| hir::ItemKind::TraitAlias(generics, _)
|
||||
| hir::ItemKind::Trait(_, _, generics, ..)
|
||||
hir::ItemKind::Union(_, _, generics)
|
||||
| hir::ItemKind::Enum(_, _, generics)
|
||||
| hir::ItemKind::TraitAlias(_, generics, _)
|
||||
| hir::ItemKind::Trait(_, _, _, generics, ..)
|
||||
| hir::ItemKind::Impl(hir::Impl { generics, .. })
|
||||
| hir::ItemKind::Struct(_, generics) => (generics, true),
|
||||
hir::ItemKind::TyAlias(_, generics) => (generics, false),
|
||||
| hir::ItemKind::Struct(_, _, generics) => (generics, true),
|
||||
hir::ItemKind::TyAlias(_, _, generics) => (generics, false),
|
||||
// `static`, `fn` and `const` are handled elsewhere to suggest appropriate type.
|
||||
_ => return,
|
||||
};
|
||||
@@ -470,9 +470,9 @@ fn lower_assoc_shared(
|
||||
.tcx
|
||||
.hir_expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id);
|
||||
match &item.kind {
|
||||
hir::ItemKind::Enum(_, generics)
|
||||
| hir::ItemKind::Struct(_, generics)
|
||||
| hir::ItemKind::Union(_, generics) => {
|
||||
hir::ItemKind::Enum(_, _, generics)
|
||||
| hir::ItemKind::Struct(_, _, generics)
|
||||
| hir::ItemKind::Union(_, _, generics) => {
|
||||
let lt_name = get_new_lifetime_name(self.tcx, poly_trait_ref, generics);
|
||||
let (lt_sp, sugg) = match generics.params {
|
||||
[] => (generics.span, format!("<{lt_name}>")),
|
||||
@@ -667,16 +667,16 @@ fn get_new_lifetime_name<'tcx>(
|
||||
#[instrument(level = "debug", skip_all)]
|
||||
fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
||||
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 icx = ItemCtxt::new(tcx, def_id);
|
||||
|
||||
match &it.kind {
|
||||
// These don't define types.
|
||||
hir::ItemKind::ExternCrate(_)
|
||||
hir::ItemKind::ExternCrate(..)
|
||||
| hir::ItemKind::Use(..)
|
||||
| hir::ItemKind::Macro(..)
|
||||
| hir::ItemKind::Mod(_)
|
||||
| hir::ItemKind::Mod(..)
|
||||
| hir::ItemKind::GlobalAsm { .. } => {}
|
||||
hir::ItemKind::ForeignMod { 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.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().type_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);
|
||||
}
|
||||
|
||||
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().type_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 (kind, variants) = match &item.kind {
|
||||
ItemKind::Enum(def, _) => {
|
||||
ItemKind::Enum(_, def, _) => {
|
||||
let mut distance_from_explicit = 0;
|
||||
let variants = def
|
||||
.variants
|
||||
@@ -1117,7 +1117,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
|
||||
|
||||
(AdtKind::Enum, variants)
|
||||
}
|
||||
ItemKind::Struct(def, _) | ItemKind::Union(def, _) => {
|
||||
ItemKind::Struct(ident, def, _) | ItemKind::Union(ident, def, _) => {
|
||||
let adt_kind = match item.kind {
|
||||
ItemKind::Struct(..) => AdtKind::Struct,
|
||||
_ => AdtKind::Union,
|
||||
@@ -1125,7 +1125,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
|
||||
let variants = std::iter::once(lower_variant(
|
||||
tcx,
|
||||
None,
|
||||
item.ident,
|
||||
*ident,
|
||||
ty::VariantDiscr::Relative(0),
|
||||
def,
|
||||
adt_kind,
|
||||
|
||||
@@ -134,7 +134,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
|
||||
};
|
||||
tcx.vtable_entries(trait_ref)
|
||||
}
|
||||
hir::ItemKind::TyAlias(_, _) => {
|
||||
hir::ItemKind::TyAlias(..) => {
|
||||
let ty = tcx.type_of(def_id).instantiate_identity();
|
||||
if ty.has_non_region_param() {
|
||||
tcx.dcx().span_err(
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
_ => {}
|
||||
@@ -615,7 +616,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
|
||||
|
||||
let (generics, superbounds) = match item.kind {
|
||||
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"),
|
||||
};
|
||||
|
||||
@@ -959,7 +960,7 @@ pub(super) fn const_conditions<'tcx>(
|
||||
Node::Item(item) => match item.kind {
|
||||
hir::ItemKind::Impl(impl_) => (impl_.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)
|
||||
}
|
||||
_ => bug!("const_conditions called on wrong item: {def_id:?}"),
|
||||
|
||||
@@ -617,7 +617,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
||||
});
|
||||
}
|
||||
|
||||
hir::ItemKind::ExternCrate(_)
|
||||
hir::ItemKind::ExternCrate(..)
|
||||
| hir::ItemKind::Use(..)
|
||||
| hir::ItemKind::Macro(..)
|
||||
| hir::ItemKind::Mod(..)
|
||||
@@ -627,13 +627,13 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
||||
// These sorts of items have no lifetime parameters at all.
|
||||
intravisit::walk_item(self, item);
|
||||
}
|
||||
hir::ItemKind::TyAlias(_, generics)
|
||||
| hir::ItemKind::Const(_, generics, _)
|
||||
| hir::ItemKind::Enum(_, generics)
|
||||
| hir::ItemKind::Struct(_, generics)
|
||||
| hir::ItemKind::Union(_, generics)
|
||||
| hir::ItemKind::Trait(_, _, generics, ..)
|
||||
| hir::ItemKind::TraitAlias(generics, ..)
|
||||
hir::ItemKind::TyAlias(_, _, generics)
|
||||
| hir::ItemKind::Const(_, _, generics, _)
|
||||
| hir::ItemKind::Enum(_, _, generics)
|
||||
| hir::ItemKind::Struct(_, _, generics)
|
||||
| hir::ItemKind::Union(_, _, generics)
|
||||
| hir::ItemKind::Trait(_, _, _, generics, ..)
|
||||
| hir::ItemKind::TraitAlias(_, generics, ..)
|
||||
| hir::ItemKind::Impl(&hir::Impl { generics, .. }) => {
|
||||
// These kinds of items have only early-bound lifetime parameters.
|
||||
self.visit_early(item.hir_id(), generics, |this| intravisit::walk_item(this, item));
|
||||
|
||||
@@ -202,35 +202,35 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
|
||||
},
|
||||
|
||||
Node::Item(item) => match item.kind {
|
||||
ItemKind::Static(ty, .., body_id) => {
|
||||
ItemKind::Static(ident, ty, .., body_id) => {
|
||||
if ty.is_suggestable_infer_ty() {
|
||||
infer_placeholder_type(
|
||||
icx.lowerer(),
|
||||
def_id,
|
||||
body_id,
|
||||
ty.span,
|
||||
item.ident,
|
||||
ident,
|
||||
"static variable",
|
||||
)
|
||||
} else {
|
||||
icx.lower_ty(ty)
|
||||
}
|
||||
}
|
||||
ItemKind::Const(ty, _, body_id) => {
|
||||
ItemKind::Const(ident, ty, _, body_id) => {
|
||||
if ty.is_suggestable_infer_ty() {
|
||||
infer_placeholder_type(
|
||||
icx.lowerer(),
|
||||
def_id,
|
||||
body_id,
|
||||
ty.span,
|
||||
item.ident,
|
||||
ident,
|
||||
"constant",
|
||||
)
|
||||
} else {
|
||||
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() {
|
||||
spans if spans.len() > 0 => {
|
||||
let guar = tcx
|
||||
@@ -479,5 +479,5 @@ fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx, AmbigArg>) -> Self::Result {
|
||||
}
|
||||
}
|
||||
}
|
||||
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()
|
||||
}
|
||||
|
||||
@@ -140,14 +140,15 @@ fn maybe_suggest_add_generic_impl_trait(
|
||||
|
||||
let generics = match tcx.hir_node_by_def_id(parent_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) {
|
||||
return false;
|
||||
}
|
||||
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
|
||||
.variants
|
||||
.iter()
|
||||
@@ -267,7 +268,7 @@ fn maybe_suggest_dyn_trait(
|
||||
hir::Node::Field(field) => {
|
||||
// Enums can't have unsized fields, fields can only have an unsized tail field.
|
||||
if let hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Struct(variant, _), ..
|
||||
kind: hir::ItemKind::Struct(_, variant, _), ..
|
||||
}) = tcx.parent_hir_node(field.hir_id)
|
||||
&& variant
|
||||
.fields()
|
||||
|
||||
@@ -136,9 +136,9 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
|
||||
ref item => bug!("Unexpected TraitItem {:?}", item),
|
||||
},
|
||||
hir::Node::Item(item) => match item.kind {
|
||||
hir::ItemKind::TyAlias(ty, _)
|
||||
| hir::ItemKind::Static(ty, _, _)
|
||||
| hir::ItemKind::Const(ty, _, _) => vec![ty],
|
||||
hir::ItemKind::TyAlias(_, ty, _)
|
||||
| hir::ItemKind::Static(_, ty, _, _)
|
||||
| hir::ItemKind::Const(_, ty, _, _) => vec![ty],
|
||||
hir::ItemKind::Impl(impl_) => match &impl_.of_trait {
|
||||
Some(t) => t
|
||||
.path
|
||||
|
||||
@@ -559,7 +559,7 @@ fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
self.print_attrs_as_outer(attrs);
|
||||
self.ann.pre(self, AnnNode::Item(item));
|
||||
match item.kind {
|
||||
hir::ItemKind::ExternCrate(orig_name) => {
|
||||
hir::ItemKind::ExternCrate(orig_name, ident) => {
|
||||
self.head("extern crate");
|
||||
if let Some(orig_name) = orig_name {
|
||||
self.print_name(orig_name);
|
||||
@@ -567,7 +567,7 @@ fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
self.word("as");
|
||||
self.space();
|
||||
}
|
||||
self.print_ident(item.ident);
|
||||
self.print_ident(ident);
|
||||
self.word(";");
|
||||
self.end(); // end inner head-block
|
||||
self.end(); // end outer head-block
|
||||
@@ -577,11 +577,11 @@ fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
self.print_path(path, false);
|
||||
|
||||
match kind {
|
||||
hir::UseKind::Single => {
|
||||
if path.segments.last().unwrap().ident != item.ident {
|
||||
hir::UseKind::Single(ident) => {
|
||||
if path.segments.last().unwrap().ident != ident {
|
||||
self.space();
|
||||
self.word_space("as");
|
||||
self.print_ident(item.ident);
|
||||
self.print_ident(ident);
|
||||
}
|
||||
self.word(";");
|
||||
}
|
||||
@@ -591,12 +591,12 @@ fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
self.end(); // end inner head-block
|
||||
self.end(); // end outer head-block
|
||||
}
|
||||
hir::ItemKind::Static(ty, m, expr) => {
|
||||
hir::ItemKind::Static(ident, ty, m, expr) => {
|
||||
self.head("static");
|
||||
if m.is_mut() {
|
||||
self.word_space("mut");
|
||||
}
|
||||
self.print_ident(item.ident);
|
||||
self.print_ident(ident);
|
||||
self.word_space(":");
|
||||
self.print_type(ty);
|
||||
self.space();
|
||||
@@ -607,9 +607,9 @@ fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
self.word(";");
|
||||
self.end(); // end the outer cbox
|
||||
}
|
||||
hir::ItemKind::Const(ty, generics, expr) => {
|
||||
hir::ItemKind::Const(ident, ty, generics, expr) => {
|
||||
self.head("const");
|
||||
self.print_ident(item.ident);
|
||||
self.print_ident(ident);
|
||||
self.print_generic_params(generics.params);
|
||||
self.word_space(":");
|
||||
self.print_type(ty);
|
||||
@@ -622,30 +622,23 @@ fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
self.word(";");
|
||||
self.end(); // end the outer cbox
|
||||
}
|
||||
hir::ItemKind::Fn { sig, generics, body, .. } => {
|
||||
hir::ItemKind::Fn { ident, sig, generics, body, .. } => {
|
||||
self.head("");
|
||||
self.print_fn(
|
||||
sig.decl,
|
||||
sig.header,
|
||||
Some(item.ident.name),
|
||||
generics,
|
||||
&[],
|
||||
Some(body),
|
||||
);
|
||||
self.print_fn(sig.decl, sig.header, Some(ident.name), generics, &[], Some(body));
|
||||
self.word(" ");
|
||||
self.end(); // need to close a box
|
||||
self.end(); // need to close a box
|
||||
self.ann.nested(self, Nested::Body(body));
|
||||
}
|
||||
hir::ItemKind::Macro(macro_def, _) => {
|
||||
self.print_mac_def(macro_def, &item.ident, item.span, |_| {});
|
||||
hir::ItemKind::Macro(ident, macro_def, _) => {
|
||||
self.print_mac_def(macro_def, &ident, item.span, |_| {});
|
||||
}
|
||||
hir::ItemKind::Mod(_mod) => {
|
||||
hir::ItemKind::Mod(ident, mod_) => {
|
||||
self.head("mod");
|
||||
self.print_ident(item.ident);
|
||||
self.print_ident(ident);
|
||||
self.nbsp();
|
||||
self.bopen();
|
||||
self.print_mod(_mod, attrs);
|
||||
self.print_mod(mod_, attrs);
|
||||
self.bclose(item.span);
|
||||
}
|
||||
hir::ItemKind::ForeignMod { abi, items } => {
|
||||
@@ -663,9 +656,9 @@ fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
self.print_inline_asm(asm);
|
||||
self.end()
|
||||
}
|
||||
hir::ItemKind::TyAlias(ty, generics) => {
|
||||
hir::ItemKind::TyAlias(ident, ty, generics) => {
|
||||
self.head("type");
|
||||
self.print_ident(item.ident);
|
||||
self.print_ident(ident);
|
||||
self.print_generic_params(generics.params);
|
||||
self.end(); // end the inner ibox
|
||||
|
||||
@@ -676,16 +669,16 @@ fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
self.word(";");
|
||||
self.end(); // end the outer ibox
|
||||
}
|
||||
hir::ItemKind::Enum(ref enum_definition, params) => {
|
||||
self.print_enum_def(enum_definition, params, item.ident.name, item.span);
|
||||
hir::ItemKind::Enum(ident, ref enum_definition, params) => {
|
||||
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.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.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 {
|
||||
constness,
|
||||
@@ -733,12 +726,12 @@ fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
}
|
||||
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.print_is_auto(is_auto);
|
||||
self.print_safety(safety);
|
||||
self.word_nbsp("trait");
|
||||
self.print_ident(item.ident);
|
||||
self.print_ident(ident);
|
||||
self.print_generic_params(generics.params);
|
||||
self.print_bounds(":", bounds);
|
||||
self.print_where_clause(generics);
|
||||
@@ -749,9 +742,9 @@ fn print_item(&mut self, item: &hir::Item<'_>) {
|
||||
}
|
||||
self.bclose(item.span);
|
||||
}
|
||||
hir::ItemKind::TraitAlias(generics, bounds) => {
|
||||
hir::ItemKind::TraitAlias(ident, generics, bounds) => {
|
||||
self.head("trait");
|
||||
self.print_ident(item.ident);
|
||||
self.print_ident(ident);
|
||||
self.print_generic_params(generics.params);
|
||||
self.nbsp();
|
||||
self.print_bounds("=", bounds);
|
||||
|
||||
@@ -713,8 +713,8 @@ fn report_invalid_callee(
|
||||
for id in self.tcx.hir_free_items() {
|
||||
if let Some(node) = self.tcx.hir_get_if_local(id.owner_id.into())
|
||||
&& let hir::Node::Item(item) = node
|
||||
&& let hir::ItemKind::Fn { .. } = item.kind
|
||||
&& item.ident.name == segment.ident.name
|
||||
&& let hir::ItemKind::Fn { ident, .. } = item.kind
|
||||
&& ident.name == segment.ident.name
|
||||
{
|
||||
err.span_label(
|
||||
self.tcx.def_span(id.owner_id),
|
||||
|
||||
@@ -721,8 +721,9 @@ fn annotate_expected_due_to_let_ty(
|
||||
},
|
||||
)) => {
|
||||
if let Some(hir::Node::Item(hir::Item {
|
||||
ident,
|
||||
kind: hir::ItemKind::Static(ty, ..) | hir::ItemKind::Const(ty, ..),
|
||||
kind:
|
||||
hir::ItemKind::Static(ident, ty, ..)
|
||||
| hir::ItemKind::Const(ident, ty, ..),
|
||||
..
|
||||
})) = self.tcx.hir_get_if_local(*def_id)
|
||||
{
|
||||
|
||||
@@ -904,7 +904,8 @@ pub(in super::super) fn suggest_missing_return_type(
|
||||
/// Assumes given function doesn't have a explicit return type.
|
||||
fn can_add_return_type(&self, fn_id: LocalDefId) -> bool {
|
||||
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
|
||||
// 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.
|
||||
|
||||
@@ -367,20 +367,21 @@ fn trait_path(&self, span: Span, expr_hir_id: HirId, trait_def_id: DefId) -> Opt
|
||||
.collect();
|
||||
|
||||
// Find an identifier with which this trait was imported (note that `_` doesn't count).
|
||||
let any_id = import_items.iter().find_map(|item| {
|
||||
if item.ident.name != kw::Underscore { Some(item.ident) } else { None }
|
||||
});
|
||||
if let Some(any_id) = any_id {
|
||||
if any_id.name == kw::Empty {
|
||||
// Glob import, so just use its name.
|
||||
return None;
|
||||
} else {
|
||||
return Some(format!("{any_id}"));
|
||||
for item in import_items.iter() {
|
||||
let (_, kind) = item.expect_use();
|
||||
match kind {
|
||||
hir::UseKind::Single(ident) => {
|
||||
if ident.name != kw::Underscore {
|
||||
return Some(format!("{}", ident.name));
|
||||
}
|
||||
}
|
||||
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,
|
||||
// so just take the first one.
|
||||
// All that is left is `_`! We need to use the full path. It doesn't matter which one we
|
||||
// pick, so just take the first one.
|
||||
match import_items[0].kind {
|
||||
ItemKind::Use(path, _) => Some(
|
||||
path.segments
|
||||
|
||||
@@ -1204,13 +1204,14 @@ fn report_no_match_method_error(
|
||||
}
|
||||
Some(
|
||||
Node::Item(hir::Item {
|
||||
ident,
|
||||
kind: hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..),
|
||||
kind:
|
||||
hir::ItemKind::Trait(_, _, ident, ..)
|
||||
| hir::ItemKind::TraitAlias(ident, ..),
|
||||
..
|
||||
})
|
||||
// We may also encounter unsatisfied GAT or method bounds
|
||||
| Node::TraitItem(hir::TraitItem { ident, .. })
|
||||
| Node::ImplItem(hir::ImplItem { ident, .. }),
|
||||
| Node::ImplItem(hir::ImplItem { ident, .. })
|
||||
) => {
|
||||
skip_list.insert(p);
|
||||
let entry = spanned_predicates.entry(ident.span);
|
||||
@@ -3960,8 +3961,7 @@ enum Introducer {
|
||||
return;
|
||||
}
|
||||
Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Trait(.., bounds, _),
|
||||
ident,
|
||||
kind: hir::ItemKind::Trait(_, _, ident, _, bounds, _),
|
||||
..
|
||||
}) => {
|
||||
let (sp, sep, article) = if bounds.is_empty() {
|
||||
|
||||
@@ -1250,7 +1250,7 @@ fn maybe_suggest_range_literal(
|
||||
match opt_def_id {
|
||||
Some(def_id) => match self.tcx.hir_get_if_local(def_id) {
|
||||
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) {
|
||||
hir::Node::Expr(expr) => {
|
||||
|
||||
@@ -441,7 +441,7 @@ fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
|
||||
// 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.
|
||||
if let hir::ItemKind::Impl(..) | hir::ItemKind::Use(..) | hir::ItemKind::ExternCrate(_) =
|
||||
if let hir::ItemKind::Impl(..) | hir::ItemKind::Use(..) | hir::ItemKind::ExternCrate(..) =
|
||||
it.kind
|
||||
{
|
||||
return;
|
||||
@@ -545,21 +545,21 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
|
||||
return;
|
||||
}
|
||||
let (def, ty) = match item.kind {
|
||||
hir::ItemKind::Struct(_, ast_generics) => {
|
||||
hir::ItemKind::Struct(_, _, ast_generics) => {
|
||||
if !ast_generics.params.is_empty() {
|
||||
return;
|
||||
}
|
||||
let def = cx.tcx.adt_def(item.owner_id);
|
||||
(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() {
|
||||
return;
|
||||
}
|
||||
let def = cx.tcx.adt_def(item.owner_id);
|
||||
(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() {
|
||||
return;
|
||||
}
|
||||
@@ -1416,7 +1416,7 @@ pub(crate) fn affects_object_lifetime_defaults(pred: &hir::WherePredicate<'_>) -
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
|
||||
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.
|
||||
if generics.predicates.is_empty() {
|
||||
@@ -2119,9 +2119,9 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
|
||||
use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
|
||||
|
||||
let def_id = item.owner_id.def_id;
|
||||
if let hir::ItemKind::Struct(_, hir_generics)
|
||||
| hir::ItemKind::Enum(_, hir_generics)
|
||||
| hir::ItemKind::Union(_, hir_generics) = item.kind
|
||||
if let hir::ItemKind::Struct(_, _, hir_generics)
|
||||
| hir::ItemKind::Enum(_, _, hir_generics)
|
||||
| hir::ItemKind::Union(_, _, hir_generics) = item.kind
|
||||
{
|
||||
let inferred_outlives = cx.tcx.inferred_outlives_of(def_id);
|
||||
if inferred_outlives.is_empty() {
|
||||
@@ -2257,7 +2257,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
|
||||
// generics, except for tuple struct, which have the `where`
|
||||
// after the fields of the struct.
|
||||
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
|
||||
} else {
|
||||
hir_generics.span.shrink_to_hi().to(where_span)
|
||||
|
||||
@@ -93,7 +93,11 @@ fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_
|
||||
let orig_fields = match cx.tcx.hir_get_if_local(type_def_id) {
|
||||
Some(hir::Node::Item(hir::Item {
|
||||
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<_, _>>(),
|
||||
_ => return,
|
||||
|
||||
@@ -308,18 +308,18 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
[.., penultimate, segment]
|
||||
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]
|
||||
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) =
|
||||
match cx.tcx.sess.source_map().span_to_snippet(path.span).as_deref() {
|
||||
Ok("self") => (path.span, "*"),
|
||||
_ => (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,
|
||||
};
|
||||
|
||||
@@ -39,7 +39,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
||||
let def_id = item.owner_id.to_def_id();
|
||||
// NOTE(nbdd0121): use `dyn_compatibility_violations` instead of `is_dyn_compatible` because
|
||||
// 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)
|
||||
{
|
||||
let direct_super_traits_iter = cx
|
||||
@@ -51,7 +51,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
||||
cx.emit_span_lint(
|
||||
MULTIPLE_SUPERTRAIT_UPCASTABLE,
|
||||
cx.tcx.def_span(def_id),
|
||||
crate::lints::MultipleSupertraitUpcastable { ident: item.ident },
|
||||
crate::lints::MultipleSupertraitUpcastable { ident },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,10 +181,10 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
&& parent_opt_item_name != Some(kw::Underscore)
|
||||
&& let Some(parent) = parent.as_local()
|
||||
&& 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
|
||||
{
|
||||
Some(item.ident.span)
|
||||
Some(ident.span)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -238,7 +238,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
},
|
||||
)
|
||||
}
|
||||
ItemKind::Macro(_macro, MacroKind::Bang)
|
||||
ItemKind::Macro(_, _macro, MacroKind::Bang)
|
||||
if cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) =>
|
||||
{
|
||||
cx.emit_span_lint(
|
||||
|
||||
@@ -415,8 +415,8 @@ fn check_fn(
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
|
||||
if let hir::ItemKind::Mod(_) = it.kind {
|
||||
self.check_snake_case(cx, "module", &it.ident);
|
||||
if let hir::ItemKind::Mod(ident, _) = it.kind {
|
||||
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<'_>) {
|
||||
let attrs = cx.tcx.hir_attrs(it.hir_id());
|
||||
match it.kind {
|
||||
hir::ItemKind::Static(..) if !ast::attr::contains_name(attrs, sym::no_mangle) => {
|
||||
NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident);
|
||||
hir::ItemKind::Static(ident, ..)
|
||||
if !ast::attr::contains_name(attrs, sym::no_mangle) =>
|
||||
{
|
||||
NonUpperCaseGlobals::check_upper_case(cx, "static variable", &ident);
|
||||
}
|
||||
hir::ItemKind::Const(..) => {
|
||||
NonUpperCaseGlobals::check_upper_case(cx, "constant", &it.ident);
|
||||
hir::ItemKind::Const(ident, ..) => {
|
||||
NonUpperCaseGlobals::check_upper_case(cx, "constant", &ident);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@@ -1664,7 +1664,7 @@ fn check_struct_for_power_alignment<'tcx>(
|
||||
&& cx.tcx.sess.target.os == "aix"
|
||||
&& !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() {
|
||||
// Struct fields (after the first field) are checked for the
|
||||
// power alignment rule, as fields after the first are likely
|
||||
@@ -1696,9 +1696,9 @@ fn check_struct_for_power_alignment<'tcx>(
|
||||
impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions {
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
||||
match item.kind {
|
||||
hir::ItemKind::Static(ty, ..)
|
||||
| hir::ItemKind::Const(ty, ..)
|
||||
| hir::ItemKind::TyAlias(ty, ..) => {
|
||||
hir::ItemKind::Static(_, ty, ..)
|
||||
| hir::ItemKind::Const(_, ty, ..)
|
||||
| hir::ItemKind::TyAlias(_, ty, ..) => {
|
||||
self.check_ty_maybe_containing_foreign_fnptr(
|
||||
cx,
|
||||
ty,
|
||||
@@ -1765,7 +1765,7 @@ fn check_fn(
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences {
|
||||
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 ty = cx.tcx.erase_regions(t);
|
||||
let Ok(layout) = cx.layout_of(ty) else { return };
|
||||
|
||||
@@ -1835,7 +1835,7 @@ fn encode_deprecation(&mut self, def_id: DefId) {
|
||||
fn encode_info_for_macro(&mut self, def_id: LocalDefId) {
|
||||
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);
|
||||
record!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body);
|
||||
}
|
||||
|
||||
@@ -385,7 +385,7 @@ pub fn hir_rustc_coherence_is_core(self) -> bool {
|
||||
pub fn hir_get_module(self, module: LocalModDefId) -> (&'tcx Mod<'tcx>, Span, HirId) {
|
||||
let hir_id = HirId::make_owner(module.to_local_def_id());
|
||||
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),
|
||||
node => panic!("not a module: {node:?}"),
|
||||
}
|
||||
@@ -847,7 +847,7 @@ fn hir_opt_ident(self, id: HirId) -> Option<Ident> {
|
||||
// A `Ctor` doesn't have an identifier itself, but its parent
|
||||
// struct/variant does. Compare with `hir::Map::span`.
|
||||
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),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
@@ -894,18 +894,14 @@ fn until_within(outer: Span, end: Span) -> 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);
|
||||
if let Some(g) = generics
|
||||
&& !g.span.is_dummy()
|
||||
&& let Some(g_span) = g.span.find_ancestor_inside(item_span)
|
||||
{
|
||||
span = span.to(g_span);
|
||||
}
|
||||
span
|
||||
} else {
|
||||
item_span
|
||||
let mut span = until_within(item_span, ident.span);
|
||||
if let Some(g) = generics
|
||||
&& !g.span.is_dummy()
|
||||
&& let Some(g_span) = g.span.find_ancestor_inside(item_span)
|
||||
{
|
||||
span = span.to(g_span);
|
||||
}
|
||||
span
|
||||
}
|
||||
|
||||
let span = match self.tcx.hir_node(hir_id) {
|
||||
@@ -936,7 +932,7 @@ fn named_span(item_span: Span, ident: Ident, generics: Option<&Generics<'_>>) ->
|
||||
}) => until_within(*outer_span, generics.where_clause_span),
|
||||
// Constants and Statics.
|
||||
Node::Item(Item {
|
||||
kind: ItemKind::Const(ty, ..) | ItemKind::Static(ty, ..),
|
||||
kind: ItemKind::Const(_, ty, ..) | ItemKind::Static(_, ty, ..),
|
||||
span: outer_span,
|
||||
..
|
||||
})
|
||||
@@ -957,7 +953,7 @@ fn named_span(item_span: Span, ident: Ident, generics: Option<&Generics<'_>>) ->
|
||||
}) => until_within(*outer_span, ty.span),
|
||||
// With generics and bounds.
|
||||
Node::Item(Item {
|
||||
kind: ItemKind::Trait(_, _, generics, bounds, _),
|
||||
kind: ItemKind::Trait(_, _, _, generics, bounds, _),
|
||||
span: outer_span,
|
||||
..
|
||||
})
|
||||
@@ -977,7 +973,13 @@ fn named_span(item_span: Span, ident: Ident, generics: Option<&Generics<'_>>) ->
|
||||
// SyntaxContext of the path.
|
||||
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::ImplItem(item) => named_span(item.span, item.ident, Some(item.generics)),
|
||||
@@ -1327,7 +1329,7 @@ fn visit_item(&mut self, item: &'hir Item<'hir>) {
|
||||
self.items.push(item.item_id());
|
||||
|
||||
// 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);
|
||||
// A module collector does not recurse inside nested modules.
|
||||
if self.crate_collector {
|
||||
|
||||
@@ -3406,20 +3406,18 @@ macro_rules! define_print_and_forward_display {
|
||||
}
|
||||
|
||||
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() {
|
||||
if matches!(tcx.def_kind(id.owner_id), DefKind::Use) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let item = tcx.hir_item(id);
|
||||
if item.ident.name == kw::Empty {
|
||||
continue;
|
||||
}
|
||||
let Some(ident) = item.kind.ident() else { continue };
|
||||
|
||||
let def_id = item.owner_id.to_def_id();
|
||||
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.
|
||||
|
||||
@@ -563,7 +563,7 @@ fn construct_const<'a, 'tcx>(
|
||||
// Figure out what primary body this item has.
|
||||
let (span, const_ty_span) = match tcx.hir_node(hir_id) {
|
||||
Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _, _),
|
||||
kind: hir::ItemKind::Static(_, ty, _, _) | hir::ItemKind::Const(_, ty, _, _),
|
||||
span,
|
||||
..
|
||||
})
|
||||
|
||||
@@ -1044,7 +1044,6 @@ fn find_fallback_pattern_typo<'tcx>(
|
||||
if let DefKind::Use = cx.tcx.def_kind(item.owner_id) {
|
||||
// Look for consts being re-exported.
|
||||
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 {
|
||||
continue;
|
||||
};
|
||||
@@ -1064,8 +1063,9 @@ fn find_fallback_pattern_typo<'tcx>(
|
||||
{
|
||||
// The const is accessible only through the re-export, point at
|
||||
// the `use`.
|
||||
imported.push(use_name);
|
||||
imported_spans.push(item.ident.span);
|
||||
let ident = item.kind.ident().unwrap();
|
||||
imported.push(ident.name);
|
||||
imported_spans.push(ident.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -743,7 +743,7 @@ fn check_non_exhaustive(
|
||||
match target {
|
||||
Target::Struct => {
|
||||
if let Some(ItemLike::Item(hir::Item {
|
||||
kind: hir::ItemKind::Struct(hir::VariantData::Struct { fields, .. }, _),
|
||||
kind: hir::ItemKind::Struct(_, hir::VariantData::Struct { fields, .. }, _),
|
||||
..
|
||||
})) = item
|
||||
&& !fields.is_empty()
|
||||
@@ -1019,7 +1019,7 @@ fn is_doc_keyword(s: Symbol) -> bool {
|
||||
_ => None,
|
||||
};
|
||||
match item_kind {
|
||||
Some(ItemKind::Mod(module)) => {
|
||||
Some(ItemKind::Mod(_, module)) => {
|
||||
if !module.item_ids.is_empty() {
|
||||
self.dcx().emit_err(errors::DocKeywordEmptyMod { span: meta.span() });
|
||||
return;
|
||||
@@ -1072,9 +1072,9 @@ fn check_doc_search_unbox(&self, meta: &MetaItemInner, hir_id: HirId) {
|
||||
return;
|
||||
};
|
||||
match item.kind {
|
||||
ItemKind::Enum(_, generics) | ItemKind::Struct(_, generics)
|
||||
ItemKind::Enum(_, _, generics) | ItemKind::Struct(_, _, generics)
|
||||
if generics.params.len() != 0 => {}
|
||||
ItemKind::Trait(_, _, generics, _, items)
|
||||
ItemKind::Trait(_, _, _, generics, _, items)
|
||||
if generics.params.len() != 0
|
||||
|| items.iter().any(|item| matches!(item.kind, AssocItemKind::Type)) => {}
|
||||
_ => {
|
||||
@@ -2293,7 +2293,7 @@ fn check_macro_export(&self, hir_id: HirId, attr: &Attribute, target: Target) {
|
||||
}
|
||||
} else {
|
||||
// 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;
|
||||
|
||||
if is_decl_macro {
|
||||
@@ -2624,7 +2624,7 @@ fn visit_item(&mut self, item: &'tcx Item<'tcx>) {
|
||||
// Historically we've run more checks on non-exported than exported macros,
|
||||
// so this lets us continue to run them while maintaining backwards compatibility.
|
||||
// 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();
|
||||
if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) {
|
||||
check_non_exported_macro_for_invalid_attrs(self.tcx, item);
|
||||
@@ -2736,7 +2736,7 @@ fn visit_pat_field(&mut self, field: &'tcx hir::PatField<'tcx>) {
|
||||
}
|
||||
|
||||
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 {
|
||||
match variant.data {
|
||||
hir::VariantData::Unit(..) => { /* continue */ }
|
||||
@@ -2784,7 +2784,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
|
||||
.map(|id| tcx.hir_item(id))
|
||||
.find(|item| !item.span.is_dummy()) // Skip prelude `use`s
|
||||
.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(),
|
||||
});
|
||||
let err = tcx.dcx().create_err(errors::InvalidAttrAtCrateLevel {
|
||||
|
||||
@@ -751,7 +751,7 @@ fn check_item<'tcx>(
|
||||
match tcx.def_kind(id.owner_id) {
|
||||
DefKind::Enum => {
|
||||
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 {
|
||||
worklist.extend(
|
||||
enum_def.variants.iter().map(|variant| (variant.def_id, comes_from_allow)),
|
||||
@@ -806,7 +806,7 @@ fn check_item<'tcx>(
|
||||
}
|
||||
DefKind::Struct => {
|
||||
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()
|
||||
{
|
||||
struct_constructors.insert(ctor_def_id, item.owner_id.def_id);
|
||||
@@ -987,7 +987,7 @@ fn get_parent_if_enum_variant<'tcx>(
|
||||
&& let Some(enum_did) = tcx.opt_parent(may_variant.to_def_id())
|
||||
&& let Some(enum_local_id) = enum_did.as_local()
|
||||
&& 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
|
||||
} else {
|
||||
@@ -1062,7 +1062,7 @@ fn get_parent_if_enum_variant<'tcx>(
|
||||
let tuple_fields = if let Some(parent_id) = parent_item
|
||||
&& let node = tcx.hir_node_by_def_id(parent_id)
|
||||
&& let hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Struct(hir::VariantData::Tuple(fields, _, _), _),
|
||||
kind: hir::ItemKind::Struct(_, hir::VariantData::Tuple(fields, _, _), _),
|
||||
..
|
||||
}) = node
|
||||
{
|
||||
|
||||
@@ -206,7 +206,7 @@ fn propagate_node(&mut self, node: &Node<'tcx>, search_item: LocalDefId) {
|
||||
}
|
||||
}
|
||||
|
||||
hir::ItemKind::Const(_, _, init) => {
|
||||
hir::ItemKind::Const(_, _, _, init) => {
|
||||
// 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
|
||||
// const-eval happens in a downstream crate, all they need is
|
||||
@@ -234,7 +234,7 @@ fn propagate_node(&mut self, node: &Node<'tcx>, search_item: LocalDefId) {
|
||||
// These are normal, nothing reachable about these
|
||||
// inherently and their children are already in the
|
||||
// worklist, as determined by the privacy pass
|
||||
hir::ItemKind::ExternCrate(_)
|
||||
hir::ItemKind::ExternCrate(..)
|
||||
| hir::ItemKind::Use(..)
|
||||
| hir::ItemKind::TyAlias(..)
|
||||
| hir::ItemKind::Macro(..)
|
||||
|
||||
@@ -430,7 +430,7 @@ fn visit_item(&mut self, i: &'tcx Item<'tcx>) {
|
||||
kind = AnnotationKind::DeprecationProhibited;
|
||||
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() {
|
||||
self.annotate(
|
||||
ctor_def_id,
|
||||
@@ -773,10 +773,10 @@ fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
|
||||
|
||||
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
||||
match item.kind {
|
||||
hir::ItemKind::ExternCrate(_) => {
|
||||
hir::ItemKind::ExternCrate(_, ident) => {
|
||||
// compiler-generated `extern crate` items have a dummy span.
|
||||
// `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;
|
||||
}
|
||||
|
||||
|
||||
@@ -574,7 +574,7 @@ fn update_macro_reachable_def(
|
||||
// privacy and mark them reachable.
|
||||
DefKind::Macro(_) => {
|
||||
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) {
|
||||
self.update(def_id, macro_ev, Level::Reachable);
|
||||
}
|
||||
@@ -598,8 +598,8 @@ fn update_macro_reachable_def(
|
||||
DefKind::Struct | DefKind::Union => {
|
||||
// While structs and unions have type privacy, their fields do not.
|
||||
let item = self.tcx.hir_expect_item(def_id);
|
||||
if let hir::ItemKind::Struct(ref struct_def, _)
|
||||
| hir::ItemKind::Union(ref struct_def, _) = item.kind
|
||||
if let hir::ItemKind::Struct(_, ref struct_def, _)
|
||||
| hir::ItemKind::Union(_, ref struct_def, _) = item.kind
|
||||
{
|
||||
for field in struct_def.fields() {
|
||||
let field_vis = self.tcx.local_visibility(field.def_id);
|
||||
@@ -653,7 +653,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
||||
| hir::ItemKind::GlobalAsm { .. } => {}
|
||||
// The interface is empty, and all nested items are processed by `visit_item`.
|
||||
hir::ItemKind::Mod(..) => {}
|
||||
hir::ItemKind::Macro(macro_def, _) => {
|
||||
hir::ItemKind::Macro(_, macro_def, _) => {
|
||||
if let Some(item_ev) = item_ev {
|
||||
self.update_reachability_from_macro(item.owner_id.def_id, macro_def, item_ev);
|
||||
}
|
||||
@@ -724,7 +724,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::ItemKind::Enum(ref def, _) => {
|
||||
hir::ItemKind::Enum(_, ref def, _) => {
|
||||
if let Some(item_ev) = item_ev {
|
||||
self.reach(item.owner_id.def_id, item_ev).generics().predicates();
|
||||
}
|
||||
@@ -762,7 +762,8 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'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 {
|
||||
self.reach(item.owner_id.def_id, item_ev).generics().predicates();
|
||||
for field in struct_def.fields() {
|
||||
@@ -866,7 +867,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
||||
self.effective_visibility_diagnostic(item.owner_id.def_id);
|
||||
|
||||
match item.kind {
|
||||
hir::ItemKind::Enum(ref def, _) => {
|
||||
hir::ItemKind::Enum(_, ref def, _) => {
|
||||
for variant in def.variants.iter() {
|
||||
self.effective_visibility_diagnostic(variant.def_id);
|
||||
if let Some(ctor_def_id) = variant.data.ctor_def_id() {
|
||||
@@ -877,7 +878,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'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() {
|
||||
self.effective_visibility_diagnostic(ctor_def_id);
|
||||
}
|
||||
@@ -1636,7 +1637,7 @@ fn check_item(&mut self, id: ItemId) {
|
||||
}
|
||||
DefKind::Enum => {
|
||||
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(item.owner_id.def_id, item_visibility, effective_vis)
|
||||
@@ -1674,8 +1675,8 @@ fn check_item(&mut self, id: ItemId) {
|
||||
// Subitems of structs and unions have their own publicity.
|
||||
DefKind::Struct | DefKind::Union => {
|
||||
let item = tcx.hir_item(id);
|
||||
if let hir::ItemKind::Struct(ref struct_def, _)
|
||||
| hir::ItemKind::Union(ref struct_def, _) = item.kind
|
||||
if let hir::ItemKind::Struct(_, ref struct_def, _)
|
||||
| hir::ItemKind::Union(_, ref struct_def, _) = item.kind
|
||||
{
|
||||
self.check_unnameable(item.owner_id.def_id, effective_vis);
|
||||
self.check(item.owner_id.def_id, item_visibility, effective_vis)
|
||||
|
||||
@@ -2026,7 +2026,7 @@ fn visit_stmt(&mut self, s: &'v hir::Stmt<'v>) -> Self::Result {
|
||||
}
|
||||
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)
|
||||
}
|
||||
_ => None,
|
||||
|
||||
@@ -338,7 +338,7 @@ pub(super) fn maybe_report_ambiguity(
|
||||
..
|
||||
},
|
||||
hir::PathSegment {
|
||||
ident: assoc_item_name,
|
||||
ident: assoc_item_ident,
|
||||
res: Res::Def(_, item_id),
|
||||
..
|
||||
},
|
||||
@@ -368,17 +368,16 @@ pub(super) fn maybe_report_ambiguity(
|
||||
|
||||
if let Some(local_def_id) = data.trait_ref.def_id.as_local()
|
||||
&& let hir::Node::Item(hir::Item {
|
||||
ident: trait_name,
|
||||
kind: hir::ItemKind::Trait(_, _, _, _, trait_item_refs),
|
||||
kind: hir::ItemKind::Trait(_, _, trait_ident, _, _, trait_item_refs),
|
||||
..
|
||||
}) = self.tcx.hir_node_by_def_id(local_def_id)
|
||||
&& let Some(method_ref) = trait_item_refs
|
||||
.iter()
|
||||
.find(|item_ref| item_ref.ident == *assoc_item_name)
|
||||
.find(|item_ref| item_ref.ident == *assoc_item_ident)
|
||||
{
|
||||
err.span_label(
|
||||
method_ref.span,
|
||||
format!("`{trait_name}::{assoc_item_name}` defined here"),
|
||||
format!("`{trait_ident}::{assoc_item_ident}` defined here"),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -419,7 +419,12 @@ pub fn report_dyn_incompatibility<'tcx>(
|
||||
) -> Diag<'tcx> {
|
||||
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 {
|
||||
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,
|
||||
});
|
||||
|
||||
|
||||
@@ -267,8 +267,7 @@ pub fn suggest_restricting_param_bound(
|
||||
let node = self.tcx.hir_node_by_def_id(body_id);
|
||||
match node {
|
||||
hir::Node::Item(hir::Item {
|
||||
ident,
|
||||
kind: hir::ItemKind::Trait(_, _, generics, bounds, _),
|
||||
kind: hir::ItemKind::Trait(_, _, ident, generics, bounds, _),
|
||||
..
|
||||
}) if self_ty == self.tcx.types.self_param => {
|
||||
assert!(param_ty);
|
||||
@@ -282,7 +281,7 @@ pub fn suggest_restricting_param_bound(
|
||||
None,
|
||||
projection,
|
||||
trait_pred,
|
||||
Some((ident, bounds)),
|
||||
Some((&ident, bounds)),
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -331,7 +330,7 @@ pub fn suggest_restricting_param_bound(
|
||||
}
|
||||
hir::Node::Item(hir::Item {
|
||||
kind:
|
||||
hir::ItemKind::Trait(_, _, generics, ..)
|
||||
hir::ItemKind::Trait(_, _, _, generics, ..)
|
||||
| hir::ItemKind::Impl(hir::Impl { generics, .. }),
|
||||
..
|
||||
}) if projection.is_some() => {
|
||||
@@ -352,15 +351,15 @@ pub fn suggest_restricting_param_bound(
|
||||
|
||||
hir::Node::Item(hir::Item {
|
||||
kind:
|
||||
hir::ItemKind::Struct(_, generics)
|
||||
| hir::ItemKind::Enum(_, generics)
|
||||
| hir::ItemKind::Union(_, generics)
|
||||
| hir::ItemKind::Trait(_, _, generics, ..)
|
||||
hir::ItemKind::Struct(_, _, generics)
|
||||
| hir::ItemKind::Enum(_, _, generics)
|
||||
| hir::ItemKind::Union(_, _, generics)
|
||||
| hir::ItemKind::Trait(_, _, _, generics, ..)
|
||||
| hir::ItemKind::Impl(hir::Impl { generics, .. })
|
||||
| hir::ItemKind::Fn { generics, .. }
|
||||
| hir::ItemKind::TyAlias(_, generics)
|
||||
| hir::ItemKind::Const(_, generics, _)
|
||||
| hir::ItemKind::TraitAlias(generics, _),
|
||||
| hir::ItemKind::TyAlias(_, _, generics)
|
||||
| hir::ItemKind::Const(_, _, generics, _)
|
||||
| hir::ItemKind::TraitAlias(_, generics, _),
|
||||
..
|
||||
})
|
||||
| hir::Node::TraitItem(hir::TraitItem { generics, .. })
|
||||
@@ -412,15 +411,15 @@ pub fn suggest_restricting_param_bound(
|
||||
|
||||
hir::Node::Item(hir::Item {
|
||||
kind:
|
||||
hir::ItemKind::Struct(_, generics)
|
||||
| hir::ItemKind::Enum(_, generics)
|
||||
| hir::ItemKind::Union(_, generics)
|
||||
| hir::ItemKind::Trait(_, _, generics, ..)
|
||||
hir::ItemKind::Struct(_, _, generics)
|
||||
| hir::ItemKind::Enum(_, _, generics)
|
||||
| hir::ItemKind::Union(_, _, generics)
|
||||
| hir::ItemKind::Trait(_, _, _, generics, ..)
|
||||
| hir::ItemKind::Impl(hir::Impl { generics, .. })
|
||||
| hir::ItemKind::Fn { generics, .. }
|
||||
| hir::ItemKind::TyAlias(_, generics)
|
||||
| hir::ItemKind::Const(_, generics, _)
|
||||
| hir::ItemKind::TraitAlias(generics, _),
|
||||
| hir::ItemKind::TyAlias(_, _, generics)
|
||||
| hir::ItemKind::Const(_, _, generics, _)
|
||||
| hir::ItemKind::TraitAlias(_, generics, _),
|
||||
..
|
||||
}) if !param_ty => {
|
||||
// Missing generic type parameter bound.
|
||||
@@ -842,7 +841,7 @@ pub(super) fn suggest_fn_call(
|
||||
name.to_string()
|
||||
}
|
||||
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");
|
||||
ident.to_string()
|
||||
@@ -1588,20 +1587,20 @@ pub(super) fn suggest_remove_await(
|
||||
if let Some(typeck_results) = &self.typeck_results
|
||||
&& let ty = typeck_results.expr_ty_adjusted(base)
|
||||
&& let ty::FnDef(def_id, _args) = ty.kind()
|
||||
&& let Some(hir::Node::Item(hir::Item { ident, span, vis_span, .. })) =
|
||||
self.tcx.hir_get_if_local(*def_id)
|
||||
&& let Some(hir::Node::Item(item)) = self.tcx.hir_get_if_local(*def_id)
|
||||
{
|
||||
let (ident, _, _, _) = item.expect_fn();
|
||||
let msg = format!("alternatively, consider making `fn {ident}` asynchronous");
|
||||
if vis_span.is_empty() {
|
||||
if item.vis_span.is_empty() {
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_lo(),
|
||||
item.span.shrink_to_lo(),
|
||||
msg,
|
||||
"async ",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
err.span_suggestion_verbose(
|
||||
vis_span.shrink_to_hi(),
|
||||
item.vis_span.shrink_to_hi(),
|
||||
msg,
|
||||
" async",
|
||||
Applicability::MaybeIncorrect,
|
||||
@@ -3303,8 +3302,7 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
|
||||
let mut is_auto_trait = false;
|
||||
match tcx.hir_get_if_local(data.impl_or_alias_def_id) {
|
||||
Some(Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Trait(is_auto, ..),
|
||||
ident,
|
||||
kind: hir::ItemKind::Trait(is_auto, _, ident, ..),
|
||||
..
|
||||
})) => {
|
||||
// FIXME: we should do something else so that it works even on crate foreign
|
||||
|
||||
@@ -516,7 +516,7 @@ fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
|
||||
match self.tcx.parent_hir_node(self.tcx.local_def_id_to_hir_id(anon_reg.scope))
|
||||
{
|
||||
hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Trait(_, _, generics, ..),
|
||||
kind: hir::ItemKind::Trait(_, _, _, generics, ..),
|
||||
..
|
||||
})
|
||||
| hir::Node::Item(hir::Item {
|
||||
|
||||
+19
-16
@@ -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, _)| {
|
||||
// Now we actually lower the imports, skipping everything else.
|
||||
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)
|
||||
} else {
|
||||
// skip everything else
|
||||
@@ -1629,8 +1629,7 @@ fn first_non_private<'tcx>(
|
||||
if let Some(use_def_id) = reexp.id()
|
||||
&& 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)
|
||||
&& !item.ident.name.is_empty()
|
||||
&& let hir::ItemKind::Use(path, _) = item.kind
|
||||
&& let hir::ItemKind::Use(path, hir::UseKind::Single(_)) = item.kind
|
||||
{
|
||||
for res in &path.res {
|
||||
if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res {
|
||||
@@ -1775,7 +1774,7 @@ fn maybe_expand_private_type_alias<'tcx>(
|
||||
} else {
|
||||
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 mut args = DefIdMap::default();
|
||||
@@ -2794,20 +2793,24 @@ fn clean_maybe_renamed_item<'tcx>(
|
||||
use hir::ItemKind;
|
||||
|
||||
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| {
|
||||
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)),
|
||||
mutability,
|
||||
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),
|
||||
type_: clean_ty(ty, cx),
|
||||
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;
|
||||
let rustdoc_ty = clean_ty(hir_ty, cx);
|
||||
let type_ =
|
||||
@@ -2840,34 +2843,34 @@ fn clean_maybe_renamed_item<'tcx>(
|
||||
));
|
||||
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(),
|
||||
generics: clean_generics(generics, cx),
|
||||
}),
|
||||
ItemKind::TraitAlias(generics, bounds) => TraitAliasItem(TraitAlias {
|
||||
ItemKind::TraitAlias(_, generics, bounds) => TraitAliasItem(TraitAlias {
|
||||
generics: clean_generics(generics, cx),
|
||||
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),
|
||||
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(),
|
||||
generics: clean_generics(generics, cx),
|
||||
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::Macro(macro_def, MacroKind::Bang) => MacroItem(Macro {
|
||||
ItemKind::Macro(_, macro_def, MacroKind::Bang) => MacroItem(Macro {
|
||||
source: display_macro_source(cx, name, macro_def),
|
||||
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
|
||||
ItemKind::Fn { ref sig, generics, body: body_id, .. } => {
|
||||
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
|
||||
.iter()
|
||||
.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(),
|
||||
}))
|
||||
}
|
||||
ItemKind::ExternCrate(orig_name) => {
|
||||
ItemKind::ExternCrate(orig_name, _) => {
|
||||
return clean_extern_crate(item, name, orig_name, cx);
|
||||
}
|
||||
ItemKind::Use(path, kind) => {
|
||||
|
||||
@@ -226,7 +226,7 @@ pub(crate) fn keywords(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, Symbol)> {
|
||||
.filter_map(|&id| {
|
||||
let item = tcx.hir_item(id);
|
||||
match item.kind {
|
||||
hir::ItemKind::Mod(_) => {
|
||||
hir::ItemKind::Mod(..) => {
|
||||
as_keyword(Res::Def(DefKind::Mod, id.owner_id.to_def_id()))
|
||||
}
|
||||
_ => None,
|
||||
@@ -282,7 +282,7 @@ pub(crate) fn primitives(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, PrimitiveTyp
|
||||
.filter_map(|&id| {
|
||||
let item = tcx.hir_item(id);
|
||||
match item.kind {
|
||||
hir::ItemKind::Mod(_) => {
|
||||
hir::ItemKind::Mod(..) => {
|
||||
as_primitive(Res::Def(DefKind::Mod, id.owner_id.to_def_id()))
|
||||
}
|
||||
_ => None,
|
||||
|
||||
@@ -80,7 +80,7 @@ pub fn new(codes: ErrorCodes, enable_per_target_ignores: bool, tcx: TyCtxt<'tcx>
|
||||
|
||||
pub fn collect_crate(mut self) -> Vec<ScrapedDocTest> {
|
||||
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)
|
||||
});
|
||||
self.collector.tests
|
||||
@@ -90,7 +90,7 @@ pub fn collect_crate(mut self) -> Vec<ScrapedDocTest> {
|
||||
impl HirCollector<'_> {
|
||||
fn visit_testable<F: FnOnce(&mut Self)>(
|
||||
&mut self,
|
||||
name: String,
|
||||
name: Option<String>,
|
||||
def_id: LocalDefId,
|
||||
sp: Span,
|
||||
nested: F,
|
||||
@@ -103,9 +103,10 @@ fn visit_testable<F: FnOnce(&mut Self)>(
|
||||
return;
|
||||
}
|
||||
|
||||
let has_name = !name.is_empty();
|
||||
if has_name {
|
||||
let mut has_name = false;
|
||||
if let Some(name) = 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
|
||||
@@ -153,9 +154,9 @@ fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
|
||||
fn visit_item(&mut self, item: &'tcx hir::Item<'_>) {
|
||||
let name = match &item.kind {
|
||||
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| {
|
||||
@@ -164,31 +165,46 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'_>) {
|
||||
}
|
||||
|
||||
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| {
|
||||
intravisit::walk_trait_item(this, item);
|
||||
});
|
||||
self.visit_testable(
|
||||
Some(item.ident.to_string()),
|
||||
item.owner_id.def_id,
|
||||
item.span,
|
||||
|this| {
|
||||
intravisit::walk_trait_item(this, item);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
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| {
|
||||
intravisit::walk_impl_item(this, item);
|
||||
});
|
||||
self.visit_testable(
|
||||
Some(item.ident.to_string()),
|
||||
item.owner_id.def_id,
|
||||
item.span,
|
||||
|this| {
|
||||
intravisit::walk_impl_item(this, item);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
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| {
|
||||
intravisit::walk_foreign_item(this, item);
|
||||
});
|
||||
self.visit_testable(
|
||||
Some(item.ident.to_string()),
|
||||
item.owner_id.def_id,
|
||||
item.span,
|
||||
|this| {
|
||||
intravisit::walk_foreign_item(this, item);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -242,10 +242,9 @@ fn visit_mod(&mut self, m: &'tcx Mod<'tcx>, span: Span, id: HirId) {
|
||||
// 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;".
|
||||
if let Node::Item(item) = self.tcx.hir_node(id) {
|
||||
self.matches.insert(
|
||||
item.ident.span,
|
||||
LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)),
|
||||
);
|
||||
let (ident, _) = item.expect_mod();
|
||||
self.matches
|
||||
.insert(ident.span, LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)));
|
||||
}
|
||||
} else {
|
||||
// If it's a "mod foo {}", we want to look to its documentation page.
|
||||
@@ -273,22 +272,22 @@ fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'tcx>) {
|
||||
fn visit_item(&mut self, item: &'tcx Item<'tcx>) {
|
||||
match item.kind {
|
||||
ItemKind::Static(..)
|
||||
| ItemKind::Const(_, _, _)
|
||||
| ItemKind::Const(..)
|
||||
| ItemKind::Fn { .. }
|
||||
| ItemKind::Macro(_, _)
|
||||
| ItemKind::TyAlias(_, _)
|
||||
| ItemKind::Enum(_, _)
|
||||
| ItemKind::Struct(_, _)
|
||||
| ItemKind::Union(_, _)
|
||||
| ItemKind::Trait(_, _, _, _, _)
|
||||
| ItemKind::TraitAlias(_, _) => self.extract_info_from_hir_id(item.hir_id()),
|
||||
| ItemKind::Macro(..)
|
||||
| ItemKind::TyAlias(..)
|
||||
| ItemKind::Enum(..)
|
||||
| ItemKind::Struct(..)
|
||||
| ItemKind::Union(..)
|
||||
| ItemKind::Trait(..)
|
||||
| ItemKind::TraitAlias(..) => self.extract_info_from_hir_id(item.hir_id()),
|
||||
ItemKind::Impl(_)
|
||||
| ItemKind::Use(_, _)
|
||||
| ItemKind::ExternCrate(_)
|
||||
| ItemKind::Use(..)
|
||||
| ItemKind::ExternCrate(..)
|
||||
| ItemKind::ForeignMod { .. }
|
||||
| ItemKind::GlobalAsm { .. }
|
||||
// We already have "visit_mod" above so no need to check it here.
|
||||
| ItemKind::Mod(_) => {}
|
||||
| ItemKind::Mod(..) => {}
|
||||
}
|
||||
intravisit::walk_item(self, item);
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ fn visit_item(&mut self, i: &clean::Item) {
|
||||
data: hir::VariantData::Tuple(_, _, _),
|
||||
..
|
||||
}) | hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Struct(hir::VariantData::Tuple(_, _, _), _),
|
||||
kind: hir::ItemKind::Struct(_, hir::VariantData::Tuple(_, _, _), _),
|
||||
..
|
||||
})
|
||||
)
|
||||
|
||||
+19
-22
@@ -144,9 +144,8 @@ pub(crate) fn visit(mut self) -> Module<'tcx> {
|
||||
&& inserted.insert(def_id)
|
||||
{
|
||||
let item = self.cx.tcx.hir_expect_item(local_def_id);
|
||||
top_level_module
|
||||
.items
|
||||
.insert((local_def_id, Some(item.ident.name)), (item, None, None));
|
||||
let (ident, _, _) = item.expect_macro();
|
||||
top_level_module.items.insert((local_def_id, Some(ident.name)), (item, None, None));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,11 +223,11 @@ fn maybe_inline_local(
|
||||
def_id: LocalDefId,
|
||||
res: Res,
|
||||
renamed: Option<Symbol>,
|
||||
glob: bool,
|
||||
please_inline: bool,
|
||||
) -> bool {
|
||||
debug!("maybe_inline_local (renamed: {renamed:?}) res: {res:?}");
|
||||
|
||||
let glob = renamed.is_none();
|
||||
if renamed == Some(kw::Underscore) {
|
||||
// We never inline `_` reexports.
|
||||
return false;
|
||||
@@ -286,7 +285,7 @@ fn maybe_inline_local(
|
||||
is_hidden &&
|
||||
// If it's a doc hidden module, we need to keep it in case some of its inner items
|
||||
// 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.
|
||||
self.reexport_public_and_not_hidden(def_id, res_did)
|
||||
@@ -297,7 +296,7 @@ fn maybe_inline_local(
|
||||
|
||||
let is_bang_macro = matches!(
|
||||
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 {
|
||||
@@ -311,7 +310,7 @@ fn maybe_inline_local(
|
||||
Node::Item(_) if is_bang_macro && !please_inline && renamed.is_some() && is_hidden => {
|
||||
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);
|
||||
for &i in m.item_ids {
|
||||
let i = tcx.hir_item(i);
|
||||
@@ -378,7 +377,7 @@ fn add_to_current_mod(
|
||||
// attribute can still be visible.
|
||||
|| match item.kind {
|
||||
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)
|
||||
}
|
||||
_ => false,
|
||||
@@ -419,7 +418,7 @@ fn visit_item_inner(
|
||||
}
|
||||
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 def_id = item.owner_id.to_def_id();
|
||||
@@ -459,15 +458,13 @@ fn visit_item_inner(
|
||||
}
|
||||
_ => false,
|
||||
});
|
||||
let is_glob = kind == hir::UseKind::Glob;
|
||||
let ident = if is_glob { None } else { Some(name) };
|
||||
if self.maybe_inline_local(
|
||||
item.owner_id.def_id,
|
||||
res,
|
||||
ident,
|
||||
is_glob,
|
||||
please_inline,
|
||||
) {
|
||||
let ident = match kind {
|
||||
hir::UseKind::Single(ident) => Some(renamed.unwrap_or(ident.name)),
|
||||
hir::UseKind::Glob => None,
|
||||
hir::UseKind::ListStem => unreachable!(),
|
||||
};
|
||||
if self.maybe_inline_local(item.owner_id.def_id, res, ident, please_inline)
|
||||
{
|
||||
debug!("Inlining {:?}", item.owner_id.def_id);
|
||||
continue;
|
||||
}
|
||||
@@ -475,7 +472,7 @@ fn visit_item_inner(
|
||||
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()`,
|
||||
// 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:
|
||||
@@ -495,8 +492,8 @@ fn visit_item_inner(
|
||||
self.add_to_current_mod(item, renamed, import_id);
|
||||
}
|
||||
}
|
||||
hir::ItemKind::Mod(m) => {
|
||||
self.enter_mod(item.owner_id.def_id, m, name, renamed, import_id);
|
||||
hir::ItemKind::Mod(_, m) => {
|
||||
self.enter_mod(item.owner_id.def_id, m, get_name(), renamed, import_id);
|
||||
}
|
||||
hir::ItemKind::Fn { .. }
|
||||
| hir::ItemKind::ExternCrate(..)
|
||||
@@ -512,7 +509,7 @@ fn visit_item_inner(
|
||||
hir::ItemKind::Const(..) => {
|
||||
// Underscore constants do not correspond to a nameable item and
|
||||
// so are never useful in documentation.
|
||||
if name != kw::Underscore {
|
||||
if get_name() != kw::Underscore {
|
||||
self.add_to_current_mod(item, renamed, import_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
};
|
||||
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 @@ fn lint_impl_item<T: LintContext>(&self, cx: &T, item: &ImplItemRef, before_item
|
||||
/// 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 @@ fn lint_member_name<T: LintContext>(
|
||||
}
|
||||
|
||||
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 @@ fn lint_member_item<T: LintContext>(cx: &T, item: &Item<'_>, before_item: &Item<
|
||||
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 @@ fn lint_trait_item<T: LintContext>(&self, cx: &T, item: &TraitItemRef, before_it
|
||||
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
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 @@ struct CurItem<'a> {
|
||||
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 @@
|
||||
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 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
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 @@ fn check_res_emit(&self, cx: &LateContext<'_>, res: &Res, span: Span) {
|
||||
|
||||
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
|
||||
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 @@
|
||||
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
span_lint(
|
||||
cx,
|
||||
ERROR_IMPL_ERROR,
|
||||
item.ident.span,
|
||||
ident.span,
|
||||
"exported type alias named `Error` that implements `Error`",
|
||||
);
|
||||
},
|
||||
|
||||
@@ -91,7 +91,7 @@ fn check_fn(
|
||||
}
|
||||
|
||||
// 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 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
|
||||
"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_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 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
|
||||
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 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
|
||||
span_lint(
|
||||
cx,
|
||||
MODULE_NAME_REPETITIONS,
|
||||
item.ident.span,
|
||||
ident.span,
|
||||
"item name ends with its containing module's name",
|
||||
);
|
||||
}
|
||||
@@ -462,13 +466,13 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
|
||||
&& 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_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 @@ fn check_mod(&mut self, cx: &LateContext<'_>, module: &Mod<'_>, _: HirId) {
|
||||
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 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
|
||||
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
|
||||
&& 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 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
|
||||
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &Item<'tcx>) {
|
||||
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
"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_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 @@
|
||||
|
||||
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 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>)
|
||||
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 fill_trait_set(traitt: DefId, set: &mut DefIdSet, cx: &LateContext<'_>) {
|
||||
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
|
||||
}
|
||||
|
||||
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
|
||||
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 @@ fn check_crate_post(&mut self, _: &LateContext<'tcx>) {
|
||||
|
||||
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 @@ pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {
|
||||
|
||||
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
&& 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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
|
||||
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 @@
|
||||
|
||||
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 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
&& 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 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<
|
||||
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
}
|
||||
|
||||
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
// 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 @@ fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'tc
|
||||
..
|
||||
}) = 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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
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 @@ fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::ImplItem<'
|
||||
}
|
||||
|
||||
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 @@ pub fn new(conf: &'static Conf) -> Self {
|
||||
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 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
&& 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 @@ fn check_item(&mut self, cx: &LateContext<'_>, it: &Item<'_>) {
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user