Skip to content

Commit 9f8cc99

Browse files
authored
Merge pull request #446 from flodiebold/dyn-super-traits-cycle-fix
Fix overeager cycle detection in dyn impl clause generation
2 parents 95dff10 + c1bcf2d commit 9f8cc99

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

chalk-solve/src/clauses/dyn_ty.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ pub fn super_traits<I: Interner>(
133133
) {
134134
let interner = db.interner();
135135
let trait_id = trait_ref.skip_binders().trait_id;
136+
// Avoid cycles
137+
if !seen_traits.insert(trait_id) {
138+
return;
139+
}
136140
trait_refs.push(trait_ref.clone());
137141
let trait_datum = db.trait_datum(trait_id);
138142
let super_trait_refs = trait_datum
@@ -153,10 +157,6 @@ pub fn super_traits<I: Interner>(
153157
{
154158
return None;
155159
}
156-
// Avoid cycles
157-
if !seen_traits.insert(tr.trait_id) {
158-
return None;
159-
}
160160
Some(tr.clone())
161161
}
162162
WhereClause::AliasEq(_) => None,
@@ -175,6 +175,7 @@ pub fn super_traits<I: Interner>(
175175
let q_super_trait_ref = actual_binders.fuse_binders(interner);
176176
go(db, q_super_trait_ref, seen_traits, trait_refs);
177177
}
178+
seen_traits.remove(&trait_id);
178179
}
179180

180181
Binders::new(trait_datum.binders.binders.clone(), trait_refs)

tests/test/existential_types.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,38 @@ fn dyn_super_trait_cycle() {
181181
}
182182
}
183183

184+
#[test]
185+
fn dyn_super_trait_not_a_cycle() {
186+
test! {
187+
program {
188+
trait Thing<T> {}
189+
trait Foo where Self: Thing<B> {}
190+
trait Bar where Self: Foo, Self: Thing<A> {}
191+
192+
struct A {}
193+
struct B {}
194+
}
195+
196+
goal {
197+
dyn Bar: Foo
198+
} yields {
199+
"Unique"
200+
}
201+
202+
goal {
203+
dyn Bar: Thing<A>
204+
} yields {
205+
"Unique"
206+
}
207+
208+
goal {
209+
dyn Bar: Thing<B>
210+
} yields {
211+
"Unique"
212+
}
213+
}
214+
}
215+
184216
#[test]
185217
fn dyn_super_trait_higher_ranked() {
186218
test! {

0 commit comments

Comments
 (0)