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> {
/// 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,

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) {
// 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;
let TraitItemRef { id, ident: _, span: _ } = *ii;
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) {
// 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: _ } = *ii;
let ImplItemRef { id, ident: _, span: _ } = *ii;
self.visit_nested_impl_item(id);
}

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.
@@ -973,30 +971,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
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),
ident: self.lower_ident(i.kind.ident().unwrap()),
span: self.lower_span(i.span),
kind,
}
}
@@ -1137,31 +1116,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
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 {
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")
}
},
}
}

View File

@@ -681,33 +681,20 @@ 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)
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
@@ -718,9 +705,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
} else {
None
}
})
}
_ => None,
}),
)
}

View File

@@ -4415,7 +4415,6 @@ impl ItemKind<'_> {
pub struct TraitItemRef {
pub id: TraitItemId,
pub ident: Ident,
pub kind: AssocItemKind,
pub span: Span,
}
@@ -4429,17 +4428,9 @@ pub struct TraitItemRef {
pub struct ImplItemRef {
pub id: ImplItemId,
pub ident: Ident,
pub kind: AssocItemKind,
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
// hashmap in the `Crate`. Here we just record the hir-id of the item
// 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 {
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)
}
@@ -1252,10 +1249,9 @@ 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;
let TraitItemRef { id, ident, span: _ } = *trait_item_ref;
try_visit!(visitor.visit_nested_trait_item(id));
try_visit!(visitor.visit_ident(ident));
visitor.visit_associated_item_kind(kind)
visitor.visit_ident(ident)
}
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,
impl_item_ref: &'v ImplItemRef,
) -> 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_ident(ident));
visitor.visit_associated_item_kind(kind)
visitor.visit_ident(ident)
}
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()
}
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

@@ -914,7 +914,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
let item = items.iter().find(|item| item.ident == *ident);
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() {
tcx.dcx().emit_err(errors::FunctionNotHaveDefaultImplementation {
span: item.span,

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());
_ => {}
}
}
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),
)
.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,
);
}
}
self.check_no_mangle_on_generic_fn(cx, attr_span, it.owner_id.def_id);
}
}
_ => {}

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

@@ -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.id.owner_id), DefKind::AssocTy)
}) => {}
ItemKind::TyAlias(_, generics, _) if generics.params.len() != 0 => {}
_ => {
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) => {
// mark assoc ty live if the trait is live
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());
}
}

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 _;
@@ -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);
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()
{
// No type to visit.
@@ -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,25 +1618,16 @@ 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,
item_visibility,
effective_vis,
);
for assoc_item in tcx.associated_items(id.owner_id).in_definition_order() {
self.check_assoc_item(assoc_item, item_visibility, effective_vis);
if let AssocItemKind::Type = trait_item_ref.kind {
if assoc_item.is_type() {
self.check(
trait_item_ref.id.owner_id.def_id,
assoc_item.def_id.expect_local(),
item_visibility,
effective_vis,
)
@@ -1645,7 +1635,6 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
}
}
}
}
DefKind::TraitAlias => {
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.
// 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.
@@ -1734,49 +1717,38 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
// 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,
);
let impl_ev =
EffectiveVisibility::of_impl::<false>(def_id, 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
// for private components (#90586).
if impl_.of_trait.is_none() {
if !of_trait {
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();
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,
)
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 impl_.of_trait.is_none() {
self.get(impl_item_ref.id.owner_id.def_id)
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(
impl_item_ref.id.owner_id.def_id,
impl_item_ref.kind,
impl_item_vis,
impl_item_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), .. }) => {
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 item in &items[..] {
match item.kind {
hir::AssocItemKind::Type => {
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).
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;
}
}
}
_ => {}
}
}
}
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)
&& 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)
{
diag.span_label(
item.span,
"associated type is `default` and may be overridden",
);
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;
}
}
}
}
_ => {}
}
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
.iter()
.filter_map(move |item| {
if !matches!(item.kind, hir::AssocItemKind::Fn { .. }) {
if !matches!(tcx.def_kind(item.id.owner_id), DefKind::AssocFn) {
return None;
}
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
.iter()
.filter_map(|item| {
if !matches!(item.kind, hir::AssocItemKind::Fn { .. }) {
if !matches!(tcx.def_kind(item.id.owner_id), DefKind::AssocFn) {
return None;
}
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 rustc_attr_data_structures::AttributeKind;
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,
};
use rustc_middle::ty::AssocKind;
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::impl_lint_pass;
@@ -315,9 +316,9 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
}
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 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);
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 {
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 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);
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
/// [`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

@@ -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

@@ -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

@@ -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,17 +52,16 @@ 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()) {
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,
@@ -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_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,
};
@@ -18,6 +18,7 @@ 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;
@@ -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 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
}
&& matches!(
cx.tcx.fn_arg_idents(item.id.owner_id),
[Some(Ident { name: kw::SelfLower, .. })],
)
}
// 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())
&& 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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -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

@@ -112,12 +112,12 @@ 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 ImplItemRef 56 (NN.N%) 2 28
hir-stats TraitItemRef 48 (NN.N%) 2 24
hir-stats ImplItemRef 48 (NN.N%) 2 24
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 ----------------------------------------------------------------
hir-stats Total 8_700 173
hir-stats Total 8_684 173
hir-stats ================================================================