summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_trait_selection/src/traits/select
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/select')
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs131
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs79
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs86
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)),