Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-ty/src/lower_nextsolver.rs6
-rw-r--r--crates/hir-ty/src/tests/regression.rs53
2 files changed, 58 insertions, 1 deletions
diff --git a/crates/hir-ty/src/lower_nextsolver.rs b/crates/hir-ty/src/lower_nextsolver.rs
index ce953fdcb8..d87181f545 100644
--- a/crates/hir-ty/src/lower_nextsolver.rs
+++ b/crates/hir-ty/src/lower_nextsolver.rs
@@ -1756,7 +1756,11 @@ fn named_associated_type_shorthand_candidates<'db, R>(
db,
GenericDefId::TraitId(trait_def_id),
PredicateFilter::SelfTrait,
- |pred| pred == GenericDefId::TraitId(trait_def_id),
+ // We are likely in the midst of lowering generic predicates of `def`.
+ // So, if we allow `pred == def` we might fall into an infinite recursion.
+ // Actually, we have already checked for the case `pred == def` above as we started
+ // with a stack including `trait_id`
+ |pred| pred != def && pred == GenericDefId::TraitId(trait_def_id),
)
.0
.deref()
diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs
index fd8c641d86..966433369a 100644
--- a/crates/hir-ty/src/tests/regression.rs
+++ b/crates/hir-ty/src/tests/regression.rs
@@ -2439,3 +2439,56 @@ pub fn null_mut<T: PointeeSized + Thin>() -> *mut T {
"#,
);
}
+
+#[test]
+fn issue_20484() {
+ check_no_mismatches(
+ r#"
+struct Eth;
+
+trait FullBlockBody {
+ type Transaction;
+}
+
+impl FullBlockBody for () {
+ type Transaction = ();
+}
+
+trait NodePrimitives {
+ type BlockBody;
+ type SignedTx;
+}
+
+impl NodePrimitives for () {
+ type BlockBody = ();
+ type SignedTx = ();
+}
+
+impl NodePrimitives for Eth {
+ type BlockBody = ();
+ type SignedTx = ();
+}
+
+trait FullNodePrimitives
+where
+ Self: NodePrimitives<BlockBody: FullBlockBody<Transaction = Self::SignedTx>>,
+{
+}
+
+impl<T> FullNodePrimitives for T where
+ T: NodePrimitives<BlockBody: FullBlockBody<Transaction = Self::SignedTx>>,
+{
+}
+
+fn node<N>(_: N)
+where
+ N: FullNodePrimitives,
+{
+}
+
+fn main() {
+ node(Eth);
+}
+"#,
+ );
+}