about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src
diff options
context:
space:
mode:
authorAndrew Cann <shum@canndrew.org>2022-03-13 13:39:20 +0800
committerCharles Lew <crlf0710@gmail.com>2022-09-11 13:50:35 +0800
commit2c0bc9444eea8677a307c2440b2f206911d5bbbe (patch)
tree6a9429d879d6caaec5d054fd4c2229d8f753f25d /compiler/rustc_trait_selection/src
parentabd4d2ef0d23553c1d21b90d3b1353e3a42e1edf (diff)
downloadrust-2c0bc9444eea8677a307c2440b2f206911d5bbbe.tar.gz
rust-2c0bc9444eea8677a307c2440b2f206911d5bbbe.zip
implement Copy/Clone for generators
Diffstat (limited to 'compiler/rustc_trait_selection/src')
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs36
1 files changed, 34 insertions, 2 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 5da8cfab0b1..592c6c8e055 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -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());