diff options
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/select')
3 files changed, 181 insertions, 115 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index bead8758a..f4b6d3bcf 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -52,8 +52,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let mut candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false }; - // The only way to prove a NotImplemented(T: Foo) predicate is via a negative impl. - // There are no compiler built-in rules for this. + // Negative trait predicates have different rules than positive trait predicates. if obligation.polarity() == ty::ImplPolarity::Negative { self.assemble_candidates_for_trait_alias(obligation, &mut candidates); self.assemble_candidates_from_impls(obligation, &mut candidates); @@ -110,10 +109,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.assemble_builtin_bound_candidates(clone_conditions, &mut candidates); } - if lang_items.gen_trait() == Some(def_id) { - self.assemble_generator_candidates(obligation, &mut candidates); + if lang_items.coroutine_trait() == Some(def_id) { + self.assemble_coroutine_candidates(obligation, &mut candidates); } else if lang_items.future_trait() == Some(def_id) { self.assemble_future_candidates(obligation, &mut candidates); + } else if lang_items.iterator_trait() == Some(def_id) { + self.assemble_iterator_candidates(obligation, &mut candidates); } self.assemble_closure_candidates(obligation, &mut candidates); @@ -201,25 +202,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Ok(()) } - fn assemble_generator_candidates( + fn assemble_coroutine_candidates( &mut self, obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) { - // Okay to skip binder because the args on generator types never + // Okay to skip binder because the args on coroutine types never // touch bound regions, they just capture the in-scope // type/region parameters. let self_ty = obligation.self_ty().skip_binder(); match self_ty.kind() { - // 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",); + // `async`/`gen` constructs get lowered to a special kind of coroutine that + // should *not* `impl Coroutine`. + ty::Coroutine(did, ..) if self.tcx().is_general_coroutine(*did) => { + debug!(?self_ty, ?obligation, "assemble_coroutine_candidates",); - candidates.vec.push(GeneratorCandidate); + candidates.vec.push(CoroutineCandidate); } ty::Infer(ty::TyVar(_)) => { - debug!("assemble_generator_candidates: ambiguous self-type"); + debug!("assemble_coroutine_candidates: ambiguous self-type"); candidates.ambiguous = true; } _ => {} @@ -232,10 +233,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidates: &mut SelectionCandidateSet<'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 + if let ty::Coroutine(did, ..) = self_ty.kind() { + // async constructs get lowered to a special kind of coroutine that // should directly `impl Future`. - if self.tcx().generator_is_async(*did) { + if self.tcx().coroutine_is_async(*did) { debug!(?self_ty, ?obligation, "assemble_future_candidates",); candidates.vec.push(FutureCandidate); @@ -243,6 +244,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } + fn assemble_iterator_candidates( + &mut self, + obligation: &PolyTraitObligation<'tcx>, + candidates: &mut SelectionCandidateSet<'tcx>, + ) { + let self_ty = obligation.self_ty().skip_binder(); + if let ty::Coroutine(did, ..) = self_ty.kind() { + // gen constructs get lowered to a special kind of coroutine that + // should directly `impl Iterator`. + if self.tcx().coroutine_is_gen(*did) { + debug!(?self_ty, ?obligation, "assemble_iterator_candidates",); + + candidates.vec.push(IteratorCandidate); + } + } + } + /// Checks for the artificial impl that the compiler will create for an obligation like `X : /// FnMut<..>` where `X` is a closure type. /// @@ -435,8 +453,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::RawPtr(_) | ty::Ref(_, _, _) | ty::Closure(_, _) - | ty::Generator(_, _, _) - | ty::GeneratorWitness(..) + | ty::Coroutine(_, _, _) + | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(_) | ty::Error(_) => return true, @@ -492,7 +510,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // this trait and type. } ty::Param(..) - | ty::Alias(ty::Projection | ty::Inherent, ..) + | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..) | ty::Placeholder(..) | ty::Bound(..) => { // In these cases, we don't know what the actual @@ -513,16 +531,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // The auto impl might apply; we don't know. candidates.ambiguous = true; } - ty::Generator(_, _, movability) + ty::Coroutine(_, _, movability) if self.tcx().lang_items().unpin_trait() == Some(def_id) => { match movability { hir::Movability::Static => { - // Immovable generators are never `Unpin`, so + // Immovable coroutines are never `Unpin`, so // suppress the normal auto-impl candidate for it. } hir::Movability::Movable => { - // Movable generators are always `Unpin`, so add an + // Movable coroutines are always `Unpin`, so add an // unconditional builtin candidate. candidates.vec.push(BuiltinCandidate { has_nested: false }); } @@ -536,20 +554,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); } - ty::Alias(_, _) - if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(..))) => - { - // We do not generate an auto impl candidate for `impl Trait`s which already - // reference our auto trait. - // - // For example during candidate assembly for `impl Send: Send`, we don't have - // to look at the constituent types for this opaque types to figure out that this - // trivially holds. - // - // Note that this is only sound as projection candidates of opaque types - // are always applicable for auto traits. + ty::Alias(ty::Opaque, _) => { + if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(..))) { + // We do not generate an auto impl candidate for `impl Trait`s which already + // reference our auto trait. + // + // For example during candidate assembly for `impl Send: Send`, we don't have + // to look at the constituent types for this opaque types to figure out that this + // trivially holds. + // + // Note that this is only sound as projection candidates of opaque types + // are always applicable for auto traits. + } else if self.infcx.intercrate { + // We do not emit auto trait candidates for opaque types in coherence. + // Doing so can result in weird dependency cycles. + candidates.ambiguous = true; + } else { + candidates.vec.push(AutoImplCandidate) + } } - ty::Alias(_, _) => candidates.vec.push(AutoImplCandidate), ty::Bool | ty::Char @@ -565,10 +588,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::FnDef(..) | ty::FnPtr(_) | ty::Closure(_, _) - | ty::Generator(..) + | ty::Coroutine(..) | ty::Never | ty::Tuple(_) - | ty::GeneratorWitness(..) => { + | ty::CoroutineWitness(..) => { // Only consider auto impls if there are no manual impls for the root of `self_ty`. // // For example, we only consider auto candidates for `&i32: Auto` if no explicit impl @@ -605,15 +628,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } self.infcx.probe(|_snapshot| { - if obligation.has_non_region_late_bound() { - return; - } + let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate); + let placeholder_trait_predicate = + self.infcx.instantiate_binder_with_placeholders(poly_trait_predicate); - // The code below doesn't care about regions, and the - // self-ty here doesn't escape this probe, so just erase - // any LBR. - let self_ty = self.tcx().erase_late_bound_regions(obligation.self_ty()); - let poly_trait_ref = match self_ty.kind() { + let self_ty = placeholder_trait_predicate.self_ty(); + let principal_trait_ref = match self_ty.kind() { ty::Dynamic(ref data, ..) => { if data.auto_traits().any(|did| did == obligation.predicate.def_id()) { debug!( @@ -645,18 +665,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { _ => return, }; - debug!(?poly_trait_ref, "assemble_candidates_from_object_ty"); - - let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate); - let placeholder_trait_predicate = - self.infcx.instantiate_binder_with_placeholders(poly_trait_predicate); + debug!(?principal_trait_ref, "assemble_candidates_from_object_ty"); // Count only those upcast versions that match the trait-ref // we are looking for. Specifically, do not only check for the // correct trait, but also the correct type parameters. // For example, we may be trying to upcast `Foo` to `Bar<i32>`, // but `Foo` is declared as `trait Foo: Bar<u32>`. - let candidate_supertraits = util::supertraits(self.tcx(), poly_trait_ref) + let candidate_supertraits = util::supertraits(self.tcx(), principal_trait_ref) .enumerate() .filter(|&(_, upcast_trait_ref)| { self.infcx.probe(|_| { @@ -699,7 +715,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let ty = traits::normalize_projection_type( self, param_env, - tcx.mk_alias_ty(tcx.lang_items().deref_target()?, trait_ref.args), + ty::AliasTy::new(tcx, tcx.lang_items().deref_target()?, trait_ref.args), cause.clone(), 0, // We're *intentionally* throwing these away, @@ -942,9 +958,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Array(..) | ty::Slice(_) | ty::Closure(..) - | ty::Generator(..) + | ty::Coroutine(..) | ty::Tuple(_) - | ty::GeneratorWitness(..) => { + | ty::CoroutineWitness(..) => { // These are built-in, and cannot have a custom `impl const Destruct`. candidates.vec.push(ConstDestructCandidate(None)); } @@ -1016,8 +1032,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::FnPtr(_) | ty::Dynamic(_, _, _) | ty::Closure(_, _) - | ty::Generator(_, _, _) - | ty::GeneratorWitness(..) + | ty::Coroutine(_, _, _) + | ty::CoroutineWitness(..) | ty::Never | ty::Alias(..) | ty::Param(_) @@ -1059,6 +1075,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidates: &mut SelectionCandidateSet<'tcx>, ) { let self_ty = self.infcx.shallow_resolve(obligation.self_ty()); + match self_ty.skip_binder().kind() { ty::FnPtr(_) => candidates.vec.push(BuiltinCandidate { has_nested: false }), ty::Bool @@ -1077,8 +1094,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Placeholder(..) | ty::Dynamic(..) | ty::Closure(..) - | ty::Generator(..) - | ty::GeneratorWitness(..) + | ty::Coroutine(..) + | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(..) | ty::Alias(..) diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 08ee9c73b..4bfa341e3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -83,9 +83,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ImplSource::Builtin(BuiltinImplSource::Misc, vtable_closure) } - GeneratorCandidate => { - let vtable_generator = self.confirm_generator_candidate(obligation)?; - ImplSource::Builtin(BuiltinImplSource::Misc, vtable_generator) + CoroutineCandidate => { + let vtable_coroutine = self.confirm_coroutine_candidate(obligation)?; + ImplSource::Builtin(BuiltinImplSource::Misc, vtable_coroutine) } FutureCandidate => { @@ -93,6 +93,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ImplSource::Builtin(BuiltinImplSource::Misc, vtable_future) } + IteratorCandidate => { + let vtable_iterator = self.confirm_iterator_candidate(obligation)?; + ImplSource::Builtin(BuiltinImplSource::Misc, vtable_iterator) + } + FnPointerCandidate { is_const } => { let data = self.confirm_fn_pointer_candidate(obligation, is_const)?; ImplSource::Builtin(BuiltinImplSource::Misc, data) @@ -711,23 +716,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { trait_obligations } - fn confirm_generator_candidate( + fn confirm_coroutine_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { - // Okay to skip binder because the args on generator types never + // Okay to skip binder because the args on coroutine types never // touch bound regions, they just capture the in-scope // type/region parameters. let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder()); - let ty::Generator(generator_def_id, args, _) = *self_ty.kind() else { + let ty::Coroutine(coroutine_def_id, args, _) = *self_ty.kind() else { bug!("closure candidate for non-closure {:?}", obligation); }; - debug!(?obligation, ?generator_def_id, ?args, "confirm_generator_candidate"); + debug!(?obligation, ?coroutine_def_id, ?args, "confirm_coroutine_candidate"); - let gen_sig = args.as_generator().poly_sig(); + let coroutine_sig = args.as_coroutine().poly_sig(); - // NOTE: The self-type is a generator type and hence is + // NOTE: The self-type is a coroutine type and hence is // in fact unparameterized (or at least does not reference any // regions bound in the obligation). let self_ty = obligation @@ -736,16 +741,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .no_bound_vars() .expect("unboxed closure type should not capture bound vars from the predicate"); - let trait_ref = super::util::generator_trait_ref_and_outputs( + let trait_ref = super::util::coroutine_trait_ref_and_outputs( self.tcx(), obligation.predicate.def_id(), self_ty, - gen_sig, + coroutine_sig, ) .map_bound(|(trait_ref, ..)| trait_ref); let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?; - debug!(?trait_ref, ?nested, "generator candidate obligations"); + debug!(?trait_ref, ?nested, "coroutine candidate obligations"); Ok(nested) } @@ -754,23 +759,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { - // Okay to skip binder because the args on generator types never + // Okay to skip binder because the args on coroutine types never // touch bound regions, they just capture the in-scope // type/region parameters. let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder()); - let ty::Generator(generator_def_id, args, _) = *self_ty.kind() else { + let ty::Coroutine(coroutine_def_id, args, _) = *self_ty.kind() else { bug!("closure candidate for non-closure {:?}", obligation); }; - debug!(?obligation, ?generator_def_id, ?args, "confirm_future_candidate"); + debug!(?obligation, ?coroutine_def_id, ?args, "confirm_future_candidate"); - let gen_sig = args.as_generator().poly_sig(); + let coroutine_sig = args.as_coroutine().poly_sig(); let trait_ref = super::util::future_trait_ref_and_outputs( self.tcx(), obligation.predicate.def_id(), obligation.predicate.no_bound_vars().expect("future has no bound vars").self_ty(), - gen_sig, + coroutine_sig, ) .map_bound(|(trait_ref, ..)| trait_ref); @@ -780,6 +785,36 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Ok(nested) } + fn confirm_iterator_candidate( + &mut self, + obligation: &PolyTraitObligation<'tcx>, + ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { + // Okay to skip binder because the args on coroutine types never + // touch bound regions, they just capture the in-scope + // type/region parameters. + let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder()); + let ty::Coroutine(coroutine_def_id, args, _) = *self_ty.kind() else { + bug!("closure candidate for non-closure {:?}", obligation); + }; + + debug!(?obligation, ?coroutine_def_id, ?args, "confirm_iterator_candidate"); + + let gen_sig = args.as_coroutine().poly_sig(); + + let trait_ref = super::util::iterator_trait_ref_and_outputs( + self.tcx(), + obligation.predicate.def_id(), + obligation.predicate.no_bound_vars().expect("iterator has no bound vars").self_ty(), + gen_sig, + ) + .map_bound(|(trait_ref, ..)| trait_ref); + + let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?; + debug!(?trait_ref, ?nested, "iterator candidate obligations"); + + Ok(nested) + } + #[instrument(skip(self), level = "debug")] fn confirm_closure_candidate( &mut self, @@ -1234,13 +1269,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::Closure(_, args) => { stack.push(args.as_closure().tupled_upvars_ty()); } - ty::Generator(_, args, _) => { - let generator = args.as_generator(); - stack.extend([generator.tupled_upvars_ty(), generator.witness()]); + ty::Coroutine(_, args, _) => { + let coroutine = args.as_coroutine(); + stack.extend([coroutine.tupled_upvars_ty(), coroutine.witness()]); } - ty::GeneratorWitness(def_id, args) => { + ty::CoroutineWitness(def_id, args) => { let tcx = self.tcx(); - stack.extend(tcx.generator_hidden_types(def_id).map(|bty| { + stack.extend(tcx.coroutine_hidden_types(def_id).map(|bty| { let ty = bty.instantiate(tcx, args); debug_assert!(!ty.has_late_bound_regions()); ty diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index ec46a6769..08208cc60 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -38,6 +38,7 @@ use rustc_infer::traits::TraitObligation; use rustc_middle::dep_graph::dep_kinds; use rustc_middle::dep_graph::DepNodeIndex; use rustc_middle::mir::interpret::ErrorHandled; +use rustc_middle::ty::_match::MatchAgainstFreshVars; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::relate::TypeRelation; @@ -858,7 +859,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { subobligations, ); if let Ok(eval_rslt) = res - && (eval_rslt == EvaluatedToOk || eval_rslt == EvaluatedToOkModuloRegions) + && (eval_rslt == EvaluatedToOk + || eval_rslt == EvaluatedToOkModuloRegions) && let Some(key) = ProjectionCacheKey::from_poly_projection_predicate( self, data, @@ -1884,8 +1886,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ImplCandidate(..) | AutoImplCandidate | ClosureCandidate { .. } - | GeneratorCandidate + | CoroutineCandidate | FutureCandidate + | IteratorCandidate | FnPointerCandidate { .. } | BuiltinObjectCandidate | BuiltinUnsizeCandidate @@ -1912,8 +1915,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ImplCandidate(_) | AutoImplCandidate | ClosureCandidate { .. } - | GeneratorCandidate + | CoroutineCandidate | FutureCandidate + | IteratorCandidate | FnPointerCandidate { .. } | BuiltinObjectCandidate | BuiltinUnsizeCandidate @@ -1946,8 +1950,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ImplCandidate(..) | AutoImplCandidate | ClosureCandidate { .. } - | GeneratorCandidate + | CoroutineCandidate | FutureCandidate + | IteratorCandidate | FnPointerCandidate { .. } | BuiltinObjectCandidate | BuiltinUnsizeCandidate @@ -1960,8 +1965,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ImplCandidate(..) | AutoImplCandidate | ClosureCandidate { .. } - | GeneratorCandidate + | CoroutineCandidate | FutureCandidate + | IteratorCandidate | FnPointerCandidate { .. } | BuiltinObjectCandidate | BuiltinUnsizeCandidate @@ -2066,8 +2072,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ( ImplCandidate(_) | ClosureCandidate { .. } - | GeneratorCandidate + | CoroutineCandidate | FutureCandidate + | IteratorCandidate | FnPointerCandidate { .. } | BuiltinObjectCandidate | BuiltinUnsizeCandidate @@ -2076,8 +2083,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { | TraitAliasCandidate, ImplCandidate(_) | ClosureCandidate { .. } - | GeneratorCandidate + | CoroutineCandidate | FutureCandidate + | IteratorCandidate | FnPointerCandidate { .. } | BuiltinObjectCandidate | BuiltinUnsizeCandidate @@ -2110,8 +2118,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> { | ty::RawPtr(..) | ty::Char | ty::Ref(..) - | ty::Generator(..) - | ty::GeneratorWitness(..) + | ty::Coroutine(..) + | ty::CoroutineWitness(..) | ty::Array(..) | ty::Closure(..) | ty::Never @@ -2178,7 +2186,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ty::Dynamic(..) | ty::Str | ty::Slice(..) - | ty::Generator(_, _, hir::Movability::Static) + | ty::Coroutine(_, _, hir::Movability::Static) | ty::Foreign(..) | ty::Ref(_, _, hir::Mutability::Mut) => None, @@ -2187,21 +2195,21 @@ impl<'tcx> SelectionContext<'_, 'tcx> { Where(obligation.predicate.rebind(tys.iter().collect())) } - ty::Generator(_, args, hir::Movability::Movable) => { - if self.tcx().features().generator_clone { + ty::Coroutine(_, args, hir::Movability::Movable) => { + if self.tcx().features().coroutine_clone { let resolved_upvars = - self.infcx.shallow_resolve(args.as_generator().tupled_upvars_ty()); + self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty()); let resolved_witness = - self.infcx.shallow_resolve(args.as_generator().witness()); + self.infcx.shallow_resolve(args.as_coroutine().witness()); if resolved_upvars.is_ty_var() || resolved_witness.is_ty_var() { // Not yet resolved. Ambiguous } else { let all = args - .as_generator() + .as_coroutine() .upvar_tys() .iter() - .chain([args.as_generator().witness()]) + .chain([args.as_coroutine().witness()]) .collect::<Vec<_>>(); Where(obligation.predicate.rebind(all)) } @@ -2210,8 +2218,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } } - ty::GeneratorWitness(def_id, ref args) => { - let hidden_types = bind_generator_hidden_types_above( + ty::CoroutineWitness(def_id, ref args) => { + let hidden_types = bind_coroutine_hidden_types_above( self.infcx, def_id, args, @@ -2309,14 +2317,14 @@ impl<'tcx> SelectionContext<'_, 'tcx> { t.rebind(vec![ty]) } - ty::Generator(_, ref args, _) => { - let ty = self.infcx.shallow_resolve(args.as_generator().tupled_upvars_ty()); - let witness = args.as_generator().witness(); + ty::Coroutine(_, ref args, _) => { + let ty = self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty()); + let witness = args.as_coroutine().witness(); t.rebind([ty].into_iter().chain(iter::once(witness)).collect()) } - ty::GeneratorWitness(def_id, ref args) => { - bind_generator_hidden_types_above(self.infcx, def_id, args, t.bound_vars()) + ty::CoroutineWitness(def_id, ref args) => { + bind_coroutine_hidden_types_above(self.infcx, def_id, args, t.bound_vars()) } // For `PhantomData<T>`, we pass `T`. @@ -2381,12 +2389,21 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ) }); - let obligation = Obligation::new( - self.tcx(), - cause.clone(), - param_env, - ty::TraitRef::new(self.tcx(), trait_def_id, [normalized_ty]), - ); + let tcx = self.tcx(); + let trait_ref = if tcx.generics_of(trait_def_id).params.len() == 1 { + ty::TraitRef::new(tcx, trait_def_id, [normalized_ty]) + } else { + // If this is an ill-formed auto/built-in trait, then synthesize + // new error args for the missing generics. + let err_args = ty::GenericArgs::extend_with_error( + tcx, + trait_def_id, + &[normalized_ty.into()], + ); + ty::TraitRef::new(tcx, trait_def_id, err_args) + }; + + let obligation = Obligation::new(self.tcx(), cause.clone(), param_env, trait_ref); obligations.push(obligation); obligations }) @@ -2623,7 +2640,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { current: ty::PolyTraitPredicate<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> bool { - let mut matcher = ty::_match::Match::new(self.tcx(), param_env); + let mut matcher = MatchAgainstFreshVars::new(self.tcx(), param_env); matcher.relate(previous, current).is_ok() } @@ -3052,12 +3069,12 @@ pub enum ProjectionMatchesProjection { No, } -/// Replace all regions inside the generator interior with late bound regions. +/// Replace all regions inside the coroutine interior with late bound regions. /// Note that each region slot in the types gets a new fresh late bound region, which means that /// none of the regions inside relate to any other, even if typeck had previously found constraints /// that would cause them to be related. #[instrument(level = "trace", skip(infcx), ret)] -fn bind_generator_hidden_types_above<'tcx>( +fn bind_coroutine_hidden_types_above<'tcx>( infcx: &InferCtxt<'tcx>, def_id: DefId, args: ty::GenericArgsRef<'tcx>, @@ -3072,7 +3089,7 @@ fn bind_generator_hidden_types_above<'tcx>( let mut counter = num_bound_variables; let hidden_types: Vec<_> = tcx - .generator_hidden_types(def_id) + .coroutine_hidden_types(def_id) // Deduplicate tys to avoid repeated work. .filter(|bty| seen_tys.insert(*bty)) .map(|mut bty| { @@ -3096,9 +3113,6 @@ fn bind_generator_hidden_types_above<'tcx>( bty.instantiate(tcx, args) }) .collect(); - if considering_regions { - debug_assert!(!hidden_types.has_erased_regions()); - } let bound_vars = tcx.mk_bound_variable_kinds_from_iter(bound_vars.iter().chain( (num_bound_variables..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon)), |