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
This commit is contained in:
commit
3d881e1e59
3 changed files with 38 additions and 7 deletions
|
@ -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))
|
||||
|
|
|
@ -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>,
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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>,
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue