diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index c73ab4bfa68..7bc70836651 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -603,11 +603,7 @@ impl HirEqInterExpr<'_, '_, '_> { } fn eq_assoc_type_binding(&mut self, left: &AssocItemConstraint<'_>, right: &AssocItemConstraint<'_>) -> bool { - left.ident.name == right.ident.name - && self.eq_ty( - left.ty().expect("expected assoc type binding"), - right.ty().expect("expected assoc type binding"), - ) + left.ident.name == right.ident.name && both_some_and(left.ty(), right.ty(), |l, r| self.eq_ty(l, r)) } fn check_ctxt(&mut self, left: SyntaxContext, right: SyntaxContext) -> bool { @@ -727,6 +723,11 @@ pub fn both(l: Option<&X>, r: Option<&X>, mut eq_fn: impl FnMut(&X, &X) -> bo .map_or_else(|| r.is_none(), |x| r.as_ref().is_some_and(|y| eq_fn(x, y))) } +/// Checks if the two `Option`s are both `Some` and pass the predicate function. +pub fn both_some_and(l: Option, r: Option, mut pred: impl FnMut(X, Y) -> bool) -> bool { + l.is_some_and(|l| r.is_some_and(|r| pred(l, r))) +} + /// Checks if two slices are equal as per `eq_fn`. pub fn over(left: &[X], right: &[X], mut eq_fn: impl FnMut(&X, &X) -> bool) -> bool { left.len() == right.len() && left.iter().zip(right).all(|(x, y)| eq_fn(x, y)) diff --git a/tests/ui/trait_duplication_in_bounds.fixed b/tests/ui/trait_duplication_in_bounds.fixed index 779431303ae..e57c79553c3 100644 --- a/tests/ui/trait_duplication_in_bounds.fixed +++ b/tests/ui/trait_duplication_in_bounds.fixed @@ -1,6 +1,6 @@ #![deny(clippy::trait_duplication_in_bounds)] #![allow(unused)] -#![feature(const_trait_impl)] +#![feature(associated_const_equality, const_trait_impl)] use std::any::Any; @@ -179,3 +179,18 @@ fn main() { let _x: fn(_) = f::<()>; let _x: fn(_) = f::; } + +// #13706 +fn assoc_tys_bounds() +where + T: Iterator + Iterator, +{ +} +trait AssocConstTrait { + const ASSOC: usize; +} +fn assoc_const_args() +where + T: AssocConstTrait + AssocConstTrait, +{ +} diff --git a/tests/ui/trait_duplication_in_bounds.rs b/tests/ui/trait_duplication_in_bounds.rs index 3e974dc0a8f..ee84d3c3011 100644 --- a/tests/ui/trait_duplication_in_bounds.rs +++ b/tests/ui/trait_duplication_in_bounds.rs @@ -1,6 +1,6 @@ #![deny(clippy::trait_duplication_in_bounds)] #![allow(unused)] -#![feature(const_trait_impl)] +#![feature(associated_const_equality, const_trait_impl)] use std::any::Any; @@ -179,3 +179,18 @@ fn main() { let _x: fn(_) = f::<()>; let _x: fn(_) = f::; } + +// #13706 +fn assoc_tys_bounds() +where + T: Iterator + Iterator, +{ +} +trait AssocConstTrait { + const ASSOC: usize; +} +fn assoc_const_args() +where + T: AssocConstTrait + AssocConstTrait, +{ +}