Skip to content

Commit

Permalink
Auto merge of #755 - shamatar:auto_traits_for_closures, r=jackh726
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Jul 28, 2022
2 parents 2cbce1b + bd23a76 commit f5c7ee1
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 8 deletions.
18 changes: 10 additions & 8 deletions chalk-solve/src/clauses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,16 @@ pub fn push_auto_trait_impls<I: Interner>(
TyKind::Foreign(_) => Ok(()),

// closures require binders, while the other types do not
TyKind::Closure(closure_id, _) => {
let binders = builder
.db
.closure_upvars(*closure_id, &Substitution::empty(interner));
builder.push_binders(binders, |builder, upvar_ty| {
let conditions = iter::once(mk_ref(upvar_ty));
builder.push_clause(consequence, conditions);
});
TyKind::Closure(closure_id, substs) => {
let closure_fn_substitution = builder.db.closure_fn_substitution(*closure_id, substs);
let binders = builder.db.closure_upvars(*closure_id, substs);
let upvars = binders.substitute(builder.db.interner(), &closure_fn_substitution);

// in a same behavior as for non-auto traits (reuse the code) we can require that
// every bound type must implement this auto-trait
use crate::clauses::builtin_traits::needs_impl_for_tys;
needs_impl_for_tys(builder.db, builder, consequence, Some(upvars).into_iter());

Ok(())
}
TyKind::Generator(generator_id, _) => {
Expand Down
32 changes: 32 additions & 0 deletions tests/test/closures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,3 +280,35 @@ fn closure_implements_fn_traits() {
}
}
}

#[test]
fn closures_propagate_auto_traits() {
test! {
program {
#[auto]
trait Send { }

closure foo(self,) {}

closure with_ty<T>(self,) { T }
}

goal {
foo: Send
} yields {
expect![["Unique"]]
}

goal {
forall<T> { with_ty<T>: Send }
} yields {
expect![["No possible solution"]]
}

goal {
forall<T> { if (T: Send) { with_ty<T>: Send } }
} yields {
expect![["Unique"]]
}
}
}

0 comments on commit f5c7ee1

Please sign in to comment.