1
Fork 0

Make sure async constructs do not impl Generator

Async lowering turns async functions and blocks into generators internally.
Though these special kinds of generators should not `impl Generator` themselves.
The other way around, normal generators should not `impl Future`.
This commit is contained in:
Arpad Borsos 2022-11-30 19:34:19 +01:00
parent 8de4b13845
commit b5ae4c9629
No known key found for this signature in database
GPG key ID: FC7BCA77824B3298
3 changed files with 131 additions and 1 deletions

View file

@ -203,7 +203,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// type/region parameters.
let self_ty = obligation.self_ty().skip_binder();
match self_ty.kind() {
ty::Generator(..) => {
// async constructs get lowered to a special kind of generator that
// should *not* `impl Generator`.
ty::Generator(did, ..) if !self.tcx().generator_is_async(*did) => {
debug!(?self_ty, ?obligation, "assemble_generator_candidates",);
candidates.vec.push(GeneratorCandidate);
@ -223,6 +225,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
) {
let self_ty = obligation.self_ty().skip_binder();
if let ty::Generator(did, ..) = self_ty.kind() {
// async constructs get lowered to a special kind of generator that
// should directly `impl Future`.
if self.tcx().generator_is_async(*did) {
debug!(?self_ty, ?obligation, "assemble_future_candidates",);