Rename tcx to cx
This commit is contained in:
@@ -36,11 +36,11 @@ where
|
||||
{
|
||||
fn self_ty(self) -> I::Ty;
|
||||
|
||||
fn trait_ref(self, tcx: I) -> ty::TraitRef<I>;
|
||||
fn trait_ref(self, cx: I) -> ty::TraitRef<I>;
|
||||
|
||||
fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> Self;
|
||||
fn with_self_ty(self, cx: I, self_ty: I::Ty) -> Self;
|
||||
|
||||
fn trait_def_id(self, tcx: I) -> I::DefId;
|
||||
fn trait_def_id(self, cx: I) -> I::DefId;
|
||||
|
||||
/// Try equating an assumption predicate against a goal's predicate. If it
|
||||
/// holds, then execute the `then` callback, which should do any additional
|
||||
@@ -82,7 +82,7 @@ where
|
||||
assumption: I::Clause,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| {
|
||||
let tcx = ecx.cx();
|
||||
let cx = ecx.cx();
|
||||
let ty::Dynamic(bounds, _, _) = goal.predicate.self_ty().kind() else {
|
||||
panic!("expected object type in `probe_and_consider_object_bound_candidate`");
|
||||
};
|
||||
@@ -91,7 +91,7 @@ where
|
||||
structural_traits::predicates_for_object_candidate(
|
||||
ecx,
|
||||
goal.param_env,
|
||||
goal.predicate.trait_ref(tcx),
|
||||
goal.predicate.trait_ref(cx),
|
||||
bounds,
|
||||
),
|
||||
);
|
||||
@@ -340,15 +340,15 @@ where
|
||||
goal: Goal<I, G>,
|
||||
candidates: &mut Vec<Candidate<I>>,
|
||||
) {
|
||||
let tcx = self.cx();
|
||||
tcx.for_each_relevant_impl(
|
||||
goal.predicate.trait_def_id(tcx),
|
||||
let cx = self.cx();
|
||||
cx.for_each_relevant_impl(
|
||||
goal.predicate.trait_def_id(cx),
|
||||
goal.predicate.self_ty(),
|
||||
|impl_def_id| {
|
||||
// For every `default impl`, there's always a non-default `impl`
|
||||
// that will *also* apply. There's no reason to register a candidate
|
||||
// for this impl, since it is *not* proof that the trait goal holds.
|
||||
if tcx.impl_is_default(impl_def_id) {
|
||||
if cx.impl_is_default(impl_def_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -366,8 +366,8 @@ where
|
||||
goal: Goal<I, G>,
|
||||
candidates: &mut Vec<Candidate<I>>,
|
||||
) {
|
||||
let tcx = self.cx();
|
||||
let trait_def_id = goal.predicate.trait_def_id(tcx);
|
||||
let cx = self.cx();
|
||||
let trait_def_id = goal.predicate.trait_def_id(cx);
|
||||
|
||||
// N.B. When assembling built-in candidates for lang items that are also
|
||||
// `auto` traits, then the auto trait candidate that is assembled in
|
||||
@@ -378,47 +378,47 @@ where
|
||||
// `solve::trait_goals` instead.
|
||||
let result = if let Err(guar) = goal.predicate.error_reported() {
|
||||
G::consider_error_guaranteed_candidate(self, guar)
|
||||
} else if tcx.trait_is_auto(trait_def_id) {
|
||||
} else if cx.trait_is_auto(trait_def_id) {
|
||||
G::consider_auto_trait_candidate(self, goal)
|
||||
} else if tcx.trait_is_alias(trait_def_id) {
|
||||
} else if cx.trait_is_alias(trait_def_id) {
|
||||
G::consider_trait_alias_candidate(self, goal)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Sized) {
|
||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Sized) {
|
||||
G::consider_builtin_sized_candidate(self, goal)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Copy)
|
||||
|| tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Clone)
|
||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Copy)
|
||||
|| cx.is_lang_item(trait_def_id, TraitSolverLangItem::Clone)
|
||||
{
|
||||
G::consider_builtin_copy_clone_candidate(self, goal)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::PointerLike) {
|
||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::PointerLike) {
|
||||
G::consider_builtin_pointer_like_candidate(self, goal)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::FnPtrTrait) {
|
||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::FnPtrTrait) {
|
||||
G::consider_builtin_fn_ptr_trait_candidate(self, goal)
|
||||
} else if let Some(kind) = self.cx().fn_trait_kind_from_def_id(trait_def_id) {
|
||||
G::consider_builtin_fn_trait_candidates(self, goal, kind)
|
||||
} else if let Some(kind) = self.cx().async_fn_trait_kind_from_def_id(trait_def_id) {
|
||||
G::consider_builtin_async_fn_trait_candidates(self, goal, kind)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncFnKindHelper) {
|
||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncFnKindHelper) {
|
||||
G::consider_builtin_async_fn_kind_helper_candidate(self, goal)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Tuple) {
|
||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Tuple) {
|
||||
G::consider_builtin_tuple_candidate(self, goal)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::PointeeTrait) {
|
||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::PointeeTrait) {
|
||||
G::consider_builtin_pointee_candidate(self, goal)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Future) {
|
||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Future) {
|
||||
G::consider_builtin_future_candidate(self, goal)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Iterator) {
|
||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Iterator) {
|
||||
G::consider_builtin_iterator_candidate(self, goal)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::FusedIterator) {
|
||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::FusedIterator) {
|
||||
G::consider_builtin_fused_iterator_candidate(self, goal)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncIterator) {
|
||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncIterator) {
|
||||
G::consider_builtin_async_iterator_candidate(self, goal)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Coroutine) {
|
||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Coroutine) {
|
||||
G::consider_builtin_coroutine_candidate(self, goal)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::DiscriminantKind) {
|
||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::DiscriminantKind) {
|
||||
G::consider_builtin_discriminant_kind_candidate(self, goal)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncDestruct) {
|
||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncDestruct) {
|
||||
G::consider_builtin_async_destruct_candidate(self, goal)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Destruct) {
|
||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Destruct) {
|
||||
G::consider_builtin_destruct_candidate(self, goal)
|
||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) {
|
||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) {
|
||||
G::consider_builtin_transmute_candidate(self, goal)
|
||||
} else {
|
||||
Err(NoSolution)
|
||||
@@ -428,7 +428,7 @@ where
|
||||
|
||||
// There may be multiple unsize candidates for a trait with several supertraits:
|
||||
// `trait Foo: Bar<A> + Bar<B>` and `dyn Foo: Unsize<dyn Bar<_>>`
|
||||
if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Unsize) {
|
||||
if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Unsize) {
|
||||
candidates.extend(G::consider_structural_builtin_unsize_candidates(self, goal));
|
||||
}
|
||||
}
|
||||
@@ -557,8 +557,8 @@ where
|
||||
goal: Goal<I, G>,
|
||||
candidates: &mut Vec<Candidate<I>>,
|
||||
) {
|
||||
let tcx = self.cx();
|
||||
if !tcx.trait_may_be_implemented_via_object(goal.predicate.trait_def_id(tcx)) {
|
||||
let cx = self.cx();
|
||||
if !cx.trait_may_be_implemented_via_object(goal.predicate.trait_def_id(cx)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -596,7 +596,7 @@ where
|
||||
};
|
||||
|
||||
// Do not consider built-in object impls for non-object-safe types.
|
||||
if bounds.principal_def_id().is_some_and(|def_id| !tcx.trait_is_object_safe(def_id)) {
|
||||
if bounds.principal_def_id().is_some_and(|def_id| !cx.trait_is_object_safe(def_id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -614,7 +614,7 @@ where
|
||||
self,
|
||||
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
|
||||
goal,
|
||||
bound.with_self_ty(tcx, self_ty),
|
||||
bound.with_self_ty(cx, self_ty),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -624,14 +624,13 @@ where
|
||||
// since we don't need to look at any supertrait or anything if we are doing
|
||||
// a projection goal.
|
||||
if let Some(principal) = bounds.principal() {
|
||||
let principal_trait_ref = principal.with_self_ty(tcx, self_ty);
|
||||
for (idx, assumption) in D::elaborate_supertraits(tcx, principal_trait_ref).enumerate()
|
||||
{
|
||||
let principal_trait_ref = principal.with_self_ty(cx, self_ty);
|
||||
for (idx, assumption) in D::elaborate_supertraits(cx, principal_trait_ref).enumerate() {
|
||||
candidates.extend(G::probe_and_consider_object_bound_candidate(
|
||||
self,
|
||||
CandidateSource::BuiltinImpl(BuiltinImplSource::Object(idx)),
|
||||
goal,
|
||||
assumption.upcast(tcx),
|
||||
assumption.upcast(cx),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -649,11 +648,11 @@ where
|
||||
goal: Goal<I, G>,
|
||||
candidates: &mut Vec<Candidate<I>>,
|
||||
) {
|
||||
let tcx = self.cx();
|
||||
let cx = self.cx();
|
||||
|
||||
candidates.extend(self.probe_trait_candidate(CandidateSource::CoherenceUnknowable).enter(
|
||||
|ecx| {
|
||||
let trait_ref = goal.predicate.trait_ref(tcx);
|
||||
let trait_ref = goal.predicate.trait_ref(cx);
|
||||
if ecx.trait_ref_is_knowable(goal.param_env, trait_ref)? {
|
||||
Err(NoSolution)
|
||||
} else {
|
||||
@@ -678,9 +677,9 @@ where
|
||||
goal: Goal<I, G>,
|
||||
candidates: &mut Vec<Candidate<I>>,
|
||||
) {
|
||||
let tcx = self.cx();
|
||||
let cx = self.cx();
|
||||
let trait_goal: Goal<I, ty::TraitPredicate<I>> =
|
||||
goal.with(tcx, goal.predicate.trait_ref(tcx));
|
||||
goal.with(cx, goal.predicate.trait_ref(cx));
|
||||
|
||||
let mut trait_candidates_from_env = vec![];
|
||||
self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| {
|
||||
|
||||
@@ -23,7 +23,7 @@ where
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
let tcx = ecx.cx();
|
||||
let cx = ecx.cx();
|
||||
match ty.kind() {
|
||||
ty::Uint(_)
|
||||
| ty::Int(_)
|
||||
@@ -36,7 +36,7 @@ where
|
||||
| ty::Char => Ok(vec![]),
|
||||
|
||||
// Treat `str` like it's defined as `struct str([u8]);`
|
||||
ty::Str => Ok(vec![ty::Binder::dummy(Ty::new_slice(tcx, Ty::new_u8(tcx)))]),
|
||||
ty::Str => Ok(vec![ty::Binder::dummy(Ty::new_slice(cx, Ty::new_u8(cx)))]),
|
||||
|
||||
ty::Dynamic(..)
|
||||
| ty::Param(..)
|
||||
@@ -79,21 +79,21 @@ where
|
||||
.cx()
|
||||
.bound_coroutine_hidden_types(def_id)
|
||||
.into_iter()
|
||||
.map(|bty| bty.instantiate(tcx, args))
|
||||
.map(|bty| bty.instantiate(cx, args))
|
||||
.collect()),
|
||||
|
||||
// For `PhantomData<T>`, we pass `T`.
|
||||
ty::Adt(def, args) if def.is_phantom_data() => Ok(vec![ty::Binder::dummy(args.type_at(0))]),
|
||||
|
||||
ty::Adt(def, args) => {
|
||||
Ok(def.all_field_tys(tcx).iter_instantiated(tcx, args).map(ty::Binder::dummy).collect())
|
||||
Ok(def.all_field_tys(cx).iter_instantiated(cx, args).map(ty::Binder::dummy).collect())
|
||||
}
|
||||
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
|
||||
// We can resolve the `impl Trait` to its concrete type,
|
||||
// which enforces a DAG between the functions requiring
|
||||
// the auto trait bounds in question.
|
||||
Ok(vec![ty::Binder::dummy(tcx.type_of(def_id).instantiate(tcx, args))])
|
||||
Ok(vec![ty::Binder::dummy(cx.type_of(def_id).instantiate(cx, args))])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -247,18 +247,18 @@ where
|
||||
|
||||
// Returns a binder of the tupled inputs types and output type from a builtin callable type.
|
||||
pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Interner>(
|
||||
tcx: I,
|
||||
cx: I,
|
||||
self_ty: I::Ty,
|
||||
goal_kind: ty::ClosureKind,
|
||||
) -> Result<Option<ty::Binder<I, (I::Ty, I::Ty)>>, NoSolution> {
|
||||
match self_ty.kind() {
|
||||
// keep this in sync with assemble_fn_pointer_candidates until the old solver is removed.
|
||||
ty::FnDef(def_id, args) => {
|
||||
let sig = tcx.fn_sig(def_id);
|
||||
if sig.skip_binder().is_fn_trait_compatible() && !tcx.has_target_features(def_id) {
|
||||
let sig = cx.fn_sig(def_id);
|
||||
if sig.skip_binder().is_fn_trait_compatible() && !cx.has_target_features(def_id) {
|
||||
Ok(Some(
|
||||
sig.instantiate(tcx, args)
|
||||
.map_bound(|sig| (Ty::new_tup(tcx, sig.inputs().as_slice()), sig.output())),
|
||||
sig.instantiate(cx, args)
|
||||
.map_bound(|sig| (Ty::new_tup(cx, sig.inputs().as_slice()), sig.output())),
|
||||
))
|
||||
} else {
|
||||
Err(NoSolution)
|
||||
@@ -268,7 +268,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
|
||||
ty::FnPtr(sig) => {
|
||||
if sig.is_fn_trait_compatible() {
|
||||
Ok(Some(
|
||||
sig.map_bound(|sig| (Ty::new_tup(tcx, sig.inputs().as_slice()), sig.output())),
|
||||
sig.map_bound(|sig| (Ty::new_tup(cx, sig.inputs().as_slice()), sig.output())),
|
||||
))
|
||||
} else {
|
||||
Err(NoSolution)
|
||||
@@ -323,10 +323,10 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
|
||||
}
|
||||
|
||||
coroutine_closure_to_certain_coroutine(
|
||||
tcx,
|
||||
cx,
|
||||
goal_kind,
|
||||
// No captures by ref, so this doesn't matter.
|
||||
Region::new_static(tcx),
|
||||
Region::new_static(cx),
|
||||
def_id,
|
||||
args,
|
||||
sig,
|
||||
@@ -339,9 +339,9 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
|
||||
}
|
||||
|
||||
coroutine_closure_to_ambiguous_coroutine(
|
||||
tcx,
|
||||
cx,
|
||||
goal_kind, // No captures by ref, so this doesn't matter.
|
||||
Region::new_static(tcx),
|
||||
Region::new_static(cx),
|
||||
def_id,
|
||||
args,
|
||||
sig,
|
||||
@@ -403,7 +403,7 @@ pub(in crate::solve) struct AsyncCallableRelevantTypes<I: Interner> {
|
||||
// which enforces the closure is actually callable with the given trait. When we
|
||||
// know the kind already, we can short-circuit this check.
|
||||
pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I: Interner>(
|
||||
tcx: I,
|
||||
cx: I,
|
||||
self_ty: I::Ty,
|
||||
goal_kind: ty::ClosureKind,
|
||||
env_region: I::Region,
|
||||
@@ -422,9 +422,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
coroutine_closure_to_certain_coroutine(
|
||||
tcx, goal_kind, env_region, def_id, args, sig,
|
||||
)
|
||||
coroutine_closure_to_certain_coroutine(cx, goal_kind, env_region, def_id, args, sig)
|
||||
} else {
|
||||
// When we don't know the closure kind (and therefore also the closure's upvars,
|
||||
// which are computed at the same time), we must delay the computation of the
|
||||
@@ -435,15 +433,15 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
|
||||
// coroutine upvars respecting the closure kind.
|
||||
nested.push(
|
||||
ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(TraitSolverLangItem::AsyncFnKindHelper),
|
||||
[kind_ty, Ty::from_closure_kind(tcx, goal_kind)],
|
||||
cx,
|
||||
cx.require_lang_item(TraitSolverLangItem::AsyncFnKindHelper),
|
||||
[kind_ty, Ty::from_closure_kind(cx, goal_kind)],
|
||||
)
|
||||
.upcast(tcx),
|
||||
.upcast(cx),
|
||||
);
|
||||
|
||||
coroutine_closure_to_ambiguous_coroutine(
|
||||
tcx, goal_kind, env_region, def_id, args, sig,
|
||||
cx, goal_kind, env_region, def_id, args, sig,
|
||||
)
|
||||
};
|
||||
|
||||
@@ -458,21 +456,21 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
|
||||
}
|
||||
|
||||
ty::FnDef(..) | ty::FnPtr(..) => {
|
||||
let bound_sig = self_ty.fn_sig(tcx);
|
||||
let bound_sig = self_ty.fn_sig(cx);
|
||||
let sig = bound_sig.skip_binder();
|
||||
let future_trait_def_id = tcx.require_lang_item(TraitSolverLangItem::Future);
|
||||
let future_trait_def_id = cx.require_lang_item(TraitSolverLangItem::Future);
|
||||
// `FnDef` and `FnPtr` only implement `AsyncFn*` when their
|
||||
// return type implements `Future`.
|
||||
let nested = vec![
|
||||
bound_sig
|
||||
.rebind(ty::TraitRef::new(tcx, future_trait_def_id, [sig.output()]))
|
||||
.upcast(tcx),
|
||||
.rebind(ty::TraitRef::new(cx, future_trait_def_id, [sig.output()]))
|
||||
.upcast(cx),
|
||||
];
|
||||
let future_output_def_id = tcx.require_lang_item(TraitSolverLangItem::FutureOutput);
|
||||
let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]);
|
||||
let future_output_def_id = cx.require_lang_item(TraitSolverLangItem::FutureOutput);
|
||||
let future_output_ty = Ty::new_projection(cx, future_output_def_id, [sig.output()]);
|
||||
Ok((
|
||||
bound_sig.rebind(AsyncCallableRelevantTypes {
|
||||
tupled_inputs_ty: Ty::new_tup(tcx, sig.inputs().as_slice()),
|
||||
tupled_inputs_ty: Ty::new_tup(cx, sig.inputs().as_slice()),
|
||||
output_coroutine_ty: sig.output(),
|
||||
coroutine_return_ty: future_output_ty,
|
||||
}),
|
||||
@@ -483,13 +481,13 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
|
||||
let args = args.as_closure();
|
||||
let bound_sig = args.sig();
|
||||
let sig = bound_sig.skip_binder();
|
||||
let future_trait_def_id = tcx.require_lang_item(TraitSolverLangItem::Future);
|
||||
let future_trait_def_id = cx.require_lang_item(TraitSolverLangItem::Future);
|
||||
// `Closure`s only implement `AsyncFn*` when their return type
|
||||
// implements `Future`.
|
||||
let mut nested = vec![
|
||||
bound_sig
|
||||
.rebind(ty::TraitRef::new(tcx, future_trait_def_id, [sig.output()]))
|
||||
.upcast(tcx),
|
||||
.rebind(ty::TraitRef::new(cx, future_trait_def_id, [sig.output()]))
|
||||
.upcast(cx),
|
||||
];
|
||||
|
||||
// Additionally, we need to check that the closure kind
|
||||
@@ -501,7 +499,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
|
||||
}
|
||||
} else {
|
||||
let async_fn_kind_trait_def_id =
|
||||
tcx.require_lang_item(TraitSolverLangItem::AsyncFnKindHelper);
|
||||
cx.require_lang_item(TraitSolverLangItem::AsyncFnKindHelper);
|
||||
// When we don't know the closure kind (and therefore also the closure's upvars,
|
||||
// which are computed at the same time), we must delay the computation of the
|
||||
// generator's upvars. We do this using the `AsyncFnKindHelper`, which as a trait
|
||||
@@ -511,16 +509,16 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
|
||||
// coroutine upvars respecting the closure kind.
|
||||
nested.push(
|
||||
ty::TraitRef::new(
|
||||
tcx,
|
||||
cx,
|
||||
async_fn_kind_trait_def_id,
|
||||
[kind_ty, Ty::from_closure_kind(tcx, goal_kind)],
|
||||
[kind_ty, Ty::from_closure_kind(cx, goal_kind)],
|
||||
)
|
||||
.upcast(tcx),
|
||||
.upcast(cx),
|
||||
);
|
||||
}
|
||||
|
||||
let future_output_def_id = tcx.require_lang_item(TraitSolverLangItem::FutureOutput);
|
||||
let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]);
|
||||
let future_output_def_id = cx.require_lang_item(TraitSolverLangItem::FutureOutput);
|
||||
let future_output_ty = Ty::new_projection(cx, future_output_def_id, [sig.output()]);
|
||||
Ok((
|
||||
bound_sig.rebind(AsyncCallableRelevantTypes {
|
||||
tupled_inputs_ty: sig.inputs().get(0).unwrap(),
|
||||
@@ -565,7 +563,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
|
||||
/// Given a coroutine-closure, project to its returned coroutine when we are *certain*
|
||||
/// that the closure's kind is compatible with the goal.
|
||||
fn coroutine_closure_to_certain_coroutine<I: Interner>(
|
||||
tcx: I,
|
||||
cx: I,
|
||||
goal_kind: ty::ClosureKind,
|
||||
goal_region: I::Region,
|
||||
def_id: I::DefId,
|
||||
@@ -573,9 +571,9 @@ fn coroutine_closure_to_certain_coroutine<I: Interner>(
|
||||
sig: ty::CoroutineClosureSignature<I>,
|
||||
) -> I::Ty {
|
||||
sig.to_coroutine_given_kind_and_upvars(
|
||||
tcx,
|
||||
cx,
|
||||
args.parent_args(),
|
||||
tcx.coroutine_for_closure(def_id),
|
||||
cx.coroutine_for_closure(def_id),
|
||||
goal_kind,
|
||||
goal_region,
|
||||
args.tupled_upvars_ty(),
|
||||
@@ -589,20 +587,20 @@ fn coroutine_closure_to_certain_coroutine<I: Interner>(
|
||||
///
|
||||
/// Note that we do not also push a `AsyncFnKindHelper` goal here.
|
||||
fn coroutine_closure_to_ambiguous_coroutine<I: Interner>(
|
||||
tcx: I,
|
||||
cx: I,
|
||||
goal_kind: ty::ClosureKind,
|
||||
goal_region: I::Region,
|
||||
def_id: I::DefId,
|
||||
args: ty::CoroutineClosureArgs<I>,
|
||||
sig: ty::CoroutineClosureSignature<I>,
|
||||
) -> I::Ty {
|
||||
let upvars_projection_def_id = tcx.require_lang_item(TraitSolverLangItem::AsyncFnKindUpvars);
|
||||
let upvars_projection_def_id = cx.require_lang_item(TraitSolverLangItem::AsyncFnKindUpvars);
|
||||
let tupled_upvars_ty = Ty::new_projection(
|
||||
tcx,
|
||||
cx,
|
||||
upvars_projection_def_id,
|
||||
[
|
||||
I::GenericArg::from(args.kind_ty()),
|
||||
Ty::from_closure_kind(tcx, goal_kind).into(),
|
||||
Ty::from_closure_kind(cx, goal_kind).into(),
|
||||
goal_region.into(),
|
||||
sig.tupled_inputs_ty.into(),
|
||||
args.tupled_upvars_ty().into(),
|
||||
@@ -610,10 +608,10 @@ fn coroutine_closure_to_ambiguous_coroutine<I: Interner>(
|
||||
],
|
||||
);
|
||||
sig.to_coroutine(
|
||||
tcx,
|
||||
cx,
|
||||
args.parent_args(),
|
||||
Ty::from_closure_kind(tcx, goal_kind),
|
||||
tcx.coroutine_for_closure(def_id),
|
||||
Ty::from_closure_kind(cx, goal_kind),
|
||||
cx.coroutine_for_closure(def_id),
|
||||
tupled_upvars_ty,
|
||||
)
|
||||
}
|
||||
@@ -668,28 +666,28 @@ where
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
let tcx = ecx.cx();
|
||||
let cx = ecx.cx();
|
||||
let mut requirements = vec![];
|
||||
requirements
|
||||
.extend(tcx.super_predicates_of(trait_ref.def_id).iter_instantiated(tcx, trait_ref.args));
|
||||
.extend(cx.super_predicates_of(trait_ref.def_id).iter_instantiated(cx, trait_ref.args));
|
||||
|
||||
// FIXME(associated_const_equality): Also add associated consts to
|
||||
// the requirements here.
|
||||
for associated_type_def_id in tcx.associated_type_def_ids(trait_ref.def_id) {
|
||||
for associated_type_def_id in cx.associated_type_def_ids(trait_ref.def_id) {
|
||||
// associated types that require `Self: Sized` do not show up in the built-in
|
||||
// implementation of `Trait for dyn Trait`, and can be dropped here.
|
||||
if tcx.generics_require_sized_self(associated_type_def_id) {
|
||||
if cx.generics_require_sized_self(associated_type_def_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
requirements
|
||||
.extend(tcx.item_bounds(associated_type_def_id).iter_instantiated(tcx, trait_ref.args));
|
||||
.extend(cx.item_bounds(associated_type_def_id).iter_instantiated(cx, trait_ref.args));
|
||||
}
|
||||
|
||||
let mut replace_projection_with = HashMap::default();
|
||||
for bound in object_bounds.iter() {
|
||||
if let ty::ExistentialPredicate::Projection(proj) = bound.skip_binder() {
|
||||
let proj = proj.with_self_ty(tcx, trait_ref.self_ty());
|
||||
let proj = proj.with_self_ty(cx, trait_ref.self_ty());
|
||||
let old_ty = replace_projection_with.insert(proj.def_id(), bound.rebind(proj));
|
||||
assert_eq!(
|
||||
old_ty,
|
||||
@@ -709,7 +707,7 @@ where
|
||||
folder
|
||||
.nested
|
||||
.into_iter()
|
||||
.chain(folded_requirements.into_iter().map(|clause| Goal::new(tcx, param_env, clause)))
|
||||
.chain(folded_requirements.into_iter().map(|clause| Goal::new(cx, param_env, clause)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user