diff options
| author | llogiq <bogusandre@gmail.com> | 2024-11-25 20:24:39 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-25 20:24:39 +0000 |
| commit | 3d881e1e595dae6d5616bfd41da756967f0ae6c3 (patch) | |
| tree | 4061150ceb8998e487e6cd13f78b332c7923758d | |
| parent | d070402440a5a92f427a981784b39eb460e5f292 (diff) | |
| parent | 9fd8e99d91f7029016b9097d1311c1045f35667f (diff) | |
| download | rust-3d881e1e595dae6d5616bfd41da756967f0ae6c3.tar.gz rust-3d881e1e595dae6d5616bfd41da756967f0ae6c3.zip | |
Prevent ICE in case of a bound constraint on generic argument (#13722)
Fix #13706 changelog: [`trait_duplication_in_bounds`]: fix ICE on duplicate type or constant bound
| -rw-r--r-- | clippy_utils/src/hir_utils.rs | 11 | ||||
| -rw-r--r-- | tests/ui/trait_duplication_in_bounds.fixed | 17 | ||||
| -rw-r--r-- | tests/ui/trait_duplication_in_bounds.rs | 17 |
3 files changed, 38 insertions, 7 deletions
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<X>(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<X, Y>(l: Option<X>, r: Option<Y>, 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<X>(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::<i32>; } + +// #13706 +fn assoc_tys_bounds<T>() +where + T: Iterator<Item: Clone> + Iterator<Item: Clone>, +{ +} +trait AssocConstTrait { + const ASSOC: usize; +} +fn assoc_const_args<T>() +where + T: AssocConstTrait<ASSOC = 0> + AssocConstTrait<ASSOC = 0>, +{ +} 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::<i32>; } + +// #13706 +fn assoc_tys_bounds<T>() +where + T: Iterator<Item: Clone> + Iterator<Item: Clone>, +{ +} +trait AssocConstTrait { + const ASSOC: usize; +} +fn assoc_const_args<T>() +where + T: AssocConstTrait<ASSOC = 0> + AssocConstTrait<ASSOC = 0>, +{ +} |
