Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-ty/src/next_solver/predicate.rs7
-rw-r--r--crates/hir-ty/src/tests/regression.rs70
-rw-r--r--crates/test-utils/src/minicore.rs24
3 files changed, 97 insertions, 4 deletions
diff --git a/crates/hir-ty/src/next_solver/predicate.rs b/crates/hir-ty/src/next_solver/predicate.rs
index 6f4fae7073..8658d03a9e 100644
--- a/crates/hir-ty/src/next_solver/predicate.rs
+++ b/crates/hir-ty/src/next_solver/predicate.rs
@@ -714,9 +714,9 @@ impl<'db> rustc_type_ir::inherent::Predicate<DbInterner<'db>> for Predicate<'db>
fn allow_normalization(self) -> bool {
// TODO: this should probably live in rustc_type_ir
match self.inner().as_ref().skip_binder() {
- PredicateKind::Clause(ClauseKind::WellFormed(_))
- | PredicateKind::AliasRelate(..)
- | PredicateKind::NormalizesTo(..) => false,
+ PredicateKind::Clause(ClauseKind::WellFormed(_)) | PredicateKind::AliasRelate(..) => {
+ false
+ }
PredicateKind::Clause(ClauseKind::Trait(_))
| PredicateKind::Clause(ClauseKind::RegionOutlives(_))
| PredicateKind::Clause(ClauseKind::TypeOutlives(_))
@@ -729,6 +729,7 @@ impl<'db> rustc_type_ir::inherent::Predicate<DbInterner<'db>> for Predicate<'db>
| PredicateKind::Coerce(_)
| PredicateKind::Clause(ClauseKind::ConstEvaluatable(_))
| PredicateKind::ConstEquate(_, _)
+ | PredicateKind::NormalizesTo(..)
| PredicateKind::Ambiguous => true,
}
}
diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs
index 3b5b4e4fa5..fba582f880 100644
--- a/crates/hir-ty/src/tests/regression.rs
+++ b/crates/hir-ty/src/tests/regression.rs
@@ -2688,3 +2688,73 @@ pub trait FilterT<F: FilterT<F, V = Self::V> = Self> {
"#,
);
}
+
+#[test]
+fn regression_21605() {
+ check_infer(
+ r#"
+//- minicore: fn, coerce_unsized, dispatch_from_dyn, iterator, iterators
+pub struct Filter<'a, 'b, T>
+where
+ T: 'b,
+ 'a: 'b,
+{
+ filter_fn: dyn Fn(&'a T) -> bool,
+ t: Option<T>,
+ b: &'b (),
+}
+
+impl<'a, 'b, T> Filter<'a, 'b, T>
+where
+ T: 'b,
+ 'a: 'b,
+{
+ pub fn new(filter_fn: dyn Fn(&T) -> bool) -> Self {
+ Self {
+ filter_fn: filter_fn,
+ t: None,
+ b: &(),
+ }
+ }
+}
+
+pub trait FilterExt<T> {
+ type Output;
+ fn filter(&self, filter: &Filter<T>) -> Self::Output;
+}
+
+impl<const N: usize, T> FilterExt<T> for [T; N]
+where
+ T: IntoIterator,
+{
+ type Output = T;
+ fn filter(&self, filter: &Filter<T>) -> Self::Output {
+ let _ = self.into_iter().filter(filter.filter_fn);
+ loop {}
+ }
+}
+"#,
+ expect![[r#"
+ 214..223 'filter_fn': dyn Fn(&'? T) -> bool + 'static
+ 253..360 '{ ... }': Filter<'a, 'b, T>
+ 263..354 'Self {... }': Filter<'a, 'b, T>
+ 293..302 'filter_fn': dyn Fn(&'? T) -> bool + 'static
+ 319..323 'None': Option<T>
+ 340..343 '&()': &'? ()
+ 341..343 '()': ()
+ 421..425 'self': &'? Self
+ 427..433 'filter': &'? Filter<'?, '?, T>
+ 580..584 'self': &'? [T; N]
+ 586..592 'filter': &'? Filter<'?, '?, T>
+ 622..704 '{ ... }': T
+ 636..637 '_': Filter<Iter<'?, T>, dyn Fn(&'? T) -> bool + '?>
+ 640..644 'self': &'? [T; N]
+ 640..656 'self.i...iter()': Iter<'?, T>
+ 640..681 'self.i...er_fn)': Filter<Iter<'?, T>, dyn Fn(&'? T) -> bool + '?>
+ 664..670 'filter': &'? Filter<'?, '?, T>
+ 664..680 'filter...ter_fn': dyn Fn(&'? T) -> bool + 'static
+ 691..698 'loop {}': !
+ 696..698 '{}': ()
+ "#]],
+ );
+}
diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs
index 7d95043867..c34475bbdf 100644
--- a/crates/test-utils/src/minicore.rs
+++ b/crates/test-utils/src/minicore.rs
@@ -1689,6 +1689,21 @@ pub mod iter {
}
}
+ pub struct Filter<I, P> {
+ iter: I,
+ predicate: P,
+ }
+ impl<I: Iterator, P> Iterator for Filter<I, P>
+ where
+ P: FnMut(&I::Item) -> bool,
+ {
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<I::Item> {
+ loop {}
+ }
+ }
+
pub struct FilterMap<I, F> {
iter: I,
f: F,
@@ -1705,7 +1720,7 @@ pub mod iter {
}
}
}
- pub use self::adapters::{FilterMap, Take};
+ pub use self::adapters::{Filter, FilterMap, Take};
mod sources {
mod repeat {
@@ -1756,6 +1771,13 @@ pub mod iter {
{
loop {}
}
+ fn filter<P>(self, predicate: P) -> crate::iter::Filter<Self, P>
+ where
+ Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
+ {
+ loop {}
+ }
fn filter_map<B, F>(self, _f: F) -> crate::iter::FilterMap<Self, F>
where
Self: Sized,