Skip to content

Commit f5c7ee1

Browse files
committed
Auto merge of #755 - shamatar:auto_traits_for_closures, r=jackh726
Solve auto traits for closures (issue #734) Fixes #734 Behavior for resolution for auto trait should not be different from requirements for any other trait, even though it's placed in special location - one should require that every bound type should implement some (auto) trait for a closure to automatically implement trait.
2 parents 2cbce1b + bd23a76 commit f5c7ee1

File tree

2 files changed

+42
-8
lines changed

2 files changed

+42
-8
lines changed

chalk-solve/src/clauses.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,16 @@ pub fn push_auto_trait_impls<I: Interner>(
161161
TyKind::Foreign(_) => Ok(()),
162162

163163
// closures require binders, while the other types do not
164-
TyKind::Closure(closure_id, _) => {
165-
let binders = builder
166-
.db
167-
.closure_upvars(*closure_id, &Substitution::empty(interner));
168-
builder.push_binders(binders, |builder, upvar_ty| {
169-
let conditions = iter::once(mk_ref(upvar_ty));
170-
builder.push_clause(consequence, conditions);
171-
});
164+
TyKind::Closure(closure_id, substs) => {
165+
let closure_fn_substitution = builder.db.closure_fn_substitution(*closure_id, substs);
166+
let binders = builder.db.closure_upvars(*closure_id, substs);
167+
let upvars = binders.substitute(builder.db.interner(), &closure_fn_substitution);
168+
169+
// in a same behavior as for non-auto traits (reuse the code) we can require that
170+
// every bound type must implement this auto-trait
171+
use crate::clauses::builtin_traits::needs_impl_for_tys;
172+
needs_impl_for_tys(builder.db, builder, consequence, Some(upvars).into_iter());
173+
172174
Ok(())
173175
}
174176
TyKind::Generator(generator_id, _) => {

tests/test/closures.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,3 +280,35 @@ fn closure_implements_fn_traits() {
280280
}
281281
}
282282
}
283+
284+
#[test]
285+
fn closures_propagate_auto_traits() {
286+
test! {
287+
program {
288+
#[auto]
289+
trait Send { }
290+
291+
closure foo(self,) {}
292+
293+
closure with_ty<T>(self,) { T }
294+
}
295+
296+
goal {
297+
foo: Send
298+
} yields {
299+
expect![["Unique"]]
300+
}
301+
302+
goal {
303+
forall<T> { with_ty<T>: Send }
304+
} yields {
305+
expect![["No possible solution"]]
306+
}
307+
308+
goal {
309+
forall<T> { if (T: Send) { with_ty<T>: Send } }
310+
} yields {
311+
expect![["Unique"]]
312+
}
313+
}
314+
}

0 commit comments

Comments
 (0)