Remove hir::AssocItemKind.
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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() });
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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`
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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 ================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user