Skip to content

Commit

Permalink
Prevent ICE in case of a bound constraint on generic argument (rust-l…
Browse files Browse the repository at this point in the history
…ang#13722)

Fix rust-lang#13706

changelog: [`trait_duplication_in_bounds`]: fix ICE on duplicate type or
constant bound
  • Loading branch information
llogiq authored Nov 25, 2024
2 parents d070402 + 9fd8e99 commit 3d881e1
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 7 deletions.
11 changes: 6 additions & 5 deletions clippy_utils/src/hir_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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))
Expand Down
17 changes: 16 additions & 1 deletion tests/ui/trait_duplication_in_bounds.fixed
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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>,
{
}
17 changes: 16 additions & 1 deletion tests/ui/trait_duplication_in_bounds.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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>,
{
}

0 comments on commit 3d881e1

Please sign in to comment.