Auto merge of #143357 - cjgillot:no-assoc-item-kind, r=compiler-errors

Retire hir::*ItemRef.

This information was kept for various places that iterate on HIR to know about trait-items and impl-items.

This PR replaces them by uses of the `associated_items` query that contain pretty much the same information.

This shortens many spans to just `def_span`, which can be easier to read.
This commit is contained in:
bors 2025-07-13 22:39:10 +00:00
commit 9c3064e131
82 changed files with 663 additions and 898 deletions

View file

@ -47,6 +47,7 @@ use rustc_errors::ErrorGuaranteed;
use rustc_hir::def_id::DefId;
use rustc_middle::span_bug;
use rustc_middle::ty::{Asyncness, ResolverAstLowering};
use rustc_span::symbol::kw;
use rustc_span::{Ident, Span, Symbol};
use {rustc_ast as ast, rustc_hir as hir};
@ -61,21 +62,6 @@ pub(crate) struct DelegationResults<'hir> {
}
impl<'hir> LoweringContext<'_, 'hir> {
/// Defines whether the delegatee is an associated function whose first parameter is `self`.
pub(crate) fn delegatee_is_method(
&self,
item_id: NodeId,
path_id: NodeId,
span: Span,
is_in_trait_impl: bool,
) -> bool {
let sig_id = self.get_delegation_sig_id(item_id, path_id, span, is_in_trait_impl);
let Ok(sig_id) = sig_id else {
return false;
};
self.is_method(sig_id, span)
}
fn is_method(&self, def_id: DefId, span: Span) -> bool {
match self.tcx.def_kind(def_id) {
DefKind::Fn => false,
@ -101,10 +87,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl);
match sig_id {
Ok(sig_id) => {
let is_method = self.is_method(sig_id, span);
let (param_count, c_variadic) = self.param_count(sig_id);
let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span);
let sig = self.lower_delegation_sig(sig_id, decl, span);
let body_id = self.lower_delegation_body(delegation, param_count, span);
let body_id = self.lower_delegation_body(delegation, is_method, param_count, span);
let ident = self.lower_ident(delegation.ident);
let generics = self.lower_delegation_generics(span);
DelegationResults { body_id, sig, ident, generics }
@ -234,10 +221,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::FnSig { decl, header, span }
}
fn generate_param(&mut self, idx: usize, span: Span) -> (hir::Param<'hir>, NodeId) {
fn generate_param(
&mut self,
is_method: bool,
idx: usize,
span: Span,
) -> (hir::Param<'hir>, NodeId) {
let pat_node_id = self.next_node_id();
let pat_id = self.lower_node_id(pat_node_id);
let ident = Ident::with_dummy_span(Symbol::intern(&format!("arg{idx}")));
// FIXME(cjgillot) AssocItem currently relies on self parameter being exactly named `self`.
let name = if is_method && idx == 0 {
kw::SelfLower
} else {
Symbol::intern(&format!("arg{idx}"))
};
let ident = Ident::with_dummy_span(name);
let pat = self.arena.alloc(hir::Pat {
hir_id: pat_id,
kind: hir::PatKind::Binding(hir::BindingMode::NONE, pat_id, ident, None),
@ -248,9 +246,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
(hir::Param { hir_id: self.next_id(), pat, ty_span: span, span }, pat_node_id)
}
fn generate_arg(&mut self, idx: usize, param_id: HirId, span: Span) -> hir::Expr<'hir> {
fn generate_arg(
&mut self,
is_method: bool,
idx: usize,
param_id: HirId,
span: Span,
) -> hir::Expr<'hir> {
// FIXME(cjgillot) AssocItem currently relies on self parameter being exactly named `self`.
let name = if is_method && idx == 0 {
kw::SelfLower
} else {
Symbol::intern(&format!("arg{idx}"))
};
let segments = self.arena.alloc_from_iter(iter::once(hir::PathSegment {
ident: Ident::with_dummy_span(Symbol::intern(&format!("arg{idx}"))),
ident: Ident::with_dummy_span(name),
hir_id: self.next_id(),
res: Res::Local(param_id),
args: None,
@ -264,6 +274,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_delegation_body(
&mut self,
delegation: &Delegation,
is_method: bool,
param_count: usize,
span: Span,
) -> BodyId {
@ -274,7 +285,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let mut args: Vec<hir::Expr<'_>> = Vec::with_capacity(param_count);
for idx in 0..param_count {
let (param, pat_node_id) = this.generate_param(idx, span);
let (param, pat_node_id) = this.generate_param(is_method, idx, span);
parameters.push(param);
let arg = if let Some(block) = block
@ -290,7 +301,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
this.ident_and_label_to_local_id.insert(pat_node_id, param.pat.hir_id.local_id);
this.lower_target_expr(&block)
} else {
this.generate_arg(idx, param.pat.hir_id, span)
this.generate_arg(is_method, idx, param.pat.hir_id, span)
};
args.push(arg);
}

View file

@ -381,28 +381,16 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
})
}
fn visit_trait_item_ref(&mut self, ii: &'hir TraitItemRef) {
// Do not visit the duplicate information in TraitItemRef. We want to
// map the actual nodes, not the duplicate ones in the *Ref.
let TraitItemRef { id, ident: _, kind: _, span: _ } = *ii;
self.visit_nested_trait_item(id);
fn visit_trait_item_ref(&mut self, id: &'hir TraitItemId) {
self.visit_nested_trait_item(*id);
}
fn visit_impl_item_ref(&mut self, ii: &'hir ImplItemRef) {
// Do not visit the duplicate information in ImplItemRef. We want to
// map the actual nodes, not the duplicate ones in the *Ref.
let ImplItemRef { id, ident: _, kind: _, span: _, trait_item_def_id: _ } = *ii;
self.visit_nested_impl_item(id);
fn visit_impl_item_ref(&mut self, id: &'hir ImplItemId) {
self.visit_nested_impl_item(*id);
}
fn visit_foreign_item_ref(&mut self, fi: &'hir ForeignItemRef) {
// Do not visit the duplicate information in ForeignItemRef. We want to
// map the actual nodes, not the duplicate ones in the *Ref.
let ForeignItemRef { id, ident: _, span: _ } = *fi;
self.visit_nested_foreign_item(id);
fn visit_foreign_item_ref(&mut self, id: &'hir ForeignItemId) {
self.visit_nested_foreign_item(*id);
}
fn visit_where_predicate(&mut self, predicate: &'hir WherePredicate<'hir>) {

View file

@ -393,11 +393,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
(trait_ref, lowered_ty)
});
let new_impl_items = self.arena.alloc_from_iter(
impl_items
.iter()
.map(|item| self.lower_impl_item_ref(item, trait_ref.is_some())),
);
let new_impl_items = self
.arena
.alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item)));
// `defaultness.has_value()` is never called for an `impl`, always `true` in order
// to not cause an assertion failure inside the `lower_defaultness` function.
@ -706,14 +704,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.arena.alloc(item)
}
fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef {
hir::ForeignItemRef {
id: hir::ForeignItemId { owner_id: self.owner_id(i.id) },
// `unwrap` is safe because `ForeignItemKind::MacCall` is the only foreign item kind
// without an identifier and it cannot reach here.
ident: self.lower_ident(i.kind.ident().unwrap()),
span: self.lower_span(i.span),
}
fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemId {
hir::ForeignItemId { owner_id: self.owner_id(i.id) }
}
fn lower_variant(&mut self, item_kind: &ItemKind, v: &Variant) -> hir::Variant<'hir> {
@ -972,32 +964,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.arena.alloc(item)
}
fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
let (ident, kind) = match &i.kind {
AssocItemKind::Const(box ConstItem { ident, .. }) => {
(*ident, hir::AssocItemKind::Const)
}
AssocItemKind::Type(box TyAlias { ident, .. }) => (*ident, hir::AssocItemKind::Type),
AssocItemKind::Fn(box Fn { ident, sig, .. }) => {
(*ident, hir::AssocItemKind::Fn { has_self: sig.decl.has_self() })
}
AssocItemKind::Delegation(box delegation) => (
delegation.ident,
hir::AssocItemKind::Fn {
has_self: self.delegatee_is_method(i.id, delegation.id, i.span, false),
},
),
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
panic!("macros should have been expanded by now")
}
};
let id = hir::TraitItemId { owner_id: self.owner_id(i.id) };
hir::TraitItemRef {
id,
ident: self.lower_ident(ident),
span: self.lower_span(i.span),
kind,
}
fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemId {
hir::TraitItemId { owner_id: self.owner_id(i.id) }
}
/// Construct `ExprKind::Err` for the given `span`.
@ -1128,41 +1096,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: self.lower_span(i.span),
defaultness,
has_delayed_lints: !self.delayed_lints.is_empty(),
};
self.arena.alloc(item)
}
fn lower_impl_item_ref(&mut self, i: &AssocItem, is_in_trait_impl: bool) -> hir::ImplItemRef {
hir::ImplItemRef {
id: hir::ImplItemId { owner_id: self.owner_id(i.id) },
// `unwrap` is safe because `AssocItemKind::{MacCall,DelegationMac}` are the only
// assoc item kinds without an identifier and they cannot reach here.
ident: self.lower_ident(i.kind.ident().unwrap()),
span: self.lower_span(i.span),
kind: match &i.kind {
AssocItemKind::Const(..) => hir::AssocItemKind::Const,
AssocItemKind::Type(..) => hir::AssocItemKind::Type,
AssocItemKind::Fn(box Fn { sig, .. }) => {
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
}
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
has_self: self.delegatee_is_method(
i.id,
delegation.id,
i.span,
is_in_trait_impl,
),
},
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
panic!("macros should have been expanded by now")
}
},
trait_item_def_id: self
.resolver
.get_partial_res(i.id)
.map(|r| r.expect_full_res().opt_def_id())
.unwrap_or(None),
}
};
self.arena.alloc(item)
}
fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemId {
hir::ImplItemId { owner_id: self.owner_id(i.id) }
}
fn lower_defaultness(

View file

@ -681,46 +681,30 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
return (false, false, None);
}
let my_def = self.body.source.def_id();
let my_hir = self.infcx.tcx.local_def_id_to_hir_id(my_def.as_local().unwrap());
let Some(td) =
self.infcx.tcx.impl_of_method(my_def).and_then(|x| self.infcx.tcx.trait_id_of_impl(x))
else {
return (false, false, None);
};
let implemented_trait_item = self.infcx.tcx.associated_item(my_def).trait_item_def_id;
(
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), ..
}) => {
let mut f_in_trait_opt = None;
for hir::TraitItemRef { id: fi, kind: k, .. } in *items {
let hi = fi.hir_id();
if !matches!(k, hir::AssocItemKind::Fn { .. }) {
continue;
}
if self.infcx.tcx.hir_name(hi) != self.infcx.tcx.hir_name(my_hir) {
continue;
}
f_in_trait_opt = Some(hi);
break;
}
f_in_trait_opt.and_then(|f_in_trait| {
if let Node::TraitItem(ti) = self.infcx.tcx.hir_node(f_in_trait)
&& let hir::TraitItemKind::Fn(sig, _) = ti.kind
&& let Some(ty) = sig.decl.inputs.get(local.index() - 1)
&& let hir::TyKind::Ref(_, mut_ty) = ty.kind
&& let hir::Mutability::Not = mut_ty.mutbl
&& sig.decl.implicit_self.has_implicit_self()
{
Some(ty.span)
} else {
None
}
})
implemented_trait_item.and_then(|f_in_trait| {
let f_in_trait = f_in_trait.as_local()?;
if let Node::TraitItem(ti) = self.infcx.tcx.hir_node_by_def_id(f_in_trait)
&& let hir::TraitItemKind::Fn(sig, _) = ti.kind
&& let Some(ty) = sig.decl.inputs.get(local.index() - 1)
&& let hir::TyKind::Ref(_, mut_ty) = ty.kind
&& let hir::Mutability::Not = mut_ty.mutbl
&& sig.decl.implicit_self.has_implicit_self()
{
Some(ty.span)
} else {
None
}
_ => None,
}),
)
}

View file

@ -3172,6 +3172,8 @@ pub struct ImplItem<'hir> {
pub span: Span,
pub vis_span: Span,
pub has_delayed_lints: bool,
/// When we are in a trait impl, link to the trait-item's id.
pub trait_item_def_id: Option<DefId>,
}
impl<'hir> ImplItem<'hir> {
@ -4136,7 +4138,7 @@ impl<'hir> Item<'hir> {
expect_mod, (Ident, &'hir Mod<'hir>), ItemKind::Mod(ident, m), (*ident, m);
expect_foreign_mod, (ExternAbi, &'hir [ForeignItemRef]),
expect_foreign_mod, (ExternAbi, &'hir [ForeignItemId]),
ItemKind::ForeignMod { abi, items }, (*abi, items);
expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm;
@ -4160,7 +4162,7 @@ impl<'hir> Item<'hir> {
Ident,
&'hir Generics<'hir>,
GenericBounds<'hir>,
&'hir [TraitItemRef]
&'hir [TraitItemId]
),
ItemKind::Trait(is_auto, safety, ident, generics, bounds, items),
(*is_auto, *safety, *ident, generics, bounds, items);
@ -4313,7 +4315,7 @@ pub enum ItemKind<'hir> {
/// A module.
Mod(Ident, &'hir Mod<'hir>),
/// An external module, e.g. `extern { .. }`.
ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemRef] },
ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemId] },
/// Module-level inline assembly (from `global_asm!`).
GlobalAsm {
asm: &'hir InlineAsm<'hir>,
@ -4333,7 +4335,7 @@ pub enum ItemKind<'hir> {
/// A union definition, e.g., `union Foo<A, B> {x: A, y: B}`.
Union(Ident, &'hir Generics<'hir>, VariantData<'hir>),
/// A trait definition.
Trait(IsAuto, Safety, Ident, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]),
Trait(IsAuto, Safety, Ident, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemId]),
/// A trait alias.
TraitAlias(Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
@ -4360,7 +4362,7 @@ pub struct Impl<'hir> {
pub of_trait: Option<TraitRef<'hir>>,
pub self_ty: &'hir Ty<'hir>,
pub items: &'hir [ImplItemRef],
pub items: &'hir [ImplItemId],
}
impl ItemKind<'_> {
@ -4403,43 +4405,6 @@ impl ItemKind<'_> {
}
}
/// A reference from an trait to one of its associated items. This
/// contains the item's id, naturally, but also the item's name and
/// some other high-level details (like whether it is an associated
/// type or method, and whether it is public). This allows other
/// passes to find the impl they want without loading the ID (which
/// means fewer edges in the incremental compilation graph).
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct TraitItemRef {
pub id: TraitItemId,
pub ident: Ident,
pub kind: AssocItemKind,
pub span: Span,
}
/// A reference from an impl to one of its associated items. This
/// contains the item's ID, naturally, but also the item's name and
/// some other high-level details (like whether it is an associated
/// type or method, and whether it is public). This allows other
/// passes to find the impl they want without loading the ID (which
/// means fewer edges in the incremental compilation graph).
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct ImplItemRef {
pub id: ImplItemId,
pub ident: Ident,
pub kind: AssocItemKind,
pub span: Span,
/// When we are in a trait impl, link to the trait-item's id.
pub trait_item_def_id: Option<DefId>,
}
#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
pub enum AssocItemKind {
Const,
Fn { has_self: bool },
Type,
}
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
@ -4456,19 +4421,6 @@ impl ForeignItemId {
}
}
/// A reference from a foreign block to one of its items. This
/// contains the item's ID, naturally, but also the item's name and
/// some other high-level details (like whether it is an associated
/// type or method, and whether it is public). This allows other
/// passes to find the impl they want without loading the ID (which
/// means fewer edges in the incremental compilation graph).
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct ForeignItemRef {
pub id: ForeignItemId,
pub ident: Ident,
pub span: Span,
}
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct ForeignItem<'hir> {
pub ident: Ident,
@ -4969,7 +4921,7 @@ mod size_asserts {
static_assert_size!(GenericBound<'_>, 64);
static_assert_size!(Generics<'_>, 56);
static_assert_size!(Impl<'_>, 80);
static_assert_size!(ImplItem<'_>, 88);
static_assert_size!(ImplItem<'_>, 96);
static_assert_size!(ImplItemKind<'_>, 40);
static_assert_size!(Item<'_>, 88);
static_assert_size!(ItemKind<'_>, 64);

View file

@ -435,17 +435,17 @@ pub trait Visitor<'v>: Sized {
fn visit_trait_item(&mut self, ti: &'v TraitItem<'v>) -> Self::Result {
walk_trait_item(self, ti)
}
fn visit_trait_item_ref(&mut self, ii: &'v TraitItemRef) -> Self::Result {
walk_trait_item_ref(self, ii)
fn visit_trait_item_ref(&mut self, ii: &'v TraitItemId) -> Self::Result {
walk_trait_item_ref(self, *ii)
}
fn visit_impl_item(&mut self, ii: &'v ImplItem<'v>) -> Self::Result {
walk_impl_item(self, ii)
}
fn visit_foreign_item_ref(&mut self, ii: &'v ForeignItemRef) -> Self::Result {
walk_foreign_item_ref(self, ii)
fn visit_foreign_item_ref(&mut self, ii: &'v ForeignItemId) -> Self::Result {
walk_foreign_item_ref(self, *ii)
}
fn visit_impl_item_ref(&mut self, ii: &'v ImplItemRef) -> Self::Result {
walk_impl_item_ref(self, ii)
fn visit_impl_item_ref(&mut self, ii: &'v ImplItemId) -> Self::Result {
walk_impl_item_ref(self, *ii)
}
fn visit_trait_ref(&mut self, t: &'v TraitRef<'v>) -> Self::Result {
walk_trait_ref(self, t)
@ -499,9 +499,6 @@ pub trait Visitor<'v>: Sized {
fn visit_attribute(&mut self, _attr: &'v Attribute) -> Self::Result {
Self::Result::output()
}
fn visit_associated_item_kind(&mut self, kind: &'v AssocItemKind) -> Self::Result {
walk_associated_item_kind(self, kind)
}
fn visit_defaultness(&mut self, defaultness: &'v Defaultness) -> Self::Result {
walk_defaultness(self, defaultness)
}
@ -1248,14 +1245,8 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(
V::Result::output()
}
pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(
visitor: &mut V,
trait_item_ref: &'v TraitItemRef,
) -> V::Result {
let TraitItemRef { id, ident, ref kind, span: _ } = *trait_item_ref;
try_visit!(visitor.visit_nested_trait_item(id));
try_visit!(visitor.visit_ident(ident));
visitor.visit_associated_item_kind(kind)
pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, id: TraitItemId) -> V::Result {
visitor.visit_nested_trait_item(id)
}
pub fn walk_impl_item<'v, V: Visitor<'v>>(
@ -1271,6 +1262,7 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(
span: _,
vis_span: _,
has_delayed_lints: _,
trait_item_def_id: _,
} = *impl_item;
try_visit!(visitor.visit_ident(ident));
@ -1293,23 +1285,12 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(
}
}
pub fn walk_foreign_item_ref<'v, V: Visitor<'v>>(
visitor: &mut V,
foreign_item_ref: &'v ForeignItemRef,
) -> V::Result {
let ForeignItemRef { id, ident, span: _ } = *foreign_item_ref;
try_visit!(visitor.visit_nested_foreign_item(id));
visitor.visit_ident(ident)
pub fn walk_foreign_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, id: ForeignItemId) -> V::Result {
visitor.visit_nested_foreign_item(id)
}
pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(
visitor: &mut V,
impl_item_ref: &'v ImplItemRef,
) -> V::Result {
let ImplItemRef { id, ident, ref kind, span: _, trait_item_def_id: _ } = *impl_item_ref;
try_visit!(visitor.visit_nested_impl_item(id));
try_visit!(visitor.visit_ident(ident));
visitor.visit_associated_item_kind(kind)
pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, id: ImplItemId) -> V::Result {
visitor.visit_nested_impl_item(id)
}
pub fn walk_trait_ref<'v, V: Visitor<'v>>(
@ -1483,13 +1464,6 @@ pub fn walk_assoc_item_constraint<'v, V: Visitor<'v>>(
V::Result::output()
}
pub fn walk_associated_item_kind<'v, V: Visitor<'v>>(_: &mut V, _: &'v AssocItemKind) -> V::Result {
// No visitable content here: this fn exists so you can call it if
// the right thing to do, should content be added in the future,
// would be to walk it.
V::Result::output()
}
pub fn walk_defaultness<'v, V: Visitor<'v>>(_: &mut V, _: &'v Defaultness) -> V::Result {
// No visitable content here: this fn exists so you can call it if
// the right thing to do, should content be added in the future,

View file

@ -930,8 +930,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
check_abi(tcx, it.hir_id(), it.span, abi);
for item in items {
let def_id = item.id.owner_id.def_id;
for &item in items {
let def_id = item.owner_id.def_id;
let generics = tcx.generics_of(def_id);
let own_counts = generics.own_counts();
@ -943,13 +943,14 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
(0, _) => ("const", "consts", None),
_ => ("type or const", "types or consts", None),
};
let span = tcx.def_span(def_id);
struct_span_code_err!(
tcx.dcx(),
item.span,
span,
E0044,
"foreign items may not have {kinds} parameters",
)
.with_span_label(item.span, format!("can't have {kinds} parameters"))
.with_span_label(span, format!("can't have {kinds} parameters"))
.with_help(
// FIXME: once we start storing spans for type arguments, turn this
// into a suggestion.
@ -963,22 +964,23 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
.emit();
}
let item = tcx.hir_foreign_item(item.id);
tcx.ensure_ok().generics_of(item.owner_id);
tcx.ensure_ok().type_of(item.owner_id);
tcx.ensure_ok().predicates_of(item.owner_id);
tcx.ensure_ok().generics_of(def_id);
tcx.ensure_ok().type_of(def_id);
tcx.ensure_ok().predicates_of(def_id);
if tcx.is_conditionally_const(def_id) {
tcx.ensure_ok().explicit_implied_const_bounds(def_id);
tcx.ensure_ok().const_conditions(def_id);
}
match item.kind {
hir::ForeignItemKind::Fn(sig, ..) => {
tcx.ensure_ok().codegen_fn_attrs(item.owner_id);
tcx.ensure_ok().fn_sig(item.owner_id);
match tcx.def_kind(def_id) {
DefKind::Fn => {
tcx.ensure_ok().codegen_fn_attrs(def_id);
tcx.ensure_ok().fn_sig(def_id);
let item = tcx.hir_foreign_item(item);
let hir::ForeignItemKind::Fn(sig, ..) = item.kind else { bug!() };
require_c_abi_if_c_variadic(tcx, sig.decl, abi, item.span);
}
hir::ForeignItemKind::Static(..) => {
tcx.ensure_ok().codegen_fn_attrs(item.owner_id);
DefKind::Static { .. } => {
tcx.ensure_ok().codegen_fn_attrs(def_id);
}
_ => (),
}

View file

@ -59,7 +59,7 @@ fn equate_intrinsic_type<'tcx>(
/// Returns the unsafety of the given intrinsic.
fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hir::Safety {
let is_in_list = match tcx.item_name(intrinsic_id.into()) {
let is_in_list = match tcx.item_name(intrinsic_id) {
// When adding a new intrinsic to this list,
// it's usually worth updating that intrinsic's documentation
// to note that it's safe to call, since
@ -144,7 +144,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
tcx.def_span(intrinsic_id),
DiagMessage::from(format!(
"intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `{}`",
tcx.item_name(intrinsic_id.into())
tcx.item_name(intrinsic_id)
)
)).emit();
}

View file

@ -844,11 +844,9 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
let item = tcx.hir_expect_item(def_id);
let (is_alias, is_auto, safety, items) = match item.kind {
hir::ItemKind::Trait(is_auto, safety, .., items) => {
(false, is_auto == hir::IsAuto::Yes, safety, items)
}
hir::ItemKind::TraitAlias(..) => (true, false, hir::Safety::Safe, &[][..]),
let (is_alias, is_auto, safety) = match item.kind {
hir::ItemKind::Trait(is_auto, safety, ..) => (false, is_auto == hir::IsAuto::Yes, safety),
hir::ItemKind::TraitAlias(..) => (true, false, hir::Safety::Safe),
_ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
};
@ -911,13 +909,16 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
// functions in the trait with default implementations
.and_then(|(list, attr_span)| {
let errors = list.iter().filter_map(|ident| {
let item = items.iter().find(|item| item.ident == *ident);
let item = tcx
.associated_items(def_id)
.filter_by_name_unhygienic(ident.name)
.find(|item| item.ident(tcx) == *ident);
match item {
Some(item) if matches!(item.kind, hir::AssocItemKind::Fn { .. }) => {
if !tcx.defaultness(item.id.owner_id).has_value() {
Some(item) if matches!(item.kind, ty::AssocKind::Fn { .. }) => {
if !item.defaultness(tcx).has_value() {
tcx.dcx().emit_err(errors::FunctionNotHaveDefaultImplementation {
span: item.span,
span: tcx.def_span(item.def_id),
note_span: attr_span,
});
@ -928,7 +929,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
}
Some(item) => {
tcx.dcx().emit_err(errors::MustImplementNotFunction {
span: item.span,
span: tcx.def_span(item.def_id),
span_note: errors::MustImplementNotFunctionSpanNote { span: attr_span },
note: errors::MustImplementNotFunctionNote {},
});

View file

@ -654,8 +654,8 @@ impl<'a> State<'a> {
let (cb, ib) = self.head("extern");
self.word_nbsp(abi.to_string());
self.bopen(ib);
for item in items {
self.ann.nested(self, Nested::ForeignItem(item.id));
for &foreign_item in items {
self.ann.nested(self, Nested::ForeignItem(foreign_item));
}
self.bclose(item.span, cb);
}
@ -730,8 +730,8 @@ impl<'a> State<'a> {
self.space();
self.bopen(ib);
for impl_item in items {
self.ann.nested(self, Nested::ImplItem(impl_item.id));
for &impl_item in items {
self.ann.nested(self, Nested::ImplItem(impl_item));
}
self.bclose(item.span, cb);
}
@ -746,8 +746,8 @@ impl<'a> State<'a> {
self.print_where_clause(generics);
self.word(" ");
self.bopen(ib);
for trait_item in trait_items {
self.ann.nested(self, Nested::TraitItem(trait_item.id));
for &trait_item in trait_items {
self.ann.nested(self, Nested::TraitItem(trait_item));
}
self.bclose(item.span, cb);
}

View file

@ -28,7 +28,7 @@ use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
use rustc_hir::intravisit::FnKind as HirFnKind;
use rustc_hir::{Body, FnDecl, GenericParamKind, PatKind, PredicateOrigin};
use rustc_hir::{Body, FnDecl, PatKind, PredicateOrigin};
use rustc_middle::bug;
use rustc_middle::lint::LevelAndSource;
use rustc_middle::ty::layout::LayoutOf;
@ -952,36 +952,34 @@ declare_lint! {
declare_lint_pass!(InvalidNoMangleItems => [NO_MANGLE_CONST_ITEMS, NO_MANGLE_GENERIC_ITEMS]);
impl InvalidNoMangleItems {
fn check_no_mangle_on_generic_fn(
&self,
cx: &LateContext<'_>,
attr_span: Span,
def_id: LocalDefId,
) {
let generics = cx.tcx.generics_of(def_id);
if generics.requires_monomorphization(cx.tcx) {
cx.emit_span_lint(
NO_MANGLE_GENERIC_ITEMS,
cx.tcx.def_span(def_id),
BuiltinNoMangleGeneric { suggestion: attr_span },
);
}
}
}
impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
let attrs = cx.tcx.hir_attrs(it.hir_id());
let check_no_mangle_on_generic_fn = |attr_span: Span,
impl_generics: Option<&hir::Generics<'_>>,
generics: &hir::Generics<'_>,
span| {
for param in
generics.params.iter().chain(impl_generics.map(|g| g.params).into_iter().flatten())
{
match param.kind {
GenericParamKind::Lifetime { .. } => {}
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
cx.emit_span_lint(
NO_MANGLE_GENERIC_ITEMS,
span,
BuiltinNoMangleGeneric { suggestion: attr_span },
);
break;
}
}
}
};
match it.kind {
hir::ItemKind::Fn { generics, .. } => {
hir::ItemKind::Fn { .. } => {
if let Some(attr_span) =
find_attr!(attrs, AttributeKind::ExportName {span, ..} => *span)
.or_else(|| find_attr!(attrs, AttributeKind::NoMangle(span) => *span))
{
check_no_mangle_on_generic_fn(attr_span, None, generics, it.span);
self.check_no_mangle_on_generic_fn(cx, attr_span, it.owner_id.def_id);
}
}
hir::ItemKind::Const(..) => {
@ -1006,24 +1004,19 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
);
}
}
hir::ItemKind::Impl(hir::Impl { generics, items, .. }) => {
for it in *items {
if let hir::AssocItemKind::Fn { .. } = it.kind {
let attrs = cx.tcx.hir_attrs(it.id.hir_id());
if let Some(attr_span) =
find_attr!(attrs, AttributeKind::ExportName {span, ..} => *span)
.or_else(
|| find_attr!(attrs, AttributeKind::NoMangle(span) => *span),
)
{
check_no_mangle_on_generic_fn(
attr_span,
Some(generics),
cx.tcx.hir_get_generics(it.id.owner_id.def_id).unwrap(),
it.span,
);
}
}
_ => {}
}
}
fn check_impl_item(&mut self, cx: &LateContext<'_>, it: &hir::ImplItem<'_>) {
let attrs = cx.tcx.hir_attrs(it.hir_id());
match it.kind {
hir::ImplItemKind::Fn { .. } => {
if let Some(attr_span) =
find_attr!(attrs, AttributeKind::ExportName {span, ..} => *span)
.or_else(|| find_attr!(attrs, AttributeKind::NoMangle(span) => *span))
{
self.check_no_mangle_on_generic_fn(cx, attr_span, it.owner_id.def_id);
}
}
_ => {}

View file

@ -1,7 +1,7 @@
use rustc_hir::{self as hir, LangItem};
use rustc_middle::ty;
use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::sym;
use rustc_span::{Ident, sym};
use rustc_trait_selection::traits::supertraits;
use crate::lints::{SupertraitAsDerefTarget, SupertraitAsDerefTargetLabel};
@ -79,11 +79,15 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
// erase regions in self type for better diagnostic presentation
let (self_ty, target_principal, supertrait_principal) =
tcx.erase_regions((self_ty, target_principal, supertrait_principal));
let label2 = impl_
.items
.iter()
.find_map(|i| (i.ident.name == sym::Target).then_some(i.span))
.map(|label| SupertraitAsDerefTargetLabel { label });
let label2 = tcx
.associated_items(item.owner_id)
.find_by_ident_and_kind(
tcx,
Ident::with_dummy_span(sym::Target),
ty::AssocTag::Type,
item.owner_id.to_def_id(),
)
.map(|label| SupertraitAsDerefTargetLabel { label: tcx.def_span(label.def_id) });
let span = tcx.def_span(item.owner_id.def_id);
cx.emit_span_lint(
DEREF_INTO_DYN_SUPERTRAIT,

View file

@ -19,7 +19,7 @@ pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> FxIndexMap<Def
let item = tcx.hir_item(id);
if let hir::ItemKind::ForeignMod { abi, items } = item.kind {
let foreign_items = items.iter().map(|it| it.id.owner_id.to_def_id()).collect();
let foreign_items = items.iter().map(|it| it.owner_id.to_def_id()).collect();
modules.insert(def_id, ForeignModule { def_id, abi, foreign_items });
}
}

View file

@ -257,6 +257,16 @@ impl AssocItems {
self.items.get_by_key(Some(name))
}
/// Returns the associated item with the given identifier and `AssocKind`, if one exists.
/// The identifier is ignoring hygiene. This is meant to be used for lints and diagnostics.
pub fn filter_by_name_unhygienic_and_kind(
&self,
name: Symbol,
assoc_tag: AssocTag,
) -> impl '_ + Iterator<Item = &ty::AssocItem> {
self.filter_by_name_unhygienic(name).filter(move |item| item.as_tag() == assoc_tag)
}
/// Returns the associated item with the given identifier and `AssocKind`, if one exists.
/// The identifier is matched hygienically.
pub fn find_by_ident_and_kind(

View file

@ -1590,7 +1590,8 @@ impl<'tcx> TyCtxt<'tcx> {
}
/// Look up the name of a definition across crates. This does not look at HIR.
pub fn opt_item_name(self, def_id: DefId) -> Option<Symbol> {
pub fn opt_item_name(self, def_id: impl IntoQueryParam<DefId>) -> Option<Symbol> {
let def_id = def_id.into_query_param();
if let Some(cnum) = def_id.as_crate_root() {
Some(self.crate_name(cnum))
} else {
@ -1610,7 +1611,8 @@ impl<'tcx> TyCtxt<'tcx> {
/// [`opt_item_name`] instead.
///
/// [`opt_item_name`]: Self::opt_item_name
pub fn item_name(self, id: DefId) -> Symbol {
pub fn item_name(self, id: impl IntoQueryParam<DefId>) -> Symbol {
let id = id.into_query_param();
self.opt_item_name(id).unwrap_or_else(|| {
bug!("item_name: no name for {:?}", self.def_path(id));
})
@ -1619,7 +1621,8 @@ impl<'tcx> TyCtxt<'tcx> {
/// Look up the name and span of a definition.
///
/// See [`item_name`][Self::item_name] for more information.
pub fn opt_item_ident(self, def_id: DefId) -> Option<Ident> {
pub fn opt_item_ident(self, def_id: impl IntoQueryParam<DefId>) -> Option<Ident> {
let def_id = def_id.into_query_param();
let def = self.opt_item_name(def_id)?;
let span = self
.def_ident_span(def_id)
@ -1630,7 +1633,8 @@ impl<'tcx> TyCtxt<'tcx> {
/// Look up the name and span of a definition.
///
/// See [`item_name`][Self::item_name] for more information.
pub fn item_ident(self, def_id: DefId) -> Ident {
pub fn item_ident(self, def_id: impl IntoQueryParam<DefId>) -> Ident {
let def_id = def_id.into_query_param();
self.opt_item_ident(def_id).unwrap_or_else(|| {
bug!("item_ident: no name for {:?}", self.def_path(def_id));
})

View file

@ -1683,7 +1683,7 @@ pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Intrinsi
_ => true,
};
Some(ty::IntrinsicDef {
name: tcx.item_name(def_id.into()),
name: tcx.item_name(def_id),
must_be_overridden,
const_stable: tcx.has_attr(def_id, sym::rustc_intrinsic_const_stable_indirect),
})

View file

@ -1084,7 +1084,7 @@ fn find_fallback_pattern_typo<'tcx>(
&& infcx.can_eq(param_env, ty, cx.tcx.type_of(item.owner_id).instantiate_identity())
{
// Look for local consts.
let item_name = cx.tcx.item_name(item.owner_id.into());
let item_name = cx.tcx.item_name(item.owner_id);
let vis = cx.tcx.visibility(item.owner_id);
if vis.is_accessible_from(parent, cx.tcx) {
accessible.push(item_name);

View file

@ -79,7 +79,7 @@ fn dump_abi_of_fn_item(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
for meta_item in meta_items {
match meta_item.name() {
Some(sym::debug) => {
let fn_name = tcx.item_name(item_def_id.into());
let fn_name = tcx.item_name(item_def_id);
tcx.dcx().emit_err(AbiOf {
span: tcx.def_span(item_def_id),
fn_name,
@ -135,7 +135,7 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
item_def_id,
);
let fn_name = tcx.item_name(item_def_id.into());
let fn_name = tcx.item_name(item_def_id);
tcx.dcx().emit_err(AbiOf { span, fn_name, fn_abi: format!("{:#?}", abi) });
}
Some(sym::assert_eq) => {

View file

@ -20,8 +20,8 @@ use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalModDefId;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{
self as hir, self, AssocItemKind, Attribute, CRATE_HIR_ID, CRATE_OWNER_ID, FnSig, ForeignItem,
HirId, Item, ItemKind, MethodKind, Safety, Target, TraitItem,
self as hir, self, Attribute, CRATE_HIR_ID, CRATE_OWNER_ID, FnSig, ForeignItem, HirId, Item,
ItemKind, MethodKind, Safety, Target, TraitItem,
};
use rustc_macros::LintDiagnostic;
use rustc_middle::hir::nested_filter;
@ -1151,7 +1151,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
if generics.params.len() != 0 => {}
ItemKind::Trait(_, _, _, generics, _, items)
if generics.params.len() != 0
|| items.iter().any(|item| matches!(item.kind, AssocItemKind::Type)) => {}
|| items.iter().any(|item| {
matches!(self.tcx.def_kind(item.owner_id), DefKind::AssocTy)
}) => {}
ItemKind::TyAlias(_, generics, _) if generics.params.len() != 0 => {}
_ => {
self.dcx().emit_err(errors::DocSearchUnboxInvalid { span: meta.span() });

View file

@ -418,8 +418,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
hir::ItemKind::Trait(.., trait_item_refs) => {
// mark assoc ty live if the trait is live
for trait_item in trait_item_refs {
if matches!(trait_item.kind, hir::AssocItemKind::Type) {
self.check_def_id(trait_item.id.owner_id.to_def_id());
if matches!(self.tcx.def_kind(trait_item.owner_id), DefKind::AssocTy) {
self.check_def_id(trait_item.owner_id.to_def_id());
}
}
intravisit::walk_item(self, item)

View file

@ -467,9 +467,9 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
hir_visit::walk_trait_item(self, ti)
}
fn visit_trait_item_ref(&mut self, ti: &'v hir::TraitItemRef) {
self.record("TraitItemRef", Some(ti.id.hir_id()), ti);
hir_visit::walk_trait_item_ref(self, ti)
fn visit_trait_item_ref(&mut self, ti: &'v hir::TraitItemId) {
self.record("TraitItemId", Some(ti.hir_id()), ti);
hir_visit::walk_trait_item_ref(self, *ti)
}
fn visit_impl_item(&mut self, ii: &'v hir::ImplItem<'v>) {
@ -480,14 +480,14 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
hir_visit::walk_impl_item(self, ii)
}
fn visit_foreign_item_ref(&mut self, fi: &'v hir::ForeignItemRef) {
self.record("ForeignItemRef", Some(fi.id.hir_id()), fi);
hir_visit::walk_foreign_item_ref(self, fi)
fn visit_foreign_item_ref(&mut self, fi: &'v hir::ForeignItemId) {
self.record("ForeignItemId", Some(fi.hir_id()), fi);
hir_visit::walk_foreign_item_ref(self, *fi)
}
fn visit_impl_item_ref(&mut self, ii: &'v hir::ImplItemRef) {
self.record("ImplItemRef", Some(ii.id.hir_id()), ii);
hir_visit::walk_impl_item_ref(self, ii)
fn visit_impl_item_ref(&mut self, ii: &'v hir::ImplItemId) {
self.record("ImplItemId", Some(ii.hir_id()), ii);
hir_visit::walk_impl_item_ref(self, *ii)
}
fn visit_param_bound(&mut self, b: &'v hir::GenericBound<'v>) {

View file

@ -880,11 +880,16 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
}
for impl_item_ref in *items {
let impl_item = self.tcx.associated_item(impl_item_ref.id.owner_id);
let impl_item = self.tcx.associated_item(impl_item_ref.owner_id);
if let Some(def_id) = impl_item.trait_item_def_id {
// Pass `None` to skip deprecation warnings.
self.tcx.check_stability(def_id, None, impl_item_ref.span, None);
self.tcx.check_stability(
def_id,
None,
self.tcx.def_span(impl_item_ref.owner_id),
None,
);
}
}
}

View file

@ -26,7 +26,7 @@ use rustc_errors::{MultiSpan, listify};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId, LocalModDefId};
use rustc_hir::intravisit::{self, InferKind, Visitor};
use rustc_hir::{AmbigArg, AssocItemKind, ForeignItemKind, ItemId, ItemKind, PatKind};
use rustc_hir::{AmbigArg, ForeignItemKind, ItemId, ItemKind, PatKind};
use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
use rustc_middle::query::Providers;
use rustc_middle::ty::print::PrintTraitRefExt as _;
@ -672,14 +672,14 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
self.reach(item.owner_id.def_id, item_ev).generics().predicates();
for trait_item_ref in trait_item_refs {
self.update(trait_item_ref.id.owner_id.def_id, item_ev, Level::Reachable);
self.update(trait_item_ref.owner_id.def_id, item_ev, Level::Reachable);
let tcx = self.tcx;
let mut reach = self.reach(trait_item_ref.id.owner_id.def_id, item_ev);
let mut reach = self.reach(trait_item_ref.owner_id.def_id, item_ev);
reach.generics().predicates();
if trait_item_ref.kind == AssocItemKind::Type
&& !tcx.defaultness(trait_item_ref.id.owner_id).has_value()
if let DefKind::AssocTy = tcx.def_kind(trait_item_ref.owner_id)
&& !tcx.defaultness(trait_item_ref.owner_id).has_value()
{
// No type to visit.
} else {
@ -715,7 +715,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
self.reach(item.owner_id.def_id, item_ev).generics().predicates().ty().trait_ref();
for impl_item_ref in impl_.items {
let def_id = impl_item_ref.id.owner_id.def_id;
let def_id = impl_item_ref.owner_id.def_id;
let max_vis =
impl_.of_trait.is_none().then(|| self.tcx.local_visibility(def_id));
self.update_eff_vis(def_id, item_ev, max_vis, Level::Direct);
@ -755,8 +755,8 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
}
hir::ItemKind::ForeignMod { items, .. } => {
for foreign_item in items {
if let Some(foreign_item_ev) = self.get(foreign_item.id.owner_id.def_id) {
self.reach(foreign_item.id.owner_id.def_id, foreign_item_ev)
if let Some(foreign_item_ev) = self.get(foreign_item.owner_id.def_id) {
self.reach(foreign_item.owner_id.def_id, foreign_item_ev)
.generics()
.predicates()
.ty();
@ -1576,16 +1576,15 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
fn check_assoc_item(
&self,
def_id: LocalDefId,
assoc_item_kind: AssocItemKind,
item: &ty::AssocItem,
vis: ty::Visibility,
effective_vis: Option<EffectiveVisibility>,
) {
let mut check = self.check(def_id, vis, effective_vis);
let mut check = self.check(item.def_id.expect_local(), vis, effective_vis);
let (check_ty, is_assoc_ty) = match assoc_item_kind {
AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false),
AssocItemKind::Type => (self.tcx.defaultness(def_id).has_value(), true),
let (check_ty, is_assoc_ty) = match item.kind {
ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => (true, false),
ty::AssocKind::Type { .. } => (item.defaultness(self.tcx).has_value(), true),
};
check.in_assoc_ty = is_assoc_ty;
@ -1619,30 +1618,20 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
self.check(def_id, item_visibility, effective_vis).generics().bounds();
}
DefKind::Trait => {
let item = tcx.hir_item(id);
if let hir::ItemKind::Trait(.., trait_item_refs) = item.kind {
self.check_unnameable(item.owner_id.def_id, effective_vis);
self.check_unnameable(def_id, effective_vis);
self.check(item.owner_id.def_id, item_visibility, effective_vis)
.generics()
.predicates();
self.check(def_id, item_visibility, effective_vis).generics().predicates();
for trait_item_ref in trait_item_refs {
self.check_assoc_item(
trait_item_ref.id.owner_id.def_id,
trait_item_ref.kind,
for assoc_item in tcx.associated_items(id.owner_id).in_definition_order() {
self.check_assoc_item(assoc_item, item_visibility, effective_vis);
if assoc_item.is_type() {
self.check(
assoc_item.def_id.expect_local(),
item_visibility,
effective_vis,
);
if let AssocItemKind::Type = trait_item_ref.kind {
self.check(
trait_item_ref.id.owner_id.def_id,
item_visibility,
effective_vis,
)
.bounds();
}
)
.bounds();
}
}
}
@ -1669,8 +1658,8 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
DefKind::ForeignMod => {
let item = tcx.hir_item(id);
if let hir::ItemKind::ForeignMod { items, .. } = item.kind {
for foreign_item in items {
let foreign_item = tcx.hir_foreign_item(foreign_item.id);
for &foreign_item in items {
let foreign_item = tcx.hir_foreign_item(foreign_item);
let ev = self.get(foreign_item.owner_id.def_id);
let vis = tcx.local_visibility(foreign_item.owner_id.def_id);
@ -1714,69 +1703,52 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
// Subitems of inherent impls have their own publicity.
// A trait impl is public when both its type and its trait are public
// Subitems of trait impls have inherited publicity.
DefKind::Impl { .. } => {
let item = tcx.hir_item(id);
if let hir::ItemKind::Impl(impl_) = item.kind {
let impl_vis = ty::Visibility::of_impl::<false>(
item.owner_id.def_id,
tcx,
&Default::default(),
);
DefKind::Impl { of_trait } => {
let impl_vis = ty::Visibility::of_impl::<false>(def_id, tcx, &Default::default());
// We are using the non-shallow version here, unlike when building the
// effective visisibilities table to avoid large number of false positives.
// For example in
//
// impl From<Priv> for Pub {
// fn from(_: Priv) -> Pub {...}
// }
//
// lints shouldn't be emitted even if `from` effective visibility
// is larger than `Priv` nominal visibility and if `Priv` can leak
// in some scenarios due to type inference.
let impl_ev = EffectiveVisibility::of_impl::<false>(
item.owner_id.def_id,
tcx,
self.effective_visibilities,
);
// We are using the non-shallow version here, unlike when building the
// effective visisibilities table to avoid large number of false positives.
// For example in
//
// impl From<Priv> for Pub {
// fn from(_: Priv) -> Pub {...}
// }
//
// lints shouldn't be emitted even if `from` effective visibility
// is larger than `Priv` nominal visibility and if `Priv` can leak
// in some scenarios due to type inference.
let impl_ev =
EffectiveVisibility::of_impl::<false>(def_id, tcx, self.effective_visibilities);
let mut check = self.check(item.owner_id.def_id, impl_vis, Some(impl_ev));
// Generics and predicates of trait impls are intentionally not checked
// for private components (#90586).
if impl_.of_trait.is_none() {
check.generics().predicates();
}
// Skip checking private components in associated types, due to lack of full
// normalization they produce very ridiculous false positives.
// FIXME: Remove this when full normalization is implemented.
check.skip_assoc_tys = true;
check.ty().trait_ref();
let mut check = self.check(def_id, impl_vis, Some(impl_ev));
for impl_item_ref in impl_.items {
let impl_item_vis = if impl_.of_trait.is_none() {
min(
tcx.local_visibility(impl_item_ref.id.owner_id.def_id),
impl_vis,
tcx,
)
} else {
impl_vis
};
// Generics and predicates of trait impls are intentionally not checked
// for private components (#90586).
if !of_trait {
check.generics().predicates();
}
let impl_item_ev = if impl_.of_trait.is_none() {
self.get(impl_item_ref.id.owner_id.def_id)
.map(|ev| ev.min(impl_ev, self.tcx))
} else {
Some(impl_ev)
};
// Skip checking private components in associated types, due to lack of full
// normalization they produce very ridiculous false positives.
// FIXME: Remove this when full normalization is implemented.
check.skip_assoc_tys = true;
check.ty().trait_ref();
self.check_assoc_item(
impl_item_ref.id.owner_id.def_id,
impl_item_ref.kind,
impl_item_vis,
impl_item_ev,
);
}
for assoc_item in tcx.associated_items(id.owner_id).in_definition_order() {
let impl_item_vis = if !of_trait {
min(tcx.local_visibility(assoc_item.def_id.expect_local()), impl_vis, tcx)
} else {
impl_vis
};
let impl_item_ev = if !of_trait {
self.get(assoc_item.def_id.expect_local())
.map(|ev| ev.min(impl_ev, self.tcx))
} else {
Some(impl_ev)
};
self.check_assoc_item(assoc_item, impl_item_vis, impl_item_ev);
}
}
_ => {}

View file

@ -841,54 +841,32 @@ fn foo(&self) -> Self::T { String::new() }
let param_env = tcx.param_env(body_owner_def_id);
match item {
hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., items), .. }) => {
// FIXME: account for `#![feature(specialization)]`
for item in &items[..] {
match item.kind {
hir::AssocItemKind::Type => {
// FIXME: account for returning some type in a trait fn impl that has
// an assoc type as a return type (#72076).
if let hir::Defaultness::Default { has_value: true } =
tcx.defaultness(item.id.owner_id)
{
let assoc_ty = tcx.type_of(item.id.owner_id).instantiate_identity();
if self.infcx.can_eq(param_env, assoc_ty, found) {
diag.span_label(
item.span,
"associated type defaults can't be assumed inside the \
trait defining them",
);
return true;
}
}
if let DefKind::Trait | DefKind::Impl { .. } = tcx.def_kind(parent_id) {
let assoc_items = tcx.associated_items(parent_id);
// FIXME: account for `#![feature(specialization)]`
for assoc_item in assoc_items.in_definition_order() {
if assoc_item.is_type()
// FIXME: account for returning some type in a trait fn impl that has
// an assoc type as a return type (#72076).
&& let hir::Defaultness::Default { has_value: true } = assoc_item.defaultness(tcx)
&& let assoc_ty = tcx.type_of(assoc_item.def_id).instantiate_identity()
&& self.infcx.can_eq(param_env, assoc_ty, found)
{
let msg = match assoc_item.container {
ty::AssocItemContainer::Trait => {
"associated type defaults can't be assumed inside the \
trait defining them"
}
_ => {}
}
ty::AssocItemContainer::Impl => {
"associated type is `default` and may be overridden"
}
};
diag.span_label(tcx.def_span(assoc_item.def_id), msg);
return true;
}
}
hir::Node::Item(hir::Item {
kind: hir::ItemKind::Impl(hir::Impl { items, .. }),
..
}) => {
for item in &items[..] {
if let hir::AssocItemKind::Type = item.kind {
let assoc_ty = tcx.type_of(item.id.owner_id).instantiate_identity();
if let hir::Defaultness::Default { has_value: true } =
tcx.defaultness(item.id.owner_id)
&& self.infcx.can_eq(param_env, assoc_ty, found)
{
diag.span_label(
item.span,
"associated type is `default` and may be overridden",
);
return true;
}
}
}
}
_ => {}
}
false
}

View file

@ -362,7 +362,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
&& self.tcx.trait_of_item(*item_id) == Some(*trait_id)
&& let None = self.tainted_by_errors()
{
let (verb, noun) = match self.tcx.associated_item(item_id).kind {
let assoc_item = self.tcx.associated_item(item_id);
let (verb, noun) = match assoc_item.kind {
ty::AssocKind::Const { .. } => ("refer to the", "constant"),
ty::AssocKind::Fn { .. } => ("call", "function"),
// This is already covered by E0223, but this following single match
@ -381,17 +382,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
);
err.code(E0790);
if let Some(local_def_id) = data.trait_ref.def_id.as_local()
&& let hir::Node::Item(hir::Item {
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_ident)
{
if item_id.is_local() {
let trait_ident = self.tcx.item_name(*trait_id);
err.span_label(
method_ref.span,
self.tcx.def_span(*item_id),
format!("`{trait_ident}::{assoc_item_ident}` defined here"),
);
}

View file

@ -288,9 +288,9 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
&& let Some(&impl_item_id) =
tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.def_id)
&& let Some(impl_item) =
items.iter().find(|item| item.id.owner_id.to_def_id() == impl_item_id)
items.iter().find(|item| item.owner_id.to_def_id() == impl_item_id)
{
Some(tcx.hir_impl_item(impl_item.id).expect_type().span)
Some(tcx.hir_impl_item(*impl_item).expect_type().span)
} else {
None
}

View file

@ -6,6 +6,8 @@ use rustc_hir::{self as hir, ItemKind};
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_span::Ident;
use rustc_span::symbol::kw;
pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers {
@ -27,7 +29,7 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] {
// query.
let rpitit_items = tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id);
tcx.arena.alloc_from_iter(trait_item_refs.iter().flat_map(|trait_item_ref| {
let item_def_id = trait_item_ref.id.owner_id.to_def_id();
let item_def_id = trait_item_ref.owner_id.to_def_id();
[item_def_id]
.into_iter()
.chain(rpitit_items.get(&item_def_id).into_iter().flatten().copied())
@ -39,7 +41,7 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] {
// associated_types_for_impl_traits_in_trait_or_impl query.
let rpitit_items = tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id);
tcx.arena.alloc_from_iter(impl_.items.iter().flat_map(|impl_item_ref| {
let item_def_id = impl_item_ref.id.owner_id.to_def_id();
let item_def_id = impl_item_ref.owner_id.to_def_id();
[item_def_id]
.into_iter()
.chain(rpitit_items.get(&item_def_id).into_iter().flatten().copied())
@ -66,46 +68,33 @@ fn impl_item_implementor_ids(tcx: TyCtxt<'_>, impl_id: DefId) -> DefIdMap<DefId>
}
fn associated_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AssocItem {
let id = tcx.local_def_id_to_hir_id(def_id);
let parent_def_id = tcx.hir_get_parent_item(id);
let parent_item = tcx.hir_expect_item(parent_def_id.def_id);
match parent_item.kind {
hir::ItemKind::Impl(impl_) => {
if let Some(impl_item_ref) = impl_.items.iter().find(|i| i.id.owner_id.def_id == def_id)
{
let assoc_item = associated_item_from_impl_item_ref(impl_item_ref);
debug_assert_eq!(assoc_item.def_id.expect_local(), def_id);
return assoc_item;
}
}
hir::ItemKind::Trait(.., trait_item_refs) => {
if let Some(trait_item_ref) =
trait_item_refs.iter().find(|i| i.id.owner_id.def_id == def_id)
{
let assoc_item = associated_item_from_trait_item_ref(trait_item_ref);
debug_assert_eq!(assoc_item.def_id.expect_local(), def_id);
return assoc_item;
}
}
_ => {}
}
span_bug!(
parent_item.span,
"unexpected parent of trait or impl item or item not found: {:?}",
parent_item.kind
)
let assoc_item = match tcx.hir_node_by_def_id(def_id) {
hir::Node::TraitItem(ti) => associated_item_from_trait_item(tcx, ti),
hir::Node::ImplItem(ii) => associated_item_from_impl_item(tcx, ii),
node => span_bug!(tcx.def_span(def_id), "impl item or item not found: {:?}", node,),
};
debug_assert_eq!(assoc_item.def_id.expect_local(), def_id);
assoc_item
}
fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty::AssocItem {
let owner_id = trait_item_ref.id.owner_id;
let name = trait_item_ref.ident.name;
let kind = match trait_item_ref.kind {
hir::AssocItemKind::Const => ty::AssocKind::Const { name },
hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { name, has_self },
hir::AssocItemKind::Type => ty::AssocKind::Type { data: ty::AssocTypeData::Normal(name) },
fn fn_has_self_parameter(tcx: TyCtxt<'_>, owner_id: hir::OwnerId) -> bool {
matches!(tcx.fn_arg_idents(owner_id.def_id), [Some(Ident { name: kw::SelfLower, .. }), ..])
}
fn associated_item_from_trait_item(
tcx: TyCtxt<'_>,
trait_item: &hir::TraitItem<'_>,
) -> ty::AssocItem {
let owner_id = trait_item.owner_id;
let name = trait_item.ident.name;
let kind = match trait_item.kind {
hir::TraitItemKind::Const { .. } => ty::AssocKind::Const { name },
hir::TraitItemKind::Fn { .. } => {
ty::AssocKind::Fn { name, has_self: fn_has_self_parameter(tcx, owner_id) }
}
hir::TraitItemKind::Type { .. } => {
ty::AssocKind::Type { data: ty::AssocTypeData::Normal(name) }
}
};
ty::AssocItem {
@ -116,19 +105,23 @@ fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty
}
}
fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::AssocItem {
let def_id = impl_item_ref.id.owner_id;
let name = impl_item_ref.ident.name;
let kind = match impl_item_ref.kind {
hir::AssocItemKind::Const => ty::AssocKind::Const { name },
hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { name, has_self },
hir::AssocItemKind::Type => ty::AssocKind::Type { data: ty::AssocTypeData::Normal(name) },
fn associated_item_from_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) -> ty::AssocItem {
let owner_id = impl_item.owner_id;
let name = impl_item.ident.name;
let kind = match impl_item.kind {
hir::ImplItemKind::Const { .. } => ty::AssocKind::Const { name },
hir::ImplItemKind::Fn { .. } => {
ty::AssocKind::Fn { name, has_self: fn_has_self_parameter(tcx, owner_id) }
}
hir::ImplItemKind::Type { .. } => {
ty::AssocKind::Type { data: ty::AssocTypeData::Normal(name) }
}
};
ty::AssocItem {
kind,
def_id: def_id.to_def_id(),
trait_item_def_id: impl_item_ref.trait_item_def_id,
def_id: owner_id.to_def_id(),
trait_item_def_id: impl_item.trait_item_def_id,
container: ty::AssocItemContainer::Impl,
}
}
@ -137,12 +130,10 @@ struct RPITVisitor<'a, 'tcx> {
synthetics: Vec<LocalDefId>,
data: DefPathData,
disambiguator: &'a mut DisambiguatorState,
depth: u32,
}
impl<'tcx> Visitor<'tcx> for RPITVisitor<'_, 'tcx> {
fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) -> Self::Result {
self.depth += 1;
self.synthetics.push(associated_type_for_impl_trait_in_trait(
self.tcx,
opaque.def_id,
@ -163,17 +154,16 @@ fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>(
ItemKind::Trait(.., trait_item_refs) => trait_item_refs
.iter()
.filter_map(move |item| {
if !matches!(item.kind, hir::AssocItemKind::Fn { .. }) {
if !matches!(tcx.def_kind(item.owner_id), DefKind::AssocFn) {
return None;
}
let fn_def_id = item.id.owner_id.def_id;
let fn_def_id = item.owner_id.def_id;
let Some(output) = tcx.hir_get_fn_output(fn_def_id) else {
return Some((fn_def_id.to_def_id(), vec![]));
};
let def_name = tcx.item_name(fn_def_id.to_def_id());
let data = DefPathData::AnonAssocTy(def_name);
let mut visitor =
RPITVisitor { tcx, synthetics: vec![], data, depth: 0, disambiguator };
let mut visitor = RPITVisitor { tcx, synthetics: vec![], data, disambiguator };
visitor.visit_fn_ret_ty(output);
let defs = visitor
.synthetics
@ -195,21 +185,17 @@ fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>(
.items
.iter()
.filter_map(|item| {
if !matches!(item.kind, hir::AssocItemKind::Fn { .. }) {
if !matches!(tcx.def_kind(item.owner_id), DefKind::AssocFn) {
return None;
}
let did = item.id.owner_id.def_id.to_def_id();
let did = item.owner_id.def_id.to_def_id();
let item = tcx.hir_impl_item(*item);
let Some(trait_item_def_id) = item.trait_item_def_id else {
return Some((did, vec![]));
};
let iter = in_trait_def[&trait_item_def_id].iter().map(|&id| {
associated_type_for_impl_trait_in_impl(
tcx,
id,
item.id.owner_id.def_id,
disambiguator,
)
.to_def_id()
associated_type_for_impl_trait_in_impl(tcx, id, item, disambiguator)
.to_def_id()
});
Some((did, iter.collect()))
})
@ -288,20 +274,20 @@ fn associated_type_for_impl_trait_in_trait(
/// Given an `trait_assoc_def_id` corresponding to an associated item synthesized
/// from an `impl Trait` in an associated function from a trait, and an
/// `impl_fn_def_id` that represents an implementation of the associated function
/// `impl_fn` that represents an implementation of the associated function
/// that the `impl Trait` comes from, synthesize an associated type for that `impl Trait`
/// that inherits properties that we infer from the method and the associated type.
fn associated_type_for_impl_trait_in_impl(
tcx: TyCtxt<'_>,
trait_assoc_def_id: DefId,
impl_fn_def_id: LocalDefId,
impl_fn: &hir::ImplItem<'_>,
disambiguator: &mut DisambiguatorState,
) -> LocalDefId {
let impl_local_def_id = tcx.local_parent(impl_fn_def_id);
let impl_local_def_id = tcx.local_parent(impl_fn.owner_id.def_id);
let decl = tcx.hir_node_by_def_id(impl_fn_def_id).fn_decl().expect("expected decl");
let span = match decl.output {
hir::FnRetTy::DefaultReturn(_) => tcx.def_span(impl_fn_def_id),
let hir::ImplItemKind::Fn(fn_sig, _) = impl_fn.kind else { bug!("expected decl") };
let span = match fn_sig.decl.output {
hir::FnRetTy::DefaultReturn(_) => tcx.def_span(impl_fn.owner_id),
hir::FnRetTy::Return(ty) => ty.span,
};
@ -332,7 +318,7 @@ fn associated_type_for_impl_trait_in_impl(
impl_assoc_ty.associated_item(ty::AssocItem {
kind: ty::AssocKind::Type {
data: ty::AssocTypeData::Rpitit(ImplTraitInTraitData::Impl {
fn_def_id: impl_fn_def_id.to_def_id(),
fn_def_id: impl_fn.owner_id.to_def_id(),
}),
},
def_id,
@ -341,10 +327,10 @@ fn associated_type_for_impl_trait_in_impl(
});
// Copy visility of the containing function.
impl_assoc_ty.visibility(tcx.visibility(impl_fn_def_id));
impl_assoc_ty.visibility(tcx.visibility(impl_fn.owner_id));
// Copy defaultness of the containing function.
impl_assoc_ty.defaultness(tcx.defaultness(impl_fn_def_id));
impl_assoc_ty.defaultness(tcx.defaultness(impl_fn.owner_id));
// Copy generics_of the trait's associated item but the impl as the parent.
// FIXME: This may be detrimental to diagnostics, as we resolve the early-bound vars

View file

@ -499,7 +499,7 @@ pub(crate) fn build_impl(
impl_
.items
.iter()
.map(|item| tcx.hir_impl_item(item.id))
.map(|&item| tcx.hir_impl_item(item))
.filter(|item| {
// Filter out impl items whose corresponding trait item has `doc(hidden)`
// not to document such impl items.

View file

@ -2867,7 +2867,7 @@ fn clean_maybe_renamed_item<'tcx>(
ItemKind::Trait(_, _, _, generics, bounds, item_ids) => {
let items = item_ids
.iter()
.map(|ti| clean_trait_item(cx.tcx.hir_trait_item(ti.id), cx))
.map(|&ti| clean_trait_item(cx.tcx.hir_trait_item(ti), cx))
.collect();
TraitItem(Box::new(Trait {
@ -2910,7 +2910,7 @@ fn clean_impl<'tcx>(
let items = impl_
.items
.iter()
.map(|ii| clean_impl_item(tcx.hir_impl_item(ii.id), cx))
.map(|&ii| clean_impl_item(tcx.hir_impl_item(ii), cx))
.collect::<Vec<_>>();
// If this impl block is an implementation of the Deref trait, then we

View file

@ -469,8 +469,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
match item.kind {
hir::ItemKind::ForeignMod { items, .. } => {
for item in items {
let item = tcx.hir_foreign_item(item.id);
for &item in items {
let item = tcx.hir_foreign_item(item);
self.visit_foreign_item_inner(item, None, None);
}
}

View file

@ -8,11 +8,13 @@ use clippy_utils::diagnostics::span_lint_and_note;
use clippy_utils::is_cfg_test;
use rustc_attr_data_structures::AttributeKind;
use rustc_hir::{
AssocItemKind, Attribute, FieldDef, HirId, ImplItemRef, IsAuto, Item, ItemKind, Mod, QPath, TraitItemRef, TyKind,
Attribute, FieldDef, HirId, IsAuto, ImplItemId, Item, ItemKind, Mod, OwnerId, QPath, TraitItemId, TyKind,
Variant, VariantData,
};
use rustc_middle::ty::AssocKind;
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::impl_lint_pass;
use rustc_span::Ident;
declare_clippy_lint! {
/// ### What it does
@ -194,22 +196,22 @@ impl ArbitrarySourceItemOrdering {
}
/// Produces a linting warning for incorrectly ordered impl items.
fn lint_impl_item<T: LintContext>(&self, cx: &T, item: &ImplItemRef, before_item: &ImplItemRef) {
fn lint_impl_item(&self, cx: &LateContext<'_>, item: ImplItemId, before_item: ImplItemId) {
span_lint_and_note(
cx,
ARBITRARY_SOURCE_ITEM_ORDERING,
item.span,
cx.tcx.def_span(item.owner_id),
format!(
"incorrect ordering of impl items (defined order: {:?})",
self.assoc_types_order
),
Some(before_item.span),
format!("should be placed before `{}`", before_item.ident.name),
Some(cx.tcx.def_span(before_item.owner_id)),
format!("should be placed before `{}`", cx.tcx.item_name(before_item.owner_id)),
);
}
/// Produces a linting warning for incorrectly ordered item members.
fn lint_member_name<T: LintContext>(cx: &T, ident: &rustc_span::Ident, before_ident: &rustc_span::Ident) {
fn lint_member_name<T: LintContext>(cx: &T, ident: Ident, before_ident: Ident) {
span_lint_and_note(
cx,
ARBITRARY_SOURCE_ITEM_ORDERING,
@ -220,7 +222,7 @@ impl ArbitrarySourceItemOrdering {
);
}
fn lint_member_item<T: LintContext>(cx: &T, item: &Item<'_>, before_item: &Item<'_>, msg: &'static str) {
fn lint_member_item(cx: &LateContext<'_>, item: &Item<'_>, before_item: &Item<'_>, msg: &'static str) {
let span = if let Some(ident) = item.kind.ident() {
ident.span
} else {
@ -245,17 +247,17 @@ impl ArbitrarySourceItemOrdering {
}
/// Produces a linting warning for incorrectly ordered trait items.
fn lint_trait_item<T: LintContext>(&self, cx: &T, item: &TraitItemRef, before_item: &TraitItemRef) {
fn lint_trait_item(&self, cx: &LateContext<'_>, item: TraitItemId, before_item: TraitItemId) {
span_lint_and_note(
cx,
ARBITRARY_SOURCE_ITEM_ORDERING,
item.span,
cx.tcx.def_span(item.owner_id),
format!(
"incorrect ordering of trait items (defined order: {:?})",
self.assoc_types_order
),
Some(before_item.span),
format!("should be placed before `{}`", before_item.ident.name),
Some(cx.tcx.def_span(before_item.owner_id)),
format!("should be placed before `{}`", cx.tcx.item_name(before_item.owner_id)),
);
}
}
@ -283,7 +285,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
&& cur_v.ident.name.as_str() > variant.ident.name.as_str()
&& cur_v.span != variant.span
{
Self::lint_member_name(cx, &variant.ident, &cur_v.ident);
Self::lint_member_name(cx, variant.ident, cur_v.ident);
}
cur_v = Some(variant);
}
@ -299,7 +301,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
&& cur_f.ident.name.as_str() > field.ident.name.as_str()
&& cur_f.span != field.span
{
Self::lint_member_name(cx, &field.ident, &cur_f.ident);
Self::lint_member_name(cx, field.ident, cur_f.ident);
}
cur_f = Some(field);
}
@ -307,49 +309,53 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
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;
let mut cur_t: Option<(TraitItemId, Ident)> = None;
for item in *item_ref {
if item.span.in_external_macro(cx.sess().source_map()) {
for &item in *item_ref {
let span = cx.tcx.def_span(item.owner_id);
let ident = cx.tcx.item_ident(item.owner_id);
if span.in_external_macro(cx.sess().source_map()) {
continue;
}
if let Some(cur_t) = cur_t {
let cur_t_kind = convert_assoc_item_kind(cur_t.kind);
if let Some((cur_t, cur_ident)) = cur_t {
let cur_t_kind = convert_assoc_item_kind(cx, cur_t.owner_id);
let cur_t_kind_index = self.assoc_types_order.index_of(&cur_t_kind);
let item_kind = convert_assoc_item_kind(item.kind);
let item_kind = convert_assoc_item_kind(cx, item.owner_id);
let item_kind_index = self.assoc_types_order.index_of(&item_kind);
if cur_t_kind == item_kind && cur_t.ident.name.as_str() > item.ident.name.as_str() {
Self::lint_member_name(cx, &item.ident, &cur_t.ident);
if cur_t_kind == item_kind && cur_ident.name.as_str() > ident.name.as_str() {
Self::lint_member_name(cx, ident, cur_ident);
} else if cur_t_kind_index > item_kind_index {
self.lint_trait_item(cx, item, cur_t);
}
}
cur_t = Some(item);
cur_t = Some((item, ident));
}
},
ItemKind::Impl(trait_impl) if self.enable_ordering_for_impl => {
let mut cur_t: Option<&ImplItemRef> = None;
let mut cur_t: Option<(ImplItemId, Ident)> = None;
for item in trait_impl.items {
if item.span.in_external_macro(cx.sess().source_map()) {
for &item in trait_impl.items {
let span = cx.tcx.def_span(item.owner_id);
let ident = cx.tcx.item_ident(item.owner_id);
if span.in_external_macro(cx.sess().source_map()) {
continue;
}
if let Some(cur_t) = cur_t {
let cur_t_kind = convert_assoc_item_kind(cur_t.kind);
if let Some((cur_t, cur_ident)) = cur_t {
let cur_t_kind = convert_assoc_item_kind(cx, cur_t.owner_id);
let cur_t_kind_index = self.assoc_types_order.index_of(&cur_t_kind);
let item_kind = convert_assoc_item_kind(item.kind);
let item_kind = convert_assoc_item_kind(cx, item.owner_id);
let item_kind_index = self.assoc_types_order.index_of(&item_kind);
if cur_t_kind == item_kind && cur_t.ident.name.as_str() > item.ident.name.as_str() {
Self::lint_member_name(cx, &item.ident, &cur_t.ident);
if cur_t_kind == item_kind && cur_ident.name.as_str() > ident.name.as_str() {
Self::lint_member_name(cx, ident, cur_ident);
} else if cur_t_kind_index > item_kind_index {
self.lint_impl_item(cx, item, cur_t);
}
}
cur_t = Some(item);
cur_t = Some((item, ident));
}
},
_ => {}, // Catch-all for `ItemKinds` that don't have fields.
@ -458,18 +464,19 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
}
}
/// Converts a [`rustc_hir::AssocItemKind`] to a
/// [`SourceItemOrderingTraitAssocItemKind`].
/// Converts a [`ty::AssocKind`] to a [`SourceItemOrderingTraitAssocItemKind`].
///
/// This is implemented here because `rustc_hir` is not a dependency of
/// `clippy_config`.
fn convert_assoc_item_kind(value: AssocItemKind) -> SourceItemOrderingTraitAssocItemKind {
fn convert_assoc_item_kind(cx: &LateContext<'_>, owner_id: OwnerId) -> SourceItemOrderingTraitAssocItemKind {
let kind = cx.tcx.associated_item(owner_id.def_id).kind;
#[allow(clippy::enum_glob_use)] // Very local glob use for legibility.
use SourceItemOrderingTraitAssocItemKind::*;
match value {
AssocItemKind::Const => Const,
AssocItemKind::Type => Type,
AssocItemKind::Fn { .. } => Fn,
match kind {
AssocKind::Const{..} => Const,
AssocKind::Type {..}=> Type,
AssocKind::Fn { .. } => Fn,
}
}

View file

@ -192,7 +192,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
&& !item.span.from_expansion()
&& let Some(def_id) = trait_ref.trait_def_id()
&& cx.tcx.is_diagnostic_item(sym::Default, def_id)
&& let impl_item_hir = child.id.hir_id()
&& let impl_item_hir = child.hir_id()
&& let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir)
&& let ImplItemKind::Fn(_, b) = &impl_item.kind
&& let Body { value: func_expr, .. } = cx.tcx.hir_body(*b)

View file

@ -41,7 +41,7 @@ impl LateLintPass<'_> for EmptyDrop {
..
}) = item.kind
&& trait_ref.trait_def_id() == cx.tcx.lang_items().drop_trait()
&& let impl_item_hir = child.id.hir_id()
&& let impl_item_hir = child.hir_id()
&& let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir)
&& let ImplItemKind::Fn(_, b) = &impl_item.kind
&& let Body { value: func_expr, .. } = cx.tcx.hir_body(*b)

View file

@ -1,7 +1,8 @@
use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_hir;
use rustc_abi::ExternAbi;
use rustc_hir::{AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node, Pat, PatKind, intravisit};
use rustc_hir::{Body, FnDecl, HirId, HirIdSet, Node, Pat, PatKind, intravisit};
use rustc_hir::def::DefKind;
use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::mir::FakeReadCause;
@ -84,23 +85,18 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
.def_id;
let mut trait_self_ty = None;
if let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent_id) {
match cx.tcx.def_kind(parent_id) {
// If the method is an impl for a trait, don't warn.
if let ItemKind::Impl(Impl { of_trait: Some(_), .. }) = item.kind {
return;
DefKind::Impl { of_trait: true } => {
return
}
// find `self` ty for this trait if relevant
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
&& trait_item.kind == (AssocItemKind::Fn { has_self: true })
{
trait_self_ty = Some(TraitRef::identity(cx.tcx, trait_item.id.owner_id.to_def_id()).self_ty());
}
}
DefKind::Trait => {
trait_self_ty = Some(TraitRef::identity(cx.tcx, parent_id.to_def_id()).self_ty());
}
_ => {}
}
let mut v = EscapeDelegate {

View file

@ -52,20 +52,20 @@ declare_lint_pass!(FallibleImplFrom => [FALLIBLE_IMPL_FROM]);
impl<'tcx> LateLintPass<'tcx> for FallibleImplFrom {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
// check for `impl From<???> for ..`
if let hir::ItemKind::Impl(impl_) = &item.kind
if let hir::ItemKind::Impl(_) = &item.kind
&& let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id)
&& cx
.tcx
.is_diagnostic_item(sym::From, impl_trait_ref.skip_binder().def_id)
{
lint_impl_body(cx, item.span, impl_.items);
lint_impl_body(cx, item.owner_id, item.span);
}
}
}
fn lint_impl_body(cx: &LateContext<'_>, impl_span: Span, impl_items: &[hir::ImplItemRef]) {
fn lint_impl_body(cx: &LateContext<'_>, item_def_id: hir::OwnerId, impl_span: Span) {
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{Expr, ImplItemKind};
use rustc_hir::Expr;
struct FindPanicUnwrap<'a, 'tcx> {
lcx: &'a LateContext<'tcx>,
@ -96,35 +96,35 @@ fn lint_impl_body(cx: &LateContext<'_>, impl_span: Span, impl_items: &[hir::Impl
}
}
for impl_item in impl_items {
if impl_item.ident.name == sym::from
&& let ImplItemKind::Fn(_, body_id) = cx.tcx.hir_impl_item(impl_item.id).kind
{
// check the body for `begin_panic` or `unwrap`
let body = cx.tcx.hir_body(body_id);
let mut fpu = FindPanicUnwrap {
lcx: cx,
typeck_results: cx.tcx.typeck(impl_item.id.owner_id.def_id),
result: Vec::new(),
};
fpu.visit_expr(body.value);
for impl_item in cx.tcx.associated_items(item_def_id)
.filter_by_name_unhygienic_and_kind(sym::from, ty::AssocTag::Fn)
{
let impl_item_def_id= impl_item.def_id.expect_local();
// if we've found one, lint
if !fpu.result.is_empty() {
span_lint_and_then(
cx,
FALLIBLE_IMPL_FROM,
impl_span,
"consider implementing `TryFrom` instead",
move |diag| {
diag.help(
"`From` is intended for infallible conversions only. \
Use `TryFrom` if there's a possibility for the conversion to fail",
);
diag.span_note(fpu.result, "potential failure(s)");
},
);
}
// check the body for `begin_panic` or `unwrap`
let body = cx.tcx.hir_body_owned_by(impl_item_def_id);
let mut fpu = FindPanicUnwrap {
lcx: cx,
typeck_results: cx.tcx.typeck(impl_item_def_id),
result: Vec::new(),
};
fpu.visit_expr(body.value);
// if we've found one, lint
if !fpu.result.is_empty() {
span_lint_and_then(
cx,
FALLIBLE_IMPL_FROM,
impl_span,
"consider implementing `TryFrom` instead",
move |diag| {
diag.help(
"`From` is intended for infallible conversions only. \
Use `TryFrom` if there's a possibility for the conversion to fail",
);
diag.span_note(fpu.result, "potential failure(s)");
},
);
}
}
}

View file

@ -9,7 +9,7 @@ use clippy_utils::source::SpanRangeExt;
use rustc_errors::Applicability;
use rustc_hir::intravisit::{Visitor, walk_path};
use rustc_hir::{
FnRetTy, GenericArg, GenericArgs, HirId, Impl, ImplItemKind, ImplItemRef, Item, ItemKind, PatKind, Path,
FnRetTy, GenericArg, GenericArgs, HirId, Impl, ImplItemKind, ImplItemId, Item, ItemKind, PatKind, Path,
PathSegment, Ty, TyKind,
};
use rustc_lint::{LateContext, LateLintPass};
@ -102,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto {
middle_trait_ref.self_ty()
);
if let Some(suggestions) =
convert_to_from(cx, into_trait_seg, target_ty.as_unambig_ty(), self_ty, impl_item_ref)
convert_to_from(cx, into_trait_seg, target_ty.as_unambig_ty(), self_ty, *impl_item_ref)
{
diag.multipart_suggestion(message, suggestions, Applicability::MachineApplicable);
} else {
@ -164,14 +164,14 @@ fn convert_to_from(
into_trait_seg: &PathSegment<'_>,
target_ty: &Ty<'_>,
self_ty: &Ty<'_>,
impl_item_ref: &ImplItemRef,
impl_item_ref: ImplItemId,
) -> Option<Vec<(Span, String)>> {
if !target_ty.find_self_aliases().is_empty() {
// It's tricky to expand self-aliases correctly, we'll ignore it to not cause a
// bad suggestion/fix.
return None;
}
let impl_item = cx.tcx.hir_impl_item(impl_item_ref.id);
let impl_item = cx.tcx.hir_impl_item(impl_item_ref);
let ImplItemKind::Fn(ref sig, body_id) = impl_item.kind else {
return None;
};

View file

@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
use rustc_errors::{Applicability, MultiSpan};
use rustc_hir::def_id::{DefId, DefIdSet};
use rustc_hir::hir_id::OwnerId;
use rustc_hir::{Impl, ImplItem, ImplItemKind, ImplItemRef, ItemKind, Node, TraitRef};
use rustc_hir::{Impl, ImplItem, ImplItemKind, ItemKind, Node, TraitRef};
use rustc_lint::LateContext;
use rustc_span::Span;
use rustc_span::symbol::{Ident, kw};
@ -15,11 +15,10 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, item: &ImplItem<'_>, ignored
&& let parent_node = cx.tcx.parent_hir_node(item.hir_id())
&& let Node::Item(parent_item) = parent_node
&& let ItemKind::Impl(Impl {
items,
of_trait: Some(trait_ref),
..
}) = &parent_item.kind
&& let Some(did) = trait_item_def_id_of_impl(items, item.owner_id)
&& let Some(did) = trait_item_def_id_of_impl(cx, item.owner_id)
&& !is_from_ignored_trait(trait_ref, ignored_traits)
{
let mut param_idents_iter = cx.tcx.hir_body_param_idents(body_id);
@ -93,14 +92,8 @@ impl RenamedFnArgs {
}
/// Get the [`trait_item_def_id`](ImplItemRef::trait_item_def_id) of a relevant impl item.
fn trait_item_def_id_of_impl(items: &[ImplItemRef], target: OwnerId) -> Option<DefId> {
items.iter().find_map(|item| {
if item.id.owner_id == target {
item.trait_item_def_id
} else {
None
}
})
fn trait_item_def_id_of_impl(cx: &LateContext<'_>, target: OwnerId) -> Option<DefId> {
cx.tcx.associated_item(target).trait_item_def_id
}
fn is_from_ignored_trait(of_trait: &TraitRef<'_>, ignored_traits: &DefIdSet) -> bool {

View file

@ -130,7 +130,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
});
let mut ctr_vis = ImplicitHasherConstructorVisitor::new(cx, target);
for item in impl_.items.iter().map(|item| cx.tcx.hir_impl_item(item.id)) {
for item in impl_.items.iter().map(|&item| cx.tcx.hir_impl_item(item)) {
ctr_vis.visit_impl_item(item);
}

View file

@ -1,8 +1,9 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::sym;
use rustc_errors::MultiSpan;
use rustc_hir::{AssocItemKind, Item, ItemKind};
use rustc_hir::{Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::AssocTag;
use rustc_session::declare_lint_pass;
declare_clippy_lint! {
@ -51,25 +52,23 @@ impl<'tcx> LateLintPass<'tcx> for InfallibleTryFrom {
if !cx.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id) {
return;
}
for ii in imp.items {
if ii.kind == AssocItemKind::Type {
let ii = cx.tcx.hir_impl_item(ii.id);
if ii.ident.name != sym::Error {
continue;
}
let ii_ty = ii.expect_type();
let ii_ty_span = ii_ty.span;
let ii_ty = clippy_utils::ty::ty_from_hir_ty(cx, ii_ty);
if !ii_ty.is_inhabited_from(cx.tcx, ii.owner_id.to_def_id(), cx.typing_env()) {
let mut span = MultiSpan::from_span(cx.tcx.def_span(item.owner_id.to_def_id()));
span.push_span_label(ii_ty_span, "infallible error type");
span_lint(
cx,
INFALLIBLE_TRY_FROM,
span,
"infallible TryFrom impl; consider implementing From, instead",
);
}
for ii in cx.tcx.associated_items(item.owner_id.def_id)
.filter_by_name_unhygienic_and_kind(sym::Error, AssocTag::Type)
{
let ii_ty = cx.tcx.type_of(ii.def_id).instantiate_identity();
if !ii_ty.is_inhabited_from(cx.tcx, ii.def_id, cx.typing_env()) {
let mut span = MultiSpan::from_span(cx.tcx.def_span(item.owner_id.to_def_id()));
let ii_ty_span = cx.tcx.hir_node_by_def_id(ii.def_id.expect_local())
.expect_impl_item()
.expect_type()
.span;
span.push_span_label(ii_ty_span, "infallible error type");
span_lint(
cx,
INFALLIBLE_TRY_FROM,
span,
"infallible TryFrom impl; consider implementing From, instead",
);
}
}
}

View file

@ -139,13 +139,12 @@ impl LateLintPass<'_> for IterWithoutIntoIter {
// We can't check inherent impls for slices, but we know that they have an `iter(_mut)` method
ty.peel_refs().is_slice() || get_adt_inherent_method(cx, ty, expected_method_name).is_some()
})
&& let Some(iter_assoc_span) = imp.items.iter().find_map(|item| {
if item.ident.name == sym::IntoIter {
Some(cx.tcx.hir_impl_item(item.id).expect_type().span)
} else {
None
}
})
&& let Some(iter_assoc_span) = cx.tcx.associated_items(item.owner_id)
.filter_by_name_unhygienic_and_kind(sym::IntoIter, ty::AssocTag::Type)
.next()
.map(|assoc_item| {
cx.tcx.hir_node_by_def_id(assoc_item.def_id.expect_local()).expect_impl_item().expect_type().span
})
&& is_ty_exported(cx, ty)
{
span_lint_and_then(

View file

@ -10,14 +10,15 @@ use rustc_errors::Applicability;
use rustc_hir::def::Res;
use rustc_hir::def_id::{DefId, DefIdSet};
use rustc_hir::{
AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, HirId, ImplItem, ImplItemKind,
BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, HirId, ImplItem, ImplItemKind,
ImplicitSelfKind, Item, ItemKind, Mutability, Node, OpaqueTyOrigin, PatExprKind, PatKind, PathSegment, PrimTy,
QPath, TraitItemRef, TyKind,
QPath, TraitItemId, TyKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, FnSig, Ty};
use rustc_session::declare_lint_pass;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::kw;
use rustc_span::{Ident, Span, Symbol};
use rustc_trait_selection::traits::supertrait_def_ids;
@ -264,22 +265,13 @@ fn span_without_enclosing_paren(cx: &LateContext<'_>, span: Span) -> Span {
}
}
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 {
has_self && {
cx.tcx
.fn_sig(item.id.owner_id)
.skip_binder()
.inputs()
.skip_binder()
.len()
== 1
}
} else {
false
}
fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Ident, trait_items: &[TraitItemId]) {
fn is_named_self(cx: &LateContext<'_>, item: &TraitItemId, name: Symbol) -> bool {
cx.tcx.item_name(item.owner_id) == name
&& matches!(
cx.tcx.fn_arg_idents(item.owner_id),
[Some(Ident { name: kw::SelfLower, .. })],
)
}
// fill the set with current and super traits

View file

@ -716,7 +716,7 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'
walk_trait_ref(&mut checker, trait_ref);
}
walk_unambig_ty(&mut checker, impl_.self_ty);
for item in impl_.items {
for &item in impl_.items {
walk_impl_item_ref(&mut checker, item);
}

View file

@ -8,7 +8,7 @@ use rustc_ast::LitKind;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{
Block, Expr, ExprKind, Impl, ImplItem, ImplItemKind, Item, ItemKind, LangItem, Node, QPath, TyKind, VariantData,
Block, Expr, ExprKind, Impl, Item, ItemKind, LangItem, Node, QPath, TyKind, VariantData,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{Ty, TypeckResults};
@ -200,7 +200,7 @@ fn check_struct<'tcx>(
impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
// is this an `impl Debug for X` block?
if let ItemKind::Impl(Impl { of_trait: Some(trait_ref), self_ty, items, .. }) = item.kind
if let ItemKind::Impl(Impl { of_trait: Some(trait_ref), self_ty, .. }) = item.kind
&& let Res::Def(DefKind::Trait, trait_def_id) = trait_ref.path.res
&& let TyKind::Path(QPath::Resolved(_, self_path)) = &self_ty.kind
// make sure that the self type is either a struct, an enum or a union
@ -212,9 +212,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug {
&& !cx.tcx.is_automatically_derived(item.owner_id.to_def_id())
&& !item.span.from_expansion()
// find `Debug::fmt` function
&& let Some(fmt_item) = items.iter().find(|i| i.ident.name == sym::fmt)
&& let ImplItem { kind: ImplItemKind::Fn(_, body_id), .. } = cx.tcx.hir_impl_item(fmt_item.id)
&& let body = cx.tcx.hir_body(*body_id)
&& let Some(fmt_item) = cx.tcx.associated_items(item.owner_id).filter_by_name_unhygienic(sym::fmt).next()
&& let body = cx.tcx.hir_body_owned_by(fmt_item.def_id.expect_local())
&& let ExprKind::Block(block, _) = body.value.kind
// inspect `self`
&& let self_ty = cx.tcx.type_of(self_path_did).skip_binder().peel_refs()
@ -222,7 +221,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug {
&& let Some(self_def_id) = self_adt.did().as_local()
&& let Node::Item(self_item) = cx.tcx.hir_node_by_def_id(self_def_id)
// NB: can't call cx.typeck_results() as we are not in a body
&& let typeck_results = cx.tcx.typeck_body(*body_id)
&& let typeck_results = cx.tcx.typeck_body(body.id())
&& should_lint(cx, typeck_results, block)
// we intentionally only lint structs, see lint description
&& let ItemKind::Struct(_, _, data) = &self_item.kind

View file

@ -104,16 +104,16 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
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 {
let tit_ = cx.tcx.hir_trait_item(tit.id);
for &tit in trait_items {
let tit_ = cx.tcx.hir_trait_item(tit);
match tit_.kind {
hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => {},
hir::TraitItemKind::Fn(..) => {
if cx.tcx.defaultness(tit.id.owner_id).has_value() {
if cx.tcx.defaultness(tit.owner_id).has_value() {
// trait method with default body needs inline in case
// an impl is not provided
let desc = "a default trait method";
let item = cx.tcx.hir_trait_item(tit.id);
let item = cx.tcx.hir_trait_item(tit);
let attrs = cx.tcx.hir_attrs(item.hir_id());
check_missing_inline_attrs(cx, attrs, item.span, desc);
}

View file

@ -61,15 +61,14 @@ impl<'tcx> LateLintPass<'tcx> for MissingTraitMethods {
if !is_lint_allowed(cx, MISSING_TRAIT_METHODS, item.hir_id())
&& span_is_local(item.span)
&& let ItemKind::Impl(Impl {
items,
of_trait: Some(trait_ref),
..
}) = item.kind
&& let Some(trait_id) = trait_ref.trait_def_id()
{
let trait_item_ids: DefIdSet = items
.iter()
.filter_map(|impl_item| impl_item.trait_item_def_id)
let trait_item_ids: DefIdSet = cx.tcx.associated_items(item.owner_id)
.in_definition_order()
.filter_map(|assoc_item| assoc_item.trait_item_def_id)
.collect();
for assoc in cx

View file

@ -6,6 +6,7 @@ use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::HirIdSet;
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::ty::AssocKind;
use rustc_session::impl_lint_pass;
use rustc_span::sym;
@ -61,18 +62,18 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
of_trait: None,
generics,
self_ty: impl_self_ty,
items,
..
}) = item.kind
{
for assoc_item in *items {
if assoc_item.kind == (hir::AssocItemKind::Fn { has_self: false }) {
let impl_item = cx.tcx.hir_impl_item(assoc_item.id);
for assoc_item in cx.tcx.associated_items(item.owner_id.def_id)
.filter_by_name_unhygienic(sym::new)
{
if let AssocKind::Fn { has_self: false, .. } = assoc_item.kind {
let impl_item = cx.tcx.hir_node_by_def_id(assoc_item.def_id.expect_local()).expect_impl_item();
if impl_item.span.in_external_macro(cx.sess().source_map()) {
return;
}
if let hir::ImplItemKind::Fn(ref sig, _) = impl_item.kind {
let name = impl_item.ident.name;
let id = impl_item.owner_id;
if sig.header.is_unsafe() {
// can't be implemented for unsafe new
@ -88,11 +89,9 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
return;
}
if sig.decl.inputs.is_empty()
&& name == sym::new
&& cx.effective_visibilities.is_reachable(impl_item.owner_id.def_id)
&& let self_def_id = cx.tcx.hir_get_parent_item(id.into())
&& let self_ty = cx.tcx.type_of(self_def_id).instantiate_identity()
&& self_ty == return_ty(cx, id)
&& let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
&& self_ty == return_ty(cx, impl_item.owner_id)
&& let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default)
{
if self.impling_types.is_none() {
@ -111,7 +110,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
// Check if a Default implementation exists for the Self type, regardless of
// generics
if let Some(ref impling_types) = self.impling_types
&& let self_def = cx.tcx.type_of(self_def_id).instantiate_identity()
&& let self_def = cx.tcx.type_of(item.owner_id).instantiate_identity()
&& let Some(self_def) = self_def.ty_adt_def()
&& let Some(self_local_did) = self_def.did().as_local()
&& let self_id = cx.tcx.local_def_id_to_hir_id(self_local_did)

View file

@ -43,12 +43,12 @@ impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl {
&& trait_ref.path.res.def_id() == eq_trait
{
for impl_item in *impl_items {
if impl_item.ident.name == sym::ne {
if cx.tcx.item_name(impl_item.owner_id) == sym::ne {
span_lint_hir(
cx,
PARTIALEQ_NE_IMPL,
impl_item.id.hir_id(),
impl_item.span,
impl_item.hir_id(),
cx.tcx.def_span(impl_item.owner_id),
"re-implementing `PartialEq::ne` is unnecessary",
);
}

View file

@ -3,7 +3,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{HirId, Impl, ItemKind, Node, Path, QPath, TraitRef, TyKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::AssocItem;
use rustc_middle::ty::{AssocKind, AssocItem};
use rustc_session::declare_lint_pass;
use rustc_span::Span;
use rustc_span::symbol::Symbol;
@ -54,7 +54,6 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl { .. })
&& let item = cx.tcx.hir_item(id)
&& let ItemKind::Impl(Impl {
items,
of_trait,
self_ty,
..
@ -115,13 +114,11 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
}
};
for impl_item_ref in (*items)
.iter()
.filter(|impl_item_ref| matches!(impl_item_ref.kind, rustc_hir::AssocItemKind::Fn { .. }))
{
let method_name = impl_item_ref.ident.name;
methods_in_trait.remove(&method_name);
check_trait_method(method_name, impl_item_ref.span);
for assoc_item in cx.tcx.associated_items(id.owner_id).in_definition_order() {
if let AssocKind::Fn { name, .. } = assoc_item.kind {
methods_in_trait.remove(&name);
check_trait_method(name, cx.tcx.def_span(assoc_item.def_id));
}
}
for method_name in methods_in_trait {
@ -129,14 +126,11 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
}
},
None => {
for impl_item_ref in (*items)
.iter()
.filter(|impl_item_ref| matches!(impl_item_ref.kind, rustc_hir::AssocItemKind::Fn { .. }))
{
let method_name = impl_item_ref.ident.name;
let impl_span = impl_item_ref.span;
let hir_id = impl_item_ref.id.hir_id();
if let Some(trait_spans) = existing_name.trait_methods.get(&method_name) {
for assoc_item in cx.tcx.associated_items(id.owner_id).in_definition_order() {
let AssocKind::Fn { name, .. } = assoc_item.kind else { continue };
let impl_span = cx.tcx.def_span(assoc_item.def_id);
let hir_id = cx.tcx.local_def_id_to_hir_id(assoc_item.def_id.expect_local());
if let Some(trait_spans) = existing_name.trait_methods.get(&name) {
span_lint_hir_and_then(
cx,
SAME_NAME_METHOD,
@ -148,12 +142,12 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
// iterate on trait_spans?
diag.span_note(
trait_spans[0],
format!("existing `{method_name}` defined here"),
format!("existing `{name}` defined here"),
);
},
);
}
existing_name.impl_methods.insert(method_name, (impl_span, hir_id));
existing_name.impl_methods.insert(name, (impl_span, hir_id));
}
},
}

View file

@ -36,9 +36,9 @@ impl<'tcx> LateLintPass<'tcx> for SerdeApi {
let mut seen_str = None;
let mut seen_string = None;
for item in *items {
match item.ident.name {
sym::visit_str => seen_str = Some(item.span),
sym::visit_string => seen_string = Some(item.span),
match cx.tcx.item_name(item.owner_id) {
sym::visit_str => seen_str = Some(cx.tcx.def_span(item.owner_id)),
sym::visit_string => seen_string = Some(cx.tcx.def_span(item.owner_id)),
_ => {},
}
}

View file

@ -10,7 +10,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def::Namespace::{MacroNS, TypeNS, ValueNS};
use rustc_hir::def::{DefKind, Namespace, Res};
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
use rustc_hir::{ImplItemRef, ItemKind, Node, OwnerId, TraitItemRef, UseKind};
use rustc_hir::{ItemKind, Node, UseKind};
use rustc_lint::LateContext;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::{FloatTy, IntTy, Ty, TyCtxt, UintTy};
@ -284,14 +284,6 @@ fn local_item_child_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, ns: PathNS, n
_ => return None,
};
let res = |ident: Ident, owner_id: OwnerId| {
if ident.name == name && ns.matches(tcx.def_kind(owner_id).ns()) {
Some(owner_id.to_def_id())
} else {
None
}
};
match item_kind {
ItemKind::Mod(_, r#mod) => r#mod.item_ids.iter().find_map(|&item_id| {
let item = tcx.hir_item(item_id);
@ -307,17 +299,19 @@ fn local_item_child_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, ns: PathNS, n
} else {
None
}
} else if let Some(ident) = item.kind.ident()
&& ident.name == name
&& ns.matches(tcx.def_kind(item.owner_id).ns())
{
Some(item.owner_id.to_def_id())
} else {
res(item.kind.ident()?, item_id.owner_id)
None
}
}),
ItemKind::Impl(r#impl) => r#impl
.items
.iter()
.find_map(|&ImplItemRef { ident, id, .. }| res(ident, id.owner_id)),
ItemKind::Trait(.., trait_item_refs) => trait_item_refs
.iter()
.find_map(|&TraitItemRef { ident, id, .. }| res(ident, id.owner_id)),
ItemKind::Impl(..) | ItemKind::Trait(..)
=> tcx.associated_items(local_id).filter_by_name_unhygienic(name)
.find(|assoc_item| ns.matches(Some(assoc_item.namespace())))
.map(|assoc_item| assoc_item.def_id),
_ => None,
}
}

View file

@ -136,13 +136,13 @@ error: incorrect ordering of trait items (defined order: [Const, Type, Fn])
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:5
|
LL | const A: bool;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
|
note: should be placed before `SomeType`
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:153:5
|
LL | type SomeType;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
error: incorrect ordering of items (must be alphabetically ordered)
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:11
@ -172,13 +172,13 @@ error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:189:5
|
LL | const A: bool = false;
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
|
note: should be placed before `SomeType`
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:187:5
|
LL | type SomeType = ();
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
error: aborting due to 15 previous errors

View file

@ -136,13 +136,13 @@ error: incorrect ordering of trait items (defined order: [Const, Type, Fn])
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:5
|
LL | const A: bool;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
|
note: should be placed before `SomeType`
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:153:5
|
LL | type SomeType;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
error: incorrect ordering of items (must be alphabetically ordered)
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:11
@ -172,13 +172,13 @@ error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:189:5
|
LL | const A: bool = false;
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
|
note: should be placed before `SomeType`
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:187:5
|
LL | type SomeType = ();
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
error: aborting due to 15 previous errors

View file

@ -211,13 +211,13 @@ error: incorrect ordering of trait items (defined order: [Const, Type, Fn])
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:5
|
LL | const A: bool;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
|
note: should be placed before `SomeType`
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:153:5
|
LL | type SomeType;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
error: incorrect ordering of items (must be alphabetically ordered)
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:11
@ -247,13 +247,13 @@ error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:189:5
|
LL | const A: bool = false;
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
|
note: should be placed before `SomeType`
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:187:5
|
LL | type SomeType = ();
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
error: incorrect ordering of items (must be alphabetically ordered)
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:207:11

View file

@ -28,25 +28,25 @@ error: incorrect ordering of impl items (defined order: [Fn, Type, Const])
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:119:5
|
LL | type SomeType = ();
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
|
note: should be placed before `A`
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:117:5
|
LL | const A: bool = false;
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
error: incorrect ordering of impl items (defined order: [Fn, Type, Const])
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:122:5
|
LL | fn a() {}
| ^^^^^^^^^
| ^^^^^^
|
note: should be placed before `SomeType`
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:119:5
|
LL | type SomeType = ();
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
error: incorrect ordering of items (must be alphabetically ordered)
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:149:8
@ -76,13 +76,13 @@ error: incorrect ordering of trait items (defined order: [Fn, Type, Const])
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:163:5
|
LL | type SomeType;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
|
note: should be placed before `A`
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:161:5
|
LL | const A: bool;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
error: incorrect ordering of trait items (defined order: [Fn, Type, Const])
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:166:5
@ -94,7 +94,7 @@ note: should be placed before `SomeType`
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:163:5
|
LL | type SomeType;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
error: aborting due to 8 previous errors

View file

@ -16,25 +16,25 @@ error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:46:5
|
LL | type SomeType = i8;
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
|
note: should be placed before `a`
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:43:5
|
LL | fn a() {}
| ^^^^^^^^^
| ^^^^^^
error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:49:5
|
LL | const A: bool = true;
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
|
note: should be placed before `SomeType`
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:46:5
|
LL | type SomeType = i8;
| ^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
error: aborting due to 3 previous errors

View file

@ -28,13 +28,13 @@ error: incorrect ordering of trait items (defined order: [Const, Type, Fn])
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:45:5
|
LL | const A: bool;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
|
note: should be placed before `SomeType`
--> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:43:5
|
LL | type SomeType;
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
error: aborting due to 3 previous errors

View file

@ -1,12 +1,8 @@
error: re-implementing `PartialEq::ne` is unnecessary
--> tests/ui/partialeq_ne_impl.rs:9:5
|
LL | / fn ne(&self, _: &Foo) -> bool {
LL | |
LL | |
LL | | false
LL | | }
| |_____^
LL | fn ne(&self, _: &Foo) -> bool {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::partialeq-ne-impl` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::partialeq_ne_impl)]`

View file

@ -2,13 +2,13 @@ error: method's name is the same as an existing method in a trait
--> tests/ui/same_name_method.rs:20:13
|
LL | fn foo() {}
| ^^^^^^^^^^^
| ^^^^^^^^
|
note: existing `foo` defined here
--> tests/ui/same_name_method.rs:25:13
|
LL | fn foo() {}
| ^^^^^^^^^^^
| ^^^^^^^^
= note: `-D clippy::same-name-method` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::same_name_method)]`
@ -16,7 +16,7 @@ error: method's name is the same as an existing method in a trait
--> tests/ui/same_name_method.rs:35:13
|
LL | fn clone() {}
| ^^^^^^^^^^^^^
| ^^^^^^^^^^
|
note: existing `clone` defined here
--> tests/ui/same_name_method.rs:31:18
@ -28,19 +28,19 @@ error: method's name is the same as an existing method in a trait
--> tests/ui/same_name_method.rs:46:13
|
LL | fn foo() {}
| ^^^^^^^^^^^
| ^^^^^^^^
|
note: existing `foo` defined here
--> tests/ui/same_name_method.rs:51:13
|
LL | fn foo() {}
| ^^^^^^^^^^^
| ^^^^^^^^
error: method's name is the same as an existing method in a trait
--> tests/ui/same_name_method.rs:61:13
|
LL | fn foo() {}
| ^^^^^^^^^^^
| ^^^^^^^^
|
note: existing `foo` defined here
--> tests/ui/same_name_method.rs:65:9
@ -52,7 +52,7 @@ error: method's name is the same as an existing method in a trait
--> tests/ui/same_name_method.rs:74:13
|
LL | fn foo() {}
| ^^^^^^^^^^^
| ^^^^^^^^
|
note: existing `foo` defined here
--> tests/ui/same_name_method.rs:79:9
@ -64,7 +64,7 @@ error: method's name is the same as an existing method in a trait
--> tests/ui/same_name_method.rs:74:13
|
LL | fn foo() {}
| ^^^^^^^^^^^
| ^^^^^^^^
|
note: existing `foo` defined here
--> tests/ui/same_name_method.rs:81:9

View file

@ -5,10 +5,7 @@ LL | / fn visit_string<E>(self, _v: String) -> Result<Self::Value, E>
LL | |
LL | | where
LL | | E: serde::de::Error,
LL | | {
LL | | unimplemented!()
LL | | }
| |_____^
| |____________________________^
|
= note: `-D clippy::serde-api-misuse` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::serde_api_misuse)]`

View file

@ -150,7 +150,7 @@ impl Foo {
}
#[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes")]
#[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes")]
#[rustc_clean(cfg="cfail6")]

View file

@ -141,7 +141,7 @@ pub trait ChangeMethodSelfnessTrait {
}
#[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail2")]
#[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")]
#[rustc_clean(cfg="cfail6")]
@ -179,7 +179,7 @@ pub trait RemoveMethodSelfnessTrait {
}
#[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail2")]
#[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")]
#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")]
#[rustc_clean(cfg="cfail6")]

View file

@ -16,7 +16,7 @@ error[E0790]: cannot refer to the associated constant on trait without specifyin
--> $DIR/issue-58022.rs:4:25
|
LL | const SIZE: usize;
| ------------------ `Foo::SIZE` defined here
| ----------------- `Foo::SIZE` defined here
LL |
LL | fn new(slice: &[u8; Foo::SIZE]) -> Self;
| ^^^^^^^^^ cannot refer to the associated constant of trait

View file

@ -2,7 +2,7 @@ error[E0790]: cannot refer to the associated constant on trait without specifyin
--> $DIR/issue-63496.rs:4:21
|
LL | const C: usize;
| --------------- `A::C` defined here
| -------------- `A::C` defined here
LL |
LL | fn f() -> ([u8; A::C], [u8; A::C]);
| ^^^^ cannot refer to the associated constant of trait
@ -11,7 +11,7 @@ error[E0790]: cannot refer to the associated constant on trait without specifyin
--> $DIR/issue-63496.rs:4:33
|
LL | const C: usize;
| --------------- `A::C` defined here
| -------------- `A::C` defined here
LL |
LL | fn f() -> ([u8; A::C], [u8; A::C]);
| ^^^^ cannot refer to the associated constant of trait

View file

@ -18,7 +18,7 @@ error[E0790]: cannot refer to the associated constant on trait without specifyin
--> $DIR/issue-48027.rs:3:32
|
LL | const X: usize;
| --------------- `Bar::X` defined here
| -------------- `Bar::X` defined here
LL | fn return_n(&self) -> [u8; Bar::X];
| ^^^^^^ cannot refer to the associated constant of trait

View file

@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/defaults-in-other-trait-items.rs:9:13
|
LL | type A = ();
| ------------ associated type defaults can't be assumed inside the trait defining them
| ------ associated type defaults can't be assumed inside the trait defining them
...
LL | let () = p;
| ^^ - this expression has type `<Self as Tr>::A`
@ -16,7 +16,7 @@ error[E0308]: mismatched types
--> $DIR/defaults-in-other-trait-items.rs:36:25
|
LL | type Ty = u8;
| ------------- associated type defaults can't be assumed inside the trait defining them
| ------- associated type defaults can't be assumed inside the trait defining them
...
LL | const C: Self::Ty = 0u8;
| ^^^ expected associated type, found `u8`
@ -28,7 +28,7 @@ error[E0308]: mismatched types
--> $DIR/defaults-in-other-trait-items.rs:54:9
|
LL | type Res = isize;
| ----------------- associated type defaults can't be assumed inside the trait defining them
| -------- associated type defaults can't be assumed inside the trait defining them
LL |
LL | fn infer_me_correctly() -> Self::Res {
| --------- expected `<Self as Trait>::Res` because of return type

View file

@ -31,7 +31,7 @@ error[E0053]: method `make` has an incompatible type for trait
--> $DIR/defaults-specialization.rs:35:18
|
LL | default type Ty = bool;
| ----------------------- associated type is `default` and may be overridden
| --------------- associated type is `default` and may be overridden
LL |
LL | fn make() -> bool { true }
| ^^^^ expected associated type, found `bool`
@ -53,7 +53,7 @@ error[E0308]: mismatched types
--> $DIR/defaults-specialization.rs:10:9
|
LL | type Ty = u8;
| ------------- associated type defaults can't be assumed inside the trait defining them
| ------- associated type defaults can't be assumed inside the trait defining them
LL |
LL | fn make() -> Self::Ty {
| -------- expected `<Self as Tr>::Ty` because of return type
@ -80,7 +80,7 @@ error[E0308]: mismatched types
--> $DIR/defaults-specialization.rs:44:29
|
LL | default type Ty = bool;
| ----------------------- associated type is `default` and may be overridden
| --------------- associated type is `default` and may be overridden
LL |
LL | fn make() -> Self::Ty { true }
| -------- ^^^^ expected associated type, found `bool`

View file

@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/issue-26681.rs:17:39
|
LL | type Fv: Foo = u8;
| ------------------ associated type defaults can't be assumed inside the trait defining them
| ------------ associated type defaults can't be assumed inside the trait defining them
LL | const C: <Self::Fv as Foo>::Bar = 6665;
| ^^^^ expected associated type, found integer
|

View file

@ -10,14 +10,11 @@ LL | const fn const_val<T: Sized>() -> usize {
error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
--> $DIR/issue-54954.rs:1:24
|
LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
...
LL | / const fn const_val<T: Sized>() -> usize {
LL | |
LL | | core::mem::size_of::<T>()
LL | | }
| |_____- `Tt::const_val` defined here
LL | const fn const_val<T: Sized>() -> usize {
| --------------------------------------- `Tt::const_val` defined here
error: aborting due to 2 previous errors

View file

@ -16,7 +16,7 @@ error[E0790]: cannot refer to the associated constant on trait without specifyin
--> $DIR/E0790.rs:21:17
|
LL | const MY_ASSOC_CONST: ();
| ------------------------- `MyTrait::MY_ASSOC_CONST` defined here
| ------------------------ `MyTrait::MY_ASSOC_CONST` defined here
...
LL | let _ = MyTrait::MY_ASSOC_CONST;
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot refer to the associated constant of trait
@ -44,7 +44,7 @@ error[E0790]: cannot refer to the associated constant on trait without specifyin
--> $DIR/E0790.rs:30:13
|
LL | const MY_ASSOC_CONST: ();
| ------------------------- `MyTrait::MY_ASSOC_CONST` defined here
| ------------------------ `MyTrait::MY_ASSOC_CONST` defined here
...
LL | let _ = inner::MyTrait::MY_ASSOC_CONST;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot refer to the associated constant of trait

View file

@ -12,7 +12,7 @@ error[E0658]: use of unstable library feature `async_drop`
--> $DIR/feature-gate-async-drop.rs:13:5
|
LL | async fn drop(self: Pin<&mut Self>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #126482 <https://github.com/rust-lang/rust/issues/126482> for more information
= help: add `#![feature(async_drop)]` to the crate attributes to enable

View file

@ -4,7 +4,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "foo"]
| ---------------------- help: remove this attribute
LL | pub fn foo<T>() {}
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/export-name-on-generics.rs:3:9
@ -18,7 +18,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "bar"]
| ---------------------- help: remove this attribute
LL | pub extern "C" fn bar<T>() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/export-name-on-generics.rs:21:5
@ -26,7 +26,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "foo"]
| ---------------------- help: remove this attribute
LL | pub fn foo<T>() {}
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/export-name-on-generics.rs:24:5
@ -34,7 +34,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "bar"]
| ---------------------- help: remove this attribute
LL | pub extern "C" fn bar<T>() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/export-name-on-generics.rs:42:5
@ -42,7 +42,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "foo"]
| ---------------------- help: remove this attribute
LL | fn foo<T>() {}
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/export-name-on-generics.rs:45:5
@ -50,7 +50,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "bar"]
| ---------------------- help: remove this attribute
LL | extern "C" fn bar<T>() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/export-name-on-generics.rs:64:5
@ -58,7 +58,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "foo"]
| ---------------------- help: remove this attribute
LL | fn foo() {}
| ^^^^^^^^^^^
| ^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/export-name-on-generics.rs:67:5
@ -66,7 +66,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "foo2"]
| ----------------------- help: remove this attribute
LL | fn foo2<U>() {}
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/export-name-on-generics.rs:70:5
@ -74,7 +74,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "baz"]
| ---------------------- help: remove this attribute
LL | extern "C" fn bar() {}
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/export-name-on-generics.rs:73:5
@ -82,7 +82,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "baz"]
| ---------------------- help: remove this attribute
LL | fn baz(x: &i32) -> &i32 { x }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/export-name-on-generics.rs:76:5
@ -90,7 +90,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "qux"]
| ---------------------- help: remove this attribute
LL | fn qux<'a>(x: &'a i32) -> &i32 { x }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/export-name-on-generics.rs:83:5
@ -98,7 +98,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "foo"]
| ---------------------- help: remove this attribute
LL | pub fn foo() {}
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/export-name-on-generics.rs:86:5
@ -106,7 +106,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "bar"]
| ---------------------- help: remove this attribute
LL | pub extern "C" fn bar() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/export-name-on-generics.rs:89:5
@ -114,7 +114,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "baz"]
| ---------------------- help: remove this attribute
LL | pub fn baz<U>() {}
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/export-name-on-generics.rs:105:5
@ -122,7 +122,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "foo"]
| ---------------------- help: remove this attribute
LL | fn foo() {}
| ^^^^^^^^^^^
| ^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/export-name-on-generics.rs:108:5
@ -130,7 +130,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "bar"]
| ---------------------- help: remove this attribute
LL | extern "C" fn bar() {}
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/export-name-on-generics.rs:111:5
@ -138,7 +138,7 @@ error: functions generic over types or consts must be mangled
LL | #[export_name = "baz"]
| ---------------------- help: remove this attribute
LL | fn baz<U>() {}
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^
error: aborting due to 17 previous errors

View file

@ -4,7 +4,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | pub fn foo<T>() {}
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/generic-no-mangle.rs:3:9
@ -18,7 +18,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | pub extern "C" fn bar<T>() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/generic-no-mangle.rs:21:5
@ -26,7 +26,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | pub fn foo<T>() {}
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/generic-no-mangle.rs:24:5
@ -34,7 +34,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | pub extern "C" fn bar<T>() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/generic-no-mangle.rs:42:5
@ -42,7 +42,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | fn foo<T>() {}
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/generic-no-mangle.rs:45:5
@ -50,7 +50,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | extern "C" fn bar<T>() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/generic-no-mangle.rs:64:5
@ -58,7 +58,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | fn foo() {}
| ^^^^^^^^^^^
| ^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/generic-no-mangle.rs:67:5
@ -66,7 +66,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | fn foo2<U>() {}
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/generic-no-mangle.rs:70:5
@ -74,7 +74,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | extern "C" fn bar() {}
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/generic-no-mangle.rs:73:5
@ -82,7 +82,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | fn baz(x: &i32) -> &i32 { x }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/generic-no-mangle.rs:76:5
@ -90,7 +90,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | fn qux<'a>(x: &'a i32) -> &i32 { x }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/generic-no-mangle.rs:83:5
@ -98,7 +98,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | pub fn foo() {}
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/generic-no-mangle.rs:86:5
@ -106,7 +106,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | pub extern "C" fn bar() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/generic-no-mangle.rs:89:5
@ -114,7 +114,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | pub fn baz<U>() {}
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/generic-no-mangle.rs:105:5
@ -122,7 +122,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | fn foo() {}
| ^^^^^^^^^^^
| ^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/generic-no-mangle.rs:108:5
@ -130,7 +130,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | extern "C" fn bar() {}
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^
error: functions generic over types or consts must be mangled
--> $DIR/generic-no-mangle.rs:111:5
@ -138,7 +138,7 @@ error: functions generic over types or consts must be mangled
LL | #[no_mangle]
| ------------ help: remove this attribute
LL | fn baz<U>() {}
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^
error: aborting due to 17 previous errors

View file

@ -290,7 +290,7 @@ error[E0658]: use of unstable library feature `unstable_test_feature`
--> $DIR/lint-stability.rs:179:9
|
LL | fn trait_unstable(&self) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

View file

@ -65,7 +65,7 @@ LL | #[no_mangle]
| ------------ help: remove this attribute
LL |
LL | pub fn defiant<T>(_t: T) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(no_mangle_generic_items)]` on by default
@ -89,7 +89,7 @@ warning: functions generic over types or consts must be mangled
--> $DIR/suggestions.rs:26:18
|
LL | #[no_mangle] pub fn val_jean<T>() {}
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^
| ------------ ^^^^^^^^^^^^^^^^^^^^
| |
| help: remove this attribute
@ -105,7 +105,7 @@ warning: functions generic over types or consts must be mangled
--> $DIR/suggestions.rs:35:18
|
LL | #[no_mangle] pub(crate) fn crossfield<T>() {}
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| help: remove this attribute

View file

@ -12,7 +12,7 @@ error[E0308]: mismatched types
--> $DIR/specialization-default-types.rs:19:9
|
LL | default type Output = Box<T>;
| ----------------------------- associated type is `default` and may be overridden
| ------------------- associated type is `default` and may be overridden
LL | default fn generate(self) -> Self::Output {
| ------------ expected `<T as Example>::Output` because of return type
LL | Box::new(self)

View file

@ -12,7 +12,7 @@ error[E0308]: mismatched types
--> $DIR/specialization-default-types.rs:19:9
|
LL | default type Output = Box<T>;
| ----------------------------- associated type is `default` and may be overridden
| ------------------- associated type is `default` and may be overridden
LL | default fn generate(self) -> Self::Output {
| ------------ expected `<T as Example>::Output` because of return type
LL | Box::new(self)

View file

@ -107,17 +107,17 @@ hir-stats WherePredicate 72 (NN.N%) 3 24
hir-stats - BoundPredicate 72 (NN.N%) 3
hir-stats Local 72 (NN.N%) 1 72
hir-stats InlineAsm 72 (NN.N%) 1 72
hir-stats ImplItemRef 72 (NN.N%) 2 36
hir-stats Body 72 (NN.N%) 3 24
hir-stats Param 64 (NN.N%) 2 32
hir-stats GenericArg 64 (NN.N%) 4 16
hir-stats - Type 16 (NN.N%) 1
hir-stats - Lifetime 48 (NN.N%) 3
hir-stats TraitItemRef 56 (NN.N%) 2 28
hir-stats ExprField 40 (NN.N%) 1 40
hir-stats Mod 32 (NN.N%) 1 32
hir-stats Lifetime 28 (NN.N%) 1 28
hir-stats ForeignItemRef 24 (NN.N%) 1 24
hir-stats TraitItemId 8 (NN.N%) 2 4
hir-stats ImplItemId 8 (NN.N%) 2 4
hir-stats ForeignItemId 4 (NN.N%) 1 4
hir-stats ----------------------------------------------------------------
hir-stats Total 8_716 173
hir-stats Total 8_584 173
hir-stats ================================================================

View file

@ -2,7 +2,7 @@ error[E0790]: cannot call associated function on trait without specifying the co
--> $DIR/issue-104327.rs:10:5
|
LL | fn f() {}
| --------- `Foo::f` defined here
| ------ `Foo::f` defined here
...
LL | Foo::f();
| ^^^^^^^^ cannot call associated function of trait

View file

@ -50,7 +50,7 @@ error: not a function
--> $DIR/rustc_must_implement_one_of_misuse.rs:26:5
|
LL | const A: u8 = 1;
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^
|
note: required by this annotation
--> $DIR/rustc_must_implement_one_of_misuse.rs:24:1
@ -63,7 +63,7 @@ error: not a function
--> $DIR/rustc_must_implement_one_of_misuse.rs:28:5
|
LL | type B;
| ^^^^^^^
| ^^^^^^
|
note: required by this annotation
--> $DIR/rustc_must_implement_one_of_misuse.rs:24:1

View file

@ -5,7 +5,7 @@ LL | impl<'a> Deref for dyn Foo + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo` implements `Deref<Target = dyn Bar<u32>>` which conflicts with supertrait `Bar<i32>`
LL |
LL | type Target = dyn Bar<u32> + 'a;
| -------------------------------- target type is a supertrait of `dyn Foo`
| ----------- target type is a supertrait of `dyn Foo`
|
note: the lint level is defined here
--> $DIR/deref-upcast-shadowing-lint.rs:2:9

View file

@ -5,7 +5,7 @@ LL | impl<'a> Deref for dyn Foo<'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo<'_>` implements `Deref<Target = dyn Bar<'_>>` which conflicts with supertrait `Bar<'_>`
LL |
LL | type Target = dyn Bar<'a>;
| -------------------------- target type is a supertrait of `dyn Foo<'_>`
| ----------- target type is a supertrait of `dyn Foo<'_>`
|
note: the lint level is defined here
--> $DIR/migrate-lint-deny-regions.rs:2:9

View file

@ -5,7 +5,7 @@ LL | impl<'a> Deref for dyn Foo + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Foo` implements `Deref<Target = dyn Bar<u32>>` which conflicts with supertrait `Bar<i32>`
LL |
LL | type Target = dyn Bar<u32> + 'a;
| -------------------------------- target type is a supertrait of `dyn Foo`
| ----------- target type is a supertrait of `dyn Foo`
|
note: the lint level is defined here
--> $DIR/migrate-lint-different-substs.rs:2:9