Remove hir::AssocItemKind.

This commit is contained in:
Camille GILLOT
2025-07-13 13:42:02 +00:00
parent 3ecd03bdfd
commit 277b0ecf34
32 changed files with 293 additions and 455 deletions

View File

@@ -62,21 +62,6 @@ pub(crate) struct DelegationResults<'hir> {
} }
impl<'hir> LoweringContext<'_, '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 { fn is_method(&self, def_id: DefId, span: Span) -> bool {
match self.tcx.def_kind(def_id) { match self.tcx.def_kind(def_id) {
DefKind::Fn => false, DefKind::Fn => false,

View File

@@ -384,7 +384,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
fn visit_trait_item_ref(&mut self, ii: &'hir TraitItemRef) { fn visit_trait_item_ref(&mut self, ii: &'hir TraitItemRef) {
// Do not visit the duplicate information in TraitItemRef. We want to // Do not visit the duplicate information in TraitItemRef. We want to
// map the actual nodes, not the duplicate ones in the *Ref. // map the actual nodes, not the duplicate ones in the *Ref.
let TraitItemRef { id, ident: _, kind: _, span: _ } = *ii; let TraitItemRef { id, ident: _, span: _ } = *ii;
self.visit_nested_trait_item(id); self.visit_nested_trait_item(id);
} }
@@ -392,7 +392,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
fn visit_impl_item_ref(&mut self, ii: &'hir ImplItemRef) { fn visit_impl_item_ref(&mut self, ii: &'hir ImplItemRef) {
// Do not visit the duplicate information in ImplItemRef. We want to // Do not visit the duplicate information in ImplItemRef. We want to
// map the actual nodes, not the duplicate ones in the *Ref. // map the actual nodes, not the duplicate ones in the *Ref.
let ImplItemRef { id, ident: _, kind: _, span: _ } = *ii; let ImplItemRef { id, ident: _, span: _ } = *ii;
self.visit_nested_impl_item(id); self.visit_nested_impl_item(id);
} }

View File

@@ -393,11 +393,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
(trait_ref, lowered_ty) (trait_ref, lowered_ty)
}); });
let new_impl_items = self.arena.alloc_from_iter( let new_impl_items = self
impl_items .arena
.iter() .alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item)));
.map(|item| self.lower_impl_item_ref(item, trait_ref.is_some())),
);
// `defaultness.has_value()` is never called for an `impl`, always `true` in order // `defaultness.has_value()` is never called for an `impl`, always `true` in order
// to not cause an assertion failure inside the `lower_defaultness` function. // to not cause an assertion failure inside the `lower_defaultness` function.
@@ -973,30 +971,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef { 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) }; let id = hir::TraitItemId { owner_id: self.owner_id(i.id) };
hir::TraitItemRef { hir::TraitItemRef {
id, id,
ident: self.lower_ident(ident), ident: self.lower_ident(i.kind.ident().unwrap()),
span: self.lower_span(i.span), span: self.lower_span(i.span),
kind,
} }
} }
@@ -1137,31 +1116,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.arena.alloc(item) self.arena.alloc(item)
} }
fn lower_impl_item_ref(&mut self, i: &AssocItem, is_in_trait_impl: bool) -> hir::ImplItemRef { fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
hir::ImplItemRef { hir::ImplItemRef {
id: hir::ImplItemId { owner_id: self.owner_id(i.id) }, id: hir::ImplItemId { owner_id: self.owner_id(i.id) },
// `unwrap` is safe because `AssocItemKind::{MacCall,DelegationMac}` are the only // `unwrap` is safe because `AssocItemKind::{MacCall,DelegationMac}` are the only
// assoc item kinds without an identifier and they cannot reach here. // assoc item kinds without an identifier and they cannot reach here.
ident: self.lower_ident(i.kind.ident().unwrap()), ident: self.lower_ident(i.kind.ident().unwrap()),
span: self.lower_span(i.span), 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")
}
},
} }
} }

View File

@@ -681,33 +681,20 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
return (false, false, None); return (false, false, None);
} }
let my_def = self.body.source.def_id(); 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) = let Some(td) =
self.infcx.tcx.impl_of_method(my_def).and_then(|x| self.infcx.tcx.trait_id_of_impl(x)) self.infcx.tcx.impl_of_method(my_def).and_then(|x| self.infcx.tcx.trait_id_of_impl(x))
else { else {
return (false, false, None); return (false, false, None);
}; };
let implemented_trait_item = self.infcx.tcx.associated_item(my_def).trait_item_def_id;
( (
true, true,
td.is_local(), td.is_local(),
td.as_local().and_then(|tld| match self.infcx.tcx.hir_node_by_def_id(tld) { implemented_trait_item.and_then(|f_in_trait| {
Node::Item(hir::Item { let f_in_trait = f_in_trait.as_local()?;
kind: hir::ItemKind::Trait(_, _, _, _, _, items), .. if let Node::TraitItem(ti) = self.infcx.tcx.hir_node_by_def_id(f_in_trait)
}) => {
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 hir::TraitItemKind::Fn(sig, _) = ti.kind
&& let Some(ty) = sig.decl.inputs.get(local.index() - 1) && let Some(ty) = sig.decl.inputs.get(local.index() - 1)
&& let hir::TyKind::Ref(_, mut_ty) = ty.kind && let hir::TyKind::Ref(_, mut_ty) = ty.kind
@@ -718,9 +705,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
} else { } else {
None None
} }
})
}
_ => None,
}), }),
) )
} }

View File

@@ -4415,7 +4415,6 @@ impl ItemKind<'_> {
pub struct TraitItemRef { pub struct TraitItemRef {
pub id: TraitItemId, pub id: TraitItemId,
pub ident: Ident, pub ident: Ident,
pub kind: AssocItemKind,
pub span: Span, pub span: Span,
} }
@@ -4429,17 +4428,9 @@ pub struct TraitItemRef {
pub struct ImplItemRef { pub struct ImplItemRef {
pub id: ImplItemId, pub id: ImplItemId,
pub ident: Ident, pub ident: Ident,
pub kind: AssocItemKind,
pub span: Span, pub span: Span,
} }
#[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 // 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 // hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later. // so it can fetched later.

View File

@@ -499,9 +499,6 @@ pub trait Visitor<'v>: Sized {
fn visit_attribute(&mut self, _attr: &'v Attribute) -> Self::Result { fn visit_attribute(&mut self, _attr: &'v Attribute) -> Self::Result {
Self::Result::output() 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 { fn visit_defaultness(&mut self, defaultness: &'v Defaultness) -> Self::Result {
walk_defaultness(self, defaultness) walk_defaultness(self, defaultness)
} }
@@ -1252,10 +1249,9 @@ pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(
visitor: &mut V, visitor: &mut V,
trait_item_ref: &'v TraitItemRef, trait_item_ref: &'v TraitItemRef,
) -> V::Result { ) -> V::Result {
let TraitItemRef { id, ident, ref kind, span: _ } = *trait_item_ref; let TraitItemRef { id, ident, span: _ } = *trait_item_ref;
try_visit!(visitor.visit_nested_trait_item(id)); try_visit!(visitor.visit_nested_trait_item(id));
try_visit!(visitor.visit_ident(ident)); visitor.visit_ident(ident)
visitor.visit_associated_item_kind(kind)
} }
pub fn walk_impl_item<'v, V: Visitor<'v>>( pub fn walk_impl_item<'v, V: Visitor<'v>>(
@@ -1307,10 +1303,9 @@ pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(
visitor: &mut V, visitor: &mut V,
impl_item_ref: &'v ImplItemRef, impl_item_ref: &'v ImplItemRef,
) -> V::Result { ) -> V::Result {
let ImplItemRef { id, ident, ref kind, span: _ } = *impl_item_ref; let ImplItemRef { id, ident, span: _ } = *impl_item_ref;
try_visit!(visitor.visit_nested_impl_item(id)); try_visit!(visitor.visit_nested_impl_item(id));
try_visit!(visitor.visit_ident(ident)); visitor.visit_ident(ident)
visitor.visit_associated_item_kind(kind)
} }
pub fn walk_trait_ref<'v, V: Visitor<'v>>( pub fn walk_trait_ref<'v, V: Visitor<'v>>(
@@ -1484,13 +1479,6 @@ pub fn walk_assoc_item_constraint<'v, V: Visitor<'v>>(
V::Result::output() 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 { 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 // 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, // the right thing to do, should content be added in the future,

View File

@@ -914,7 +914,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
let item = items.iter().find(|item| item.ident == *ident); let item = items.iter().find(|item| item.ident == *ident);
match item { match item {
Some(item) if matches!(item.kind, hir::AssocItemKind::Fn { .. }) => { Some(item) if matches!(tcx.def_kind(item.id.owner_id), DefKind::AssocFn) => {
if !tcx.defaultness(item.id.owner_id).has_value() { if !tcx.defaultness(item.id.owner_id).has_value() {
tcx.dcx().emit_err(errors::FunctionNotHaveDefaultImplementation { tcx.dcx().emit_err(errors::FunctionNotHaveDefaultImplementation {
span: item.span, span: item.span,

View File

@@ -28,7 +28,7 @@ use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
use rustc_hir::intravisit::FnKind as HirFnKind; 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::bug;
use rustc_middle::lint::LevelAndSource; use rustc_middle::lint::LevelAndSource;
use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::layout::LayoutOf;
@@ -952,36 +952,34 @@ declare_lint! {
declare_lint_pass!(InvalidNoMangleItems => [NO_MANGLE_CONST_ITEMS, NO_MANGLE_GENERIC_ITEMS]); 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 { impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
let attrs = cx.tcx.hir_attrs(it.hir_id()); let attrs = cx.tcx.hir_attrs(it.hir_id());
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 { match it.kind {
hir::ItemKind::Fn { generics, .. } => { hir::ItemKind::Fn { .. } => {
if let Some(attr_span) = if let Some(attr_span) =
find_attr!(attrs, AttributeKind::ExportName {span, ..} => *span) find_attr!(attrs, AttributeKind::ExportName {span, ..} => *span)
.or_else(|| find_attr!(attrs, AttributeKind::NoMangle(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(..) => { 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());
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) = if let Some(attr_span) =
find_attr!(attrs, AttributeKind::ExportName {span, ..} => *span) find_attr!(attrs, AttributeKind::ExportName {span, ..} => *span)
.or_else( .or_else(|| find_attr!(attrs, AttributeKind::NoMangle(span) => *span))
|| find_attr!(attrs, AttributeKind::NoMangle(span) => *span),
)
{ {
check_no_mangle_on_generic_fn( self.check_no_mangle_on_generic_fn(cx, attr_span, it.owner_id.def_id);
attr_span,
Some(generics),
cx.tcx.hir_get_generics(it.id.owner_id.def_id).unwrap(),
it.span,
);
}
}
} }
} }
_ => {} _ => {}

View File

@@ -257,6 +257,16 @@ impl AssocItems {
self.items.get_by_key(Some(name)) 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. /// Returns the associated item with the given identifier and `AssocKind`, if one exists.
/// The identifier is matched hygienically. /// The identifier is matched hygienically.
pub fn find_by_ident_and_kind( pub fn find_by_ident_and_kind(

View File

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

View File

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

View File

@@ -26,7 +26,7 @@ use rustc_errors::{MultiSpan, listify};
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId, LocalModDefId}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId, LocalModDefId};
use rustc_hir::intravisit::{self, InferKind, Visitor}; 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::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::print::PrintTraitRefExt as _;
@@ -678,7 +678,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
let mut reach = self.reach(trait_item_ref.id.owner_id.def_id, item_ev); let mut reach = self.reach(trait_item_ref.id.owner_id.def_id, item_ev);
reach.generics().predicates(); reach.generics().predicates();
if trait_item_ref.kind == AssocItemKind::Type if let DefKind::AssocTy = tcx.def_kind(trait_item_ref.id.owner_id)
&& !tcx.defaultness(trait_item_ref.id.owner_id).has_value() && !tcx.defaultness(trait_item_ref.id.owner_id).has_value()
{ {
// No type to visit. // No type to visit.
@@ -1576,16 +1576,15 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
fn check_assoc_item( fn check_assoc_item(
&self, &self,
def_id: LocalDefId, item: &ty::AssocItem,
assoc_item_kind: AssocItemKind,
vis: ty::Visibility, vis: ty::Visibility,
effective_vis: Option<EffectiveVisibility>, 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 { let (check_ty, is_assoc_ty) = match item.kind {
AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false), ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => (true, false),
AssocItemKind::Type => (self.tcx.defaultness(def_id).has_value(), true), ty::AssocKind::Type { .. } => (item.defaultness(self.tcx).has_value(), true),
}; };
check.in_assoc_ty = is_assoc_ty; check.in_assoc_ty = is_assoc_ty;
@@ -1619,25 +1618,16 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
self.check(def_id, item_visibility, effective_vis).generics().bounds(); self.check(def_id, item_visibility, effective_vis).generics().bounds();
} }
DefKind::Trait => { DefKind::Trait => {
let item = tcx.hir_item(id); self.check_unnameable(def_id, effective_vis);
if let hir::ItemKind::Trait(.., trait_item_refs) = item.kind {
self.check_unnameable(item.owner_id.def_id, effective_vis);
self.check(item.owner_id.def_id, item_visibility, effective_vis) self.check(def_id, item_visibility, effective_vis).generics().predicates();
.generics()
.predicates();
for trait_item_ref in trait_item_refs { for assoc_item in tcx.associated_items(id.owner_id).in_definition_order() {
self.check_assoc_item( self.check_assoc_item(assoc_item, item_visibility, effective_vis);
trait_item_ref.id.owner_id.def_id,
trait_item_ref.kind,
item_visibility,
effective_vis,
);
if let AssocItemKind::Type = trait_item_ref.kind { if assoc_item.is_type() {
self.check( self.check(
trait_item_ref.id.owner_id.def_id, assoc_item.def_id.expect_local(),
item_visibility, item_visibility,
effective_vis, effective_vis,
) )
@@ -1645,7 +1635,6 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
} }
} }
} }
}
DefKind::TraitAlias => { DefKind::TraitAlias => {
self.check(def_id, item_visibility, effective_vis).generics().predicates(); self.check(def_id, item_visibility, effective_vis).generics().predicates();
} }
@@ -1714,14 +1703,8 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
// Subitems of inherent impls have their own publicity. // Subitems of inherent impls have their own publicity.
// A trait impl is public when both its type and its trait are public // A trait impl is public when both its type and its trait are public
// Subitems of trait impls have inherited publicity. // Subitems of trait impls have inherited publicity.
DefKind::Impl { .. } => { DefKind::Impl { of_trait } => {
let item = tcx.hir_item(id); let impl_vis = ty::Visibility::of_impl::<false>(def_id, tcx, &Default::default());
if let hir::ItemKind::Impl(impl_) = item.kind {
let impl_vis = ty::Visibility::of_impl::<false>(
item.owner_id.def_id,
tcx,
&Default::default(),
);
// We are using the non-shallow version here, unlike when building the // We are using the non-shallow version here, unlike when building the
// effective visisibilities table to avoid large number of false positives. // effective visisibilities table to avoid large number of false positives.
@@ -1734,49 +1717,38 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
// lints shouldn't be emitted even if `from` effective visibility // lints shouldn't be emitted even if `from` effective visibility
// is larger than `Priv` nominal visibility and if `Priv` can leak // is larger than `Priv` nominal visibility and if `Priv` can leak
// in some scenarios due to type inference. // in some scenarios due to type inference.
let impl_ev = EffectiveVisibility::of_impl::<false>( let impl_ev =
item.owner_id.def_id, EffectiveVisibility::of_impl::<false>(def_id, tcx, self.effective_visibilities);
tcx,
self.effective_visibilities, let mut check = self.check(def_id, impl_vis, Some(impl_ev));
);
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 // Generics and predicates of trait impls are intentionally not checked
// for private components (#90586). // for private components (#90586).
if impl_.of_trait.is_none() { if !of_trait {
check.generics().predicates(); check.generics().predicates();
} }
// Skip checking private components in associated types, due to lack of full // Skip checking private components in associated types, due to lack of full
// normalization they produce very ridiculous false positives. // normalization they produce very ridiculous false positives.
// FIXME: Remove this when full normalization is implemented. // FIXME: Remove this when full normalization is implemented.
check.skip_assoc_tys = true; check.skip_assoc_tys = true;
check.ty().trait_ref(); check.ty().trait_ref();
for impl_item_ref in impl_.items { for assoc_item in tcx.associated_items(id.owner_id).in_definition_order() {
let impl_item_vis = if impl_.of_trait.is_none() { let impl_item_vis = if !of_trait {
min( min(tcx.local_visibility(assoc_item.def_id.expect_local()), impl_vis, tcx)
tcx.local_visibility(impl_item_ref.id.owner_id.def_id),
impl_vis,
tcx,
)
} else { } else {
impl_vis impl_vis
}; };
let impl_item_ev = if impl_.of_trait.is_none() { let impl_item_ev = if !of_trait {
self.get(impl_item_ref.id.owner_id.def_id) self.get(assoc_item.def_id.expect_local())
.map(|ev| ev.min(impl_ev, self.tcx)) .map(|ev| ev.min(impl_ev, self.tcx))
} else { } else {
Some(impl_ev) Some(impl_ev)
}; };
self.check_assoc_item( self.check_assoc_item(assoc_item, impl_item_vis, impl_item_ev);
impl_item_ref.id.owner_id.def_id,
impl_item_ref.kind,
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); let param_env = tcx.param_env(body_owner_def_id);
match item { if let DefKind::Trait | DefKind::Impl { .. } = tcx.def_kind(parent_id) {
hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., items), .. }) => { let assoc_items = tcx.associated_items(parent_id);
// FIXME: account for `#![feature(specialization)]` // FIXME: account for `#![feature(specialization)]`
for item in &items[..] { for assoc_item in assoc_items.in_definition_order() {
match item.kind { if assoc_item.is_type()
hir::AssocItemKind::Type => {
// FIXME: account for returning some type in a trait fn impl that has // FIXME: account for returning some type in a trait fn impl that has
// an assoc type as a return type (#72076). // an assoc type as a return type (#72076).
if let hir::Defaultness::Default { has_value: true } = && let hir::Defaultness::Default { has_value: true } = assoc_item.defaultness(tcx)
tcx.defaultness(item.id.owner_id) && let assoc_ty = tcx.type_of(assoc_item.def_id).instantiate_identity()
{
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;
}
}
}
_ => {}
}
}
}
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) && self.infcx.can_eq(param_env, assoc_ty, found)
{ {
diag.span_label( let msg = match assoc_item.container {
item.span, ty::AssocItemContainer::Trait => {
"associated type is `default` and may be overridden", "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; return true;
} }
} }
} }
}
_ => {}
}
false false
} }

View File

@@ -154,7 +154,7 @@ fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>(
ItemKind::Trait(.., trait_item_refs) => trait_item_refs ItemKind::Trait(.., trait_item_refs) => trait_item_refs
.iter() .iter()
.filter_map(move |item| { .filter_map(move |item| {
if !matches!(item.kind, hir::AssocItemKind::Fn { .. }) { if !matches!(tcx.def_kind(item.id.owner_id), DefKind::AssocFn) {
return None; return None;
} }
let fn_def_id = item.id.owner_id.def_id; let fn_def_id = item.id.owner_id.def_id;
@@ -185,7 +185,7 @@ fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>(
.items .items
.iter() .iter()
.filter_map(|item| { .filter_map(|item| {
if !matches!(item.kind, hir::AssocItemKind::Fn { .. }) { if !matches!(tcx.def_kind(item.id.owner_id), DefKind::AssocFn) {
return None; return None;
} }
let did = item.id.owner_id.def_id.to_def_id(); let did = item.id.owner_id.def_id.to_def_id();

View File

@@ -8,9 +8,10 @@ use clippy_utils::diagnostics::span_lint_and_note;
use clippy_utils::is_cfg_test; use clippy_utils::is_cfg_test;
use rustc_attr_data_structures::AttributeKind; use rustc_attr_data_structures::AttributeKind;
use rustc_hir::{ use rustc_hir::{
AssocItemKind, Attribute, FieldDef, HirId, ImplItemRef, IsAuto, Item, ItemKind, Mod, QPath, TraitItemRef, TyKind, Attribute, FieldDef, HirId, ImplItemRef, IsAuto, Item, ItemKind, Mod, OwnerId, QPath, TraitItemRef, TyKind,
Variant, VariantData, Variant, VariantData,
}; };
use rustc_middle::ty::AssocKind;
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::impl_lint_pass; use rustc_session::impl_lint_pass;
@@ -315,9 +316,9 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
} }
if let Some(cur_t) = cur_t { if let Some(cur_t) = cur_t {
let cur_t_kind = convert_assoc_item_kind(cur_t.kind); let cur_t_kind = convert_assoc_item_kind(cx, cur_t.id.owner_id);
let cur_t_kind_index = self.assoc_types_order.index_of(&cur_t_kind); 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.id.owner_id);
let item_kind_index = self.assoc_types_order.index_of(&item_kind); 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() { if cur_t_kind == item_kind && cur_t.ident.name.as_str() > item.ident.name.as_str() {
@@ -338,9 +339,9 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
} }
if let Some(cur_t) = cur_t { if let Some(cur_t) = cur_t {
let cur_t_kind = convert_assoc_item_kind(cur_t.kind); let cur_t_kind = convert_assoc_item_kind(cx, cur_t.id.owner_id);
let cur_t_kind_index = self.assoc_types_order.index_of(&cur_t_kind); 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.id.owner_id);
let item_kind_index = self.assoc_types_order.index_of(&item_kind); 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() { if cur_t_kind == item_kind && cur_t.ident.name.as_str() > item.ident.name.as_str() {
@@ -458,18 +459,19 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
} }
} }
/// Converts a [`rustc_hir::AssocItemKind`] to a /// Converts a [`ty::AssocKind`] to a [`SourceItemOrderingTraitAssocItemKind`].
/// [`SourceItemOrderingTraitAssocItemKind`].
/// ///
/// This is implemented here because `rustc_hir` is not a dependency of /// This is implemented here because `rustc_hir` is not a dependency of
/// `clippy_config`. /// `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. #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.
use SourceItemOrderingTraitAssocItemKind::*; use SourceItemOrderingTraitAssocItemKind::*;
match value { match kind {
AssocItemKind::Const => Const, AssocKind::Const{..} => Const,
AssocItemKind::Type => Type, AssocKind::Type {..}=> Type,
AssocItemKind::Fn { .. } => Fn, AssocKind::Fn { .. } => Fn,
} }
} }

View File

@@ -1,7 +1,8 @@
use clippy_config::Conf; use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_hir; use clippy_utils::diagnostics::span_lint_hir;
use rustc_abi::ExternAbi; 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_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::mir::FakeReadCause; use rustc_middle::mir::FakeReadCause;
@@ -84,23 +85,18 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
.def_id; .def_id;
let mut trait_self_ty = None; 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 the method is an impl for a trait, don't warn.
if let ItemKind::Impl(Impl { of_trait: Some(_), .. }) = item.kind { DefKind::Impl { of_trait: true } => {
return; return
} }
// find `self` ty for this trait if relevant // find `self` ty for this trait if relevant
if let ItemKind::Trait(_, _, _, _, _, items) = item.kind { DefKind::Trait => {
for trait_item in items { trait_self_ty = Some(TraitRef::identity(cx.tcx, parent_id.to_def_id()).self_ty());
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());
}
}
} }
_ => {}
} }
let mut v = EscapeDelegate { let mut v = EscapeDelegate {

View File

@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
use rustc_errors::{Applicability, MultiSpan}; use rustc_errors::{Applicability, MultiSpan};
use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::def_id::{DefId, DefIdSet};
use rustc_hir::hir_id::OwnerId; 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_lint::LateContext;
use rustc_span::Span; use rustc_span::Span;
use rustc_span::symbol::{Ident, kw}; 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 parent_node = cx.tcx.parent_hir_node(item.hir_id())
&& let Node::Item(parent_item) = parent_node && let Node::Item(parent_item) = parent_node
&& let ItemKind::Impl(Impl { && let ItemKind::Impl(Impl {
items,
of_trait: Some(trait_ref), of_trait: Some(trait_ref),
.. ..
}) = &parent_item.kind }) = &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) && !is_from_ignored_trait(trait_ref, ignored_traits)
{ {
let mut param_idents_iter = cx.tcx.hir_body_param_idents(body_id); 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. /// 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> { fn trait_item_def_id_of_impl(cx: &LateContext<'_>, target: OwnerId) -> Option<DefId> {
items.iter().find_map(|item| { cx.tcx.associated_item(target).trait_item_def_id
if item.id.owner_id == target {
item.trait_item_def_id
} else {
None
}
})
} }
fn is_from_ignored_trait(of_trait: &TraitRef<'_>, ignored_traits: &DefIdSet) -> bool { fn is_from_ignored_trait(of_trait: &TraitRef<'_>, ignored_traits: &DefIdSet) -> bool {

View File

@@ -1,8 +1,9 @@
use clippy_utils::diagnostics::span_lint; use clippy_utils::diagnostics::span_lint;
use clippy_utils::sym; use clippy_utils::sym;
use rustc_errors::MultiSpan; use rustc_errors::MultiSpan;
use rustc_hir::{AssocItemKind, Item, ItemKind}; use rustc_hir::{Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::AssocTag;
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
declare_clippy_lint! { declare_clippy_lint! {
@@ -51,17 +52,16 @@ impl<'tcx> LateLintPass<'tcx> for InfallibleTryFrom {
if !cx.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id) { if !cx.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id) {
return; return;
} }
for ii in imp.items { for ii in cx.tcx.associated_items(item.owner_id.def_id)
if ii.kind == AssocItemKind::Type { .filter_by_name_unhygienic_and_kind(sym::Error, AssocTag::Type)
let ii = cx.tcx.hir_impl_item(ii.id); {
if ii.ident.name != sym::Error { let ii_ty = cx.tcx.type_of(ii.def_id).instantiate_identity();
continue; if !ii_ty.is_inhabited_from(cx.tcx, ii.def_id, cx.typing_env()) {
}
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())); 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.push_span_label(ii_ty_span, "infallible error type");
span_lint( span_lint(
cx, cx,
@@ -72,5 +72,4 @@ impl<'tcx> LateLintPass<'tcx> for InfallibleTryFrom {
} }
} }
} }
}
} }

View File

@@ -10,7 +10,7 @@ use rustc_errors::Applicability;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::def_id::{DefId, DefIdSet};
use rustc_hir::{ 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, ImplicitSelfKind, Item, ItemKind, Mutability, Node, OpaqueTyOrigin, PatExprKind, PatKind, PathSegment, PrimTy,
QPath, TraitItemRef, TyKind, QPath, TraitItemRef, TyKind,
}; };
@@ -18,6 +18,7 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, FnSig, Ty}; use rustc_middle::ty::{self, FnSig, Ty};
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
use rustc_span::symbol::kw;
use rustc_span::{Ident, Span, Symbol}; use rustc_span::{Ident, Span, Symbol};
use rustc_trait_selection::traits::supertrait_def_ids; use rustc_trait_selection::traits::supertrait_def_ids;
@@ -267,19 +268,10 @@ 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 check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Ident, trait_items: &[TraitItemRef]) {
fn is_named_self(cx: &LateContext<'_>, item: &TraitItemRef, name: Symbol) -> bool { fn is_named_self(cx: &LateContext<'_>, item: &TraitItemRef, name: Symbol) -> bool {
item.ident.name == name item.ident.name == name
&& if let AssocItemKind::Fn { has_self } = item.kind { && matches!(
has_self && { cx.tcx.fn_arg_idents(item.id.owner_id),
cx.tcx [Some(Ident { name: kw::SelfLower, .. })],
.fn_sig(item.id.owner_id) )
.skip_binder()
.inputs()
.skip_binder()
.len()
== 1
}
} else {
false
}
} }
// fill the set with current and super traits // fill the set with current and super traits

View File

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

View File

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

View File

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

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

View File

@@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/defaults-in-other-trait-items.rs:9:13 --> $DIR/defaults-in-other-trait-items.rs:9:13
| |
LL | type A = (); 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; LL | let () = p;
| ^^ - this expression has type `<Self as Tr>::A` | ^^ - 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 --> $DIR/defaults-in-other-trait-items.rs:36:25
| |
LL | type Ty = u8; 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; LL | const C: Self::Ty = 0u8;
| ^^^ expected associated type, found `u8` | ^^^ expected associated type, found `u8`
@@ -28,7 +28,7 @@ error[E0308]: mismatched types
--> $DIR/defaults-in-other-trait-items.rs:54:9 --> $DIR/defaults-in-other-trait-items.rs:54:9
| |
LL | type Res = isize; 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 |
LL | fn infer_me_correctly() -> Self::Res { LL | fn infer_me_correctly() -> Self::Res {
| --------- expected `<Self as Trait>::Res` because of return type | --------- 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 --> $DIR/defaults-specialization.rs:35:18
| |
LL | default type Ty = bool; LL | default type Ty = bool;
| ----------------------- associated type is `default` and may be overridden | --------------- associated type is `default` and may be overridden
LL | LL |
LL | fn make() -> bool { true } LL | fn make() -> bool { true }
| ^^^^ expected associated type, found `bool` | ^^^^ expected associated type, found `bool`
@@ -53,7 +53,7 @@ error[E0308]: mismatched types
--> $DIR/defaults-specialization.rs:10:9 --> $DIR/defaults-specialization.rs:10:9
| |
LL | type Ty = u8; 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 |
LL | fn make() -> Self::Ty { LL | fn make() -> Self::Ty {
| -------- expected `<Self as Tr>::Ty` because of return type | -------- expected `<Self as Tr>::Ty` because of return type
@@ -80,7 +80,7 @@ error[E0308]: mismatched types
--> $DIR/defaults-specialization.rs:44:29 --> $DIR/defaults-specialization.rs:44:29
| |
LL | default type Ty = bool; LL | default type Ty = bool;
| ----------------------- associated type is `default` and may be overridden | --------------- associated type is `default` and may be overridden
LL | LL |
LL | fn make() -> Self::Ty { true } LL | fn make() -> Self::Ty { true }
| -------- ^^^^ expected associated type, found `bool` | -------- ^^^^ expected associated type, found `bool`

View File

@@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/issue-26681.rs:17:39 --> $DIR/issue-26681.rs:17:39
| |
LL | type Fv: Foo = u8; 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; LL | const C: <Self::Fv as Foo>::Bar = 6665;
| ^^^^ expected associated type, found integer | ^^^^ expected associated type, found integer
| |

View File

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

View File

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

View File

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

View File

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

View File

@@ -112,12 +112,12 @@ hir-stats Param 64 (NN.N%) 2 32
hir-stats GenericArg 64 (NN.N%) 4 16 hir-stats GenericArg 64 (NN.N%) 4 16
hir-stats - Type 16 (NN.N%) 1 hir-stats - Type 16 (NN.N%) 1
hir-stats - Lifetime 48 (NN.N%) 3 hir-stats - Lifetime 48 (NN.N%) 3
hir-stats TraitItemRef 56 (NN.N%) 2 28 hir-stats TraitItemRef 48 (NN.N%) 2 24
hir-stats ImplItemRef 56 (NN.N%) 2 28 hir-stats ImplItemRef 48 (NN.N%) 2 24
hir-stats ExprField 40 (NN.N%) 1 40 hir-stats ExprField 40 (NN.N%) 1 40
hir-stats Mod 32 (NN.N%) 1 32 hir-stats Mod 32 (NN.N%) 1 32
hir-stats Lifetime 28 (NN.N%) 1 28 hir-stats Lifetime 28 (NN.N%) 1 28
hir-stats ForeignItemRef 24 (NN.N%) 1 24 hir-stats ForeignItemRef 24 (NN.N%) 1 24
hir-stats ---------------------------------------------------------------- hir-stats ----------------------------------------------------------------
hir-stats Total 8_700 173 hir-stats Total 8_684 173
hir-stats ================================================================ hir-stats ================================================================