Skip to content

Commit e78522f

Browse files
authored
Rollup merge of #122358 - compiler-errors:bound-regions-in-generator, r=lcnr
Don't ICE when encountering bound regions in generator interior type I'm pretty sure this meant to say "`has_free_regions`", probably just a typo in 4a4fc3b. We can have bound regions (because we only convert non-bound regions into existential regions in generator interiors), but we can't have (non-ReErased) free regions. r? lcnr
2 parents 0867025 + bca708b commit e78522f

File tree

4 files changed

+45
-38
lines changed

4 files changed

+45
-38
lines changed

compiler/rustc_middle/src/ty/util.rs

+34-2
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,9 @@ impl<'tcx> TyCtxt<'tcx> {
682682

683683
/// Return the set of types that should be taken into account when checking
684684
/// trait bounds on a coroutine's internal state.
685+
// FIXME(compiler-errors): We should remove this when the old solver goes away;
686+
// and all other usages of this function should go through `bound_coroutine_hidden_types`
687+
// instead.
685688
pub fn coroutine_hidden_types(
686689
self,
687690
def_id: DefId,
@@ -694,6 +697,33 @@ impl<'tcx> TyCtxt<'tcx> {
694697
.map(|decl| ty::EarlyBinder::bind(decl.ty))
695698
}
696699

700+
/// Return the set of types that should be taken into account when checking
701+
/// trait bounds on a coroutine's internal state. This properly replaces
702+
/// `ReErased` with new existential bound lifetimes.
703+
pub fn bound_coroutine_hidden_types(
704+
self,
705+
def_id: DefId,
706+
) -> impl Iterator<Item = ty::EarlyBinder<ty::Binder<'tcx, Ty<'tcx>>>> {
707+
let coroutine_layout = self.mir_coroutine_witnesses(def_id);
708+
coroutine_layout
709+
.as_ref()
710+
.map_or_else(|| [].iter(), |l| l.field_tys.iter())
711+
.filter(|decl| !decl.ignore_for_traits)
712+
.map(move |decl| {
713+
let mut vars = vec![];
714+
let ty = self.fold_regions(decl.ty, |re, debruijn| {
715+
assert_eq!(re, self.lifetimes.re_erased);
716+
let var = ty::BoundVar::from_usize(vars.len());
717+
vars.push(ty::BoundVariableKind::Region(ty::BrAnon));
718+
ty::Region::new_bound(self, debruijn, ty::BoundRegion { var, kind: ty::BrAnon })
719+
});
720+
ty::EarlyBinder::bind(ty::Binder::bind_with_vars(
721+
ty,
722+
self.mk_bound_variable_kinds(&vars),
723+
))
724+
})
725+
}
726+
697727
/// Expands the given impl trait type, stopping if the type is recursive.
698728
#[instrument(skip(self), level = "debug", ret)]
699729
pub fn try_expand_impl_trait_type(
@@ -998,8 +1028,10 @@ impl<'tcx> OpaqueTypeExpander<'tcx> {
9981028
Some(expanded_ty) => *expanded_ty,
9991029
None => {
10001030
if matches!(self.inspect_coroutine_fields, InspectCoroutineFields::Yes) {
1001-
for bty in self.tcx.coroutine_hidden_types(def_id) {
1002-
let hidden_ty = bty.instantiate(self.tcx, args);
1031+
for bty in self.tcx.bound_coroutine_hidden_types(def_id) {
1032+
let hidden_ty = self.tcx.instantiate_bound_regions_with_erased(
1033+
bty.instantiate(self.tcx, args),
1034+
);
10031035
self.fold_ty(hidden_ty);
10041036
}
10051037
}

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

+5-31
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_hir::{def_id::DefId, Movability, Mutability};
66
use rustc_infer::traits::query::NoSolution;
77
use rustc_middle::traits::solve::Goal;
88
use rustc_middle::ty::{
9-
self, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
9+
self, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
1010
};
1111
use rustc_span::sym;
1212

@@ -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,27 +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-
debug_assert!(!ty.has_bound_regions());
101-
let mut counter = 0;
102-
let ty = tcx.fold_regions(ty, |r, current_depth| match r.kind() {
103-
ty::ReErased => {
104-
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(counter), kind: ty::BrAnon };
105-
counter += 1;
106-
ty::Region::new_bound(tcx, current_depth, br)
107-
}
108-
// All free regions should be erased here.
109-
r => bug!("unexpected region: {r:?}"),
110-
});
111-
let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
112-
(0..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon)),
113-
);
114-
ty::Binder::bind_with_vars(ty, bound_vars)
115-
}
116-
11796
#[instrument(level = "debug", skip(ecx), ret)]
11897
pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
11998
ecx: &EvalCtxt<'_, 'tcx>,
@@ -241,13 +220,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
241220
// impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types
242221
ty::CoroutineWitness(def_id, args) => Ok(ecx
243222
.tcx()
244-
.coroutine_hidden_types(def_id)
245-
.map(|bty| {
246-
replace_erased_lifetimes_with_bound_vars(
247-
ecx.tcx(),
248-
bty.instantiate(ecx.tcx(), args),
249-
)
250-
})
223+
.bound_coroutine_hidden_types(def_id)
224+
.map(|bty| bty.instantiate(ecx.tcx(), args))
251225
.collect()),
252226
}
253227
}

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

+3-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
1414
use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData};
1515
use rustc_middle::ty::{
1616
self, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, ToPredicate,
17-
TraitPredicate, Ty, TyCtxt, TypeVisitableExt,
17+
TraitPredicate, Ty, TyCtxt,
1818
};
1919
use rustc_span::def_id::DefId;
2020

@@ -1438,10 +1438,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
14381438
}
14391439
ty::CoroutineWitness(def_id, args) => {
14401440
let tcx = self.tcx();
1441-
stack.extend(tcx.coroutine_hidden_types(def_id).map(|bty| {
1442-
let ty = bty.instantiate(tcx, args);
1443-
debug_assert!(!ty.has_bound_regions());
1444-
ty
1441+
stack.extend(tcx.bound_coroutine_hidden_types(def_id).map(|bty| {
1442+
self.infcx.enter_forall_and_leak_universe(bty.instantiate(tcx, args))
14451443
}))
14461444
}
14471445

tests/ui/async-await/send-bound-async-closure.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
//@ edition: 2021
22
//@ check-pass
3+
//@ revisions: current next
4+
//@ ignore-compare-mode-next-solver (explicit revisions)
5+
//@[next] compile-flags: -Znext-solver
36

47
// This test verifies that we do not create a query cycle when typechecking has several inference
58
// variables that point to the same coroutine interior type.

0 commit comments

Comments
 (0)