From 0228c073e07bc36ab4dbb88ab7f3cbdf00832d59 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Sun, 13 Mar 2022 14:41:44 +0800 Subject: [PATCH] add generator_clone feature gate --- compiler/rustc_feature/src/active.rs | 2 + compiler/rustc_span/src/symbol.rs | 1 + .../src/traits/select/mod.rs | 56 +++++++++++-------- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 98258834bd5..0168587fbce 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -396,6 +396,8 @@ declare_features! ( (active, fn_align, "1.53.0", Some(82232), None), /// Allows defining generators. (active, generators, "1.21.0", Some(43122), None), + /// Allows generators to be cloned. + (active, generator_clone, "1.60.0", None, None), /// Infer generic args for both consts and types. (active, generic_arg_infer, "1.55.0", Some(85077), None), /// Allows associated types to be generic, e.g., `type Foo;` (RFC 1598). diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9c3d99deae0..5bddcd34819 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -763,6 +763,7 @@ symbols! { gen_future, gen_kill, generator, + generator_clone, generator_state, generators, generic_arg_infer, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 592c6c8e055..0e7483847e3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1938,35 +1938,43 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } 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 + if self.tcx().features().generator_clone { + 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::>(); + all.push(substs.as_generator().witness()); + Where(obligation.predicate.rebind(all)) + } } else { - let mut all = substs.as_generator().upvar_tys().collect::>(); - all.push(substs.as_generator().witness()); - Where(obligation.predicate.rebind(all)) + None } } 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; - } + match binder.no_bound_vars() { + Some(tys) => { + 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; + } + } + }, + Option::None => None, } }