implement Copy/Clone for generators

This commit is contained in:
Andrew Cann 2022-03-13 13:39:20 +08:00 committed by Charles Lew
parent abd4d2ef0d
commit 2c0bc9444e
3 changed files with 136 additions and 36 deletions

View file

@ -1928,8 +1928,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::Dynamic(..)
| ty::Str
| ty::Slice(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
| ty::Generator(_, _, hir::Movability::Static)
| ty::Foreign(..)
| ty::Ref(_, _, hir::Mutability::Mut) => None,
@ -1938,6 +1937,39 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
Where(obligation.predicate.rebind(tys.iter().collect()))
}
ty::Generator(_, substs, hir::Movability::Movable) => {
let resolved_upvars = self.infcx.shallow_resolve(substs.as_generator().tupled_upvars_ty());
let resolved_witness = self.infcx.shallow_resolve(substs.as_generator().witness());
if {
matches!(resolved_upvars.kind(), ty::Infer(ty::TyVar(_))) ||
matches!(resolved_witness.kind(), ty::Infer(ty::TyVar(_)))
} {
// Not yet resolved.
Ambiguous
} else {
let mut all = substs.as_generator().upvar_tys().collect::<Vec<_>>();
all.push(substs.as_generator().witness());
Where(obligation.predicate.rebind(all))
}
}
ty::GeneratorWitness(binder) => {
let tys = binder.no_bound_vars().unwrap();
let mut iter = tys.iter();
loop {
let ty = match iter.next() {
Some(ty) => ty,
Option::None => {
break Where(obligation.predicate.rebind(tys.to_vec()))
},
};
let resolved = self.infcx.shallow_resolve(ty);
if matches!(resolved.kind(), ty::Infer(ty::TyVar(_))) {
break Ambiguous;
}
}
}
ty::Closure(_, substs) => {
// (*) binder moved here
let ty = self.infcx.shallow_resolve(substs.as_closure().tupled_upvars_ty());