Skip to content

Commit a04ad8c

Browse files
Do binder folding eagerly in bound_coroutine_hidden_types
I refuse to fix this in the old solver; its lazy instantiation of binders will be the end of me.
1 parent a85dbfb commit a04ad8c

File tree

3 files changed

+33
-33
lines changed

3 files changed

+33
-33
lines changed

compiler/rustc_middle/src/ty/util.rs

+27
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,33 @@ impl<'tcx> TyCtxt<'tcx> {
690690
.map(|decl| ty::EarlyBinder::bind(decl.ty))
691691
}
692692

693+
/// Return the set of types that should be taken into account when checking
694+
/// trait bounds on a coroutine's internal state. This properly replaces
695+
/// `ReErased` with new existential bound lifetimes.
696+
pub fn bound_coroutine_hidden_types(
697+
self,
698+
def_id: DefId,
699+
) -> impl Iterator<Item = ty::EarlyBinder<ty::Binder<'tcx, Ty<'tcx>>>> {
700+
let coroutine_layout = self.mir_coroutine_witnesses(def_id);
701+
coroutine_layout
702+
.as_ref()
703+
.map_or_else(|| [].iter(), |l| l.field_tys.iter())
704+
.filter(|decl| !decl.ignore_for_traits)
705+
.map(move |decl| {
706+
let mut vars = vec![];
707+
let ty = self.fold_regions(decl.ty, |re, debruijn| {
708+
assert_eq!(re, self.lifetimes.re_erased);
709+
let var = ty::BoundVar::from_usize(vars.len());
710+
vars.push(ty::BoundVariableKind::Region(ty::BrAnon));
711+
ty::Region::new_bound(self, debruijn, ty::BoundRegion { var, kind: ty::BrAnon })
712+
});
713+
ty::EarlyBinder::bind(ty::Binder::bind_with_vars(
714+
ty,
715+
self.mk_bound_variable_kinds(&vars),
716+
))
717+
})
718+
}
719+
693720
/// Expands the given impl trait type, stopping if the type is recursive.
694721
#[instrument(skip(self), level = "debug", ret)]
695722
pub fn try_expand_impl_trait_type(

compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs

+4-29
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
7373

7474
ty::CoroutineWitness(def_id, args) => Ok(ecx
7575
.tcx()
76-
.coroutine_hidden_types(def_id)
77-
.map(|bty| replace_erased_lifetimes_with_bound_vars(tcx, bty.instantiate(tcx, args)))
76+
.bound_coroutine_hidden_types(def_id)
77+
.map(|bty| bty.instantiate(tcx, args))
7878
.collect()),
7979

8080
// For `PhantomData<T>`, we pass `T`.
@@ -93,26 +93,6 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
9393
}
9494
}
9595

96-
pub(in crate::solve) fn replace_erased_lifetimes_with_bound_vars<'tcx>(
97-
tcx: TyCtxt<'tcx>,
98-
ty: Ty<'tcx>,
99-
) -> ty::Binder<'tcx, Ty<'tcx>> {
100-
let mut counter = 0;
101-
let ty = tcx.fold_regions(ty, |r, current_depth| match r.kind() {
102-
ty::ReErased => {
103-
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(counter), kind: ty::BrAnon };
104-
counter += 1;
105-
ty::Region::new_bound(tcx, current_depth, br)
106-
}
107-
// All free regions should be erased here.
108-
r => bug!("unexpected region: {r:?}"),
109-
});
110-
let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
111-
(0..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon)),
112-
);
113-
ty::Binder::bind_with_vars(ty, bound_vars)
114-
}
115-
11696
#[instrument(level = "debug", skip(ecx), ret)]
11797
pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
11898
ecx: &EvalCtxt<'_, 'tcx>,
@@ -218,13 +198,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
218198

219199
ty::CoroutineWitness(def_id, args) => Ok(ecx
220200
.tcx()
221-
.coroutine_hidden_types(def_id)
222-
.map(|bty| {
223-
replace_erased_lifetimes_with_bound_vars(
224-
ecx.tcx(),
225-
bty.instantiate(ecx.tcx(), args),
226-
)
227-
})
201+
.bound_coroutine_hidden_types(def_id)
202+
.map(|bty| bty.instantiate(tcx, args))
228203
.collect()),
229204
}
230205
}

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1425,10 +1425,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
14251425
}
14261426
ty::CoroutineWitness(def_id, args) => {
14271427
let tcx = self.tcx();
1428-
stack.extend(tcx.coroutine_hidden_types(def_id).map(|bty| {
1429-
let ty = bty.instantiate(tcx, args);
1430-
debug_assert!(!ty.has_bound_regions());
1431-
ty
1428+
stack.extend(tcx.bound_coroutine_hidden_types(def_id).map(|bty| {
1429+
self.infcx.enter_forall_and_leak_universe(bty.instantiate(tcx, args))
14321430
}))
14331431
}
14341432

0 commit comments

Comments
 (0)