Skip to content

Commit a38f44c

Browse files
committed
extract finding implied bound to separate function
1 parent d1acbf5 commit a38f44c

File tree

1 file changed

+35
-23
lines changed

1 file changed

+35
-23
lines changed

clippy_lints/src/implied_bounds_in_impls.rs

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ fn emit_lint(
6161
implied_bindings: &[rustc_hir::TypeBinding<'_>],
6262
bound: &ImplTraitBound<'_>,
6363
) {
64-
let implied_by = snippet(cx, bound.impl_trait_bound_span, "..");
64+
let implied_by = snippet(cx, bound.span, "..");
6565

6666
span_lint_and_then(
6767
cx,
@@ -101,7 +101,7 @@ fn emit_lint(
101101
([.., arg], [.., binding]) => arg.span().max(binding.span).shrink_to_hi(),
102102
([.., arg], []) => arg.span().shrink_to_hi(),
103103
([], [.., binding]) => binding.span.shrink_to_hi(),
104-
([], []) => bound.impl_trait_bound_span.shrink_to_hi(),
104+
([], []) => bound.span.shrink_to_hi(),
105105
};
106106

107107
let mut associated_tys_sugg = if needs_angle_brackets {
@@ -223,8 +223,9 @@ fn is_same_generics<'tcx>(
223223

224224
struct ImplTraitBound<'tcx> {
225225
/// The span of the bound in the `impl Trait` type
226-
impl_trait_bound_span: Span,
227-
/// The predicates defined in the trait referenced by this bound
226+
span: Span,
227+
/// The predicates defined in the trait referenced by this bound. This also contains the actual
228+
/// supertrait bounds
228229
predicates: &'tcx [(ty::Clause<'tcx>, Span)],
229230
/// The `DefId` of the trait being referenced by this bound
230231
trait_def_id: DefId,
@@ -257,7 +258,7 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, opaque_ty: &OpaqueTy<
257258
args: path.args.map_or([].as_slice(), |p| p.args),
258259
bindings: path.args.map_or([].as_slice(), |p| p.bindings),
259260
trait_def_id,
260-
impl_trait_bound_span: bound.span(),
261+
span: bound.span(),
261262
})
262263
} else {
263264
None
@@ -266,6 +267,34 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, opaque_ty: &OpaqueTy<
266267
.collect()
267268
}
268269

270+
/// Given a bound in an `impl Trait` type, looks for a trait in the set of supertraits (previously
271+
/// collected in [`collect_supertrait_bounds`]) that matches (same trait and generic arguments).
272+
fn find_bound_in_supertraits<'a, 'tcx>(
273+
cx: &LateContext<'tcx>,
274+
trait_def_id: DefId,
275+
args: &'tcx [GenericArg<'tcx>],
276+
bounds: &'a [ImplTraitBound<'tcx>],
277+
) -> Option<&'a ImplTraitBound<'tcx>> {
278+
bounds.iter().find(|bound| {
279+
bound.predicates.iter().any(|(clause, _)| {
280+
if let ClauseKind::Trait(tr) = clause.kind().skip_binder()
281+
&& tr.def_id() == trait_def_id
282+
{
283+
is_same_generics(
284+
cx.tcx,
285+
tr.trait_ref.args,
286+
bound.args,
287+
args,
288+
bound.trait_def_id,
289+
trait_def_id,
290+
)
291+
} else {
292+
false
293+
}
294+
})
295+
})
296+
}
297+
269298
fn check(cx: &LateContext<'_>, decl: &FnDecl<'_>) {
270299
if let FnRetTy::Return(ty) = decl.output
271300
&& let TyKind::OpaqueDef(item_id, ..) = ty.kind
@@ -287,24 +316,7 @@ fn check(cx: &LateContext<'_>, decl: &FnDecl<'_>) {
287316
&& let implied_args = path.args.map_or([].as_slice(), |a| a.args)
288317
&& let implied_bindings = path.args.map_or([].as_slice(), |a| a.bindings)
289318
&& let Some(def_id) = poly_trait.trait_ref.path.res.opt_def_id()
290-
&& let Some(bound) = supertraits.iter().find(|bound| {
291-
bound.predicates.iter().any(|(clause, _)| {
292-
if let ClauseKind::Trait(tr) = clause.kind().skip_binder()
293-
&& tr.def_id() == def_id
294-
{
295-
is_same_generics(
296-
cx.tcx,
297-
tr.trait_ref.args,
298-
bound.args,
299-
implied_args,
300-
bound.trait_def_id,
301-
def_id,
302-
)
303-
} else {
304-
false
305-
}
306-
})
307-
})
319+
&& let Some(bound) = find_bound_in_supertraits(cx, def_id, implied_args, &supertraits)
308320
{
309321
emit_lint(cx, poly_trait, opaque_ty, index, implied_bindings, bound);
310322
}

0 commit comments

Comments
 (0)