Skip to content

Commit 8204494

Browse files
bors[bot]Michael Wright
and
Michael Wright
committed
Merge #3423
3423: Fix `use_self` false positive r=flip1995 a=mikerite This fixes the first error reported in issue #3410. Co-authored-by: Michael Wright <[email protected]>
2 parents 3bb8877 + 460c2b3 commit 8204494

File tree

2 files changed

+38
-15
lines changed

2 files changed

+38
-15
lines changed

clippy_lints/src/use_self.rs

+24-15
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ fn span_use_self_lint(cx: &LateContext<'_, '_>, path: &Path) {
7373
}
7474

7575
struct TraitImplTyVisitor<'a, 'tcx: 'a> {
76-
item_path: &'a Path,
76+
item_type: ty::Ty<'tcx>,
7777
cx: &'a LateContext<'a, 'tcx>,
7878
trait_type_walker: ty::walk::TypeWalker<'tcx>,
7979
impl_type_walker: ty::walk::TypeWalker<'tcx>,
@@ -85,21 +85,28 @@ impl<'a, 'tcx> Visitor<'tcx> for TraitImplTyVisitor<'a, 'tcx> {
8585
let impl_ty = self.impl_type_walker.next();
8686

8787
if let TyKind::Path(QPath::Resolved(_, path)) = &t.node {
88-
if self.item_path.def == path.def {
89-
let is_self_ty = if let def::Def::SelfTy(..) = path.def {
90-
true
91-
} else {
92-
false
93-
};
9488

95-
if !is_self_ty && impl_ty != trait_ty {
96-
// The implementation and trait types don't match which means that
97-
// the concrete type was specified by the implementation but
98-
// it didn't use `Self`
99-
span_use_self_lint(self.cx, path);
89+
// The implementation and trait types don't match which means that
90+
// the concrete type was specified by the implementation
91+
if impl_ty != trait_ty {
92+
93+
if let Some(impl_ty) = impl_ty {
94+
if self.item_type == impl_ty {
95+
let is_self_ty = if let def::Def::SelfTy(..) = path.def {
96+
true
97+
} else {
98+
false
99+
};
100+
101+
if !is_self_ty {
102+
span_use_self_lint(self.cx, path);
103+
}
104+
}
100105
}
106+
101107
}
102108
}
109+
103110
walk_ty(self, t)
104111
}
105112

@@ -110,7 +117,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TraitImplTyVisitor<'a, 'tcx> {
110117

111118
fn check_trait_method_impl_decl<'a, 'tcx: 'a>(
112119
cx: &'a LateContext<'a, 'tcx>,
113-
item_path: &'a Path,
120+
item_type: ty::Ty<'tcx>,
114121
impl_item: &ImplItem,
115122
impl_decl: &'tcx FnDecl,
116123
impl_trait_ref: &ty::TraitRef<'_>,
@@ -151,7 +158,7 @@ fn check_trait_method_impl_decl<'a, 'tcx: 'a>(
151158
) {
152159
let mut visitor = TraitImplTyVisitor {
153160
cx,
154-
item_path,
161+
item_type,
155162
trait_type_walker: trait_ty.walk(),
156163
impl_type_walker: impl_ty.walk(),
157164
};
@@ -192,7 +199,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseSelf {
192199
let impl_item = cx.tcx.hir.impl_item(impl_item_ref.id);
193200
if let ImplItemKind::Method(MethodSig{ decl: impl_decl, .. }, impl_body_id)
194201
= &impl_item.node {
195-
check_trait_method_impl_decl(cx, item_path, impl_item, impl_decl, &impl_trait_ref);
202+
let item_type = cx.tcx.type_of(impl_def_id);
203+
check_trait_method_impl_decl(cx, item_type, impl_item, impl_decl, &impl_trait_ref);
204+
196205
let body = cx.tcx.hir.body(*impl_body_id);
197206
visitor.visit_body(body);
198207
} else {

tests/ui/use_self.rs

+14
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,17 @@ mod existential {
219219
}
220220
}
221221
}
222+
223+
mod issue3410 {
224+
225+
struct A;
226+
struct B;
227+
228+
trait Trait<T>: Sized {
229+
fn a(v: T);
230+
}
231+
232+
impl Trait<Vec<A>> for Vec<B> {
233+
fn a(_: Vec<A>) {}
234+
}
235+
}

0 commit comments

Comments
 (0)