Skip to content

Commit 3cd89f2

Browse files
authored
Rollup merge of #137689 - compiler-errors:coroutine, r=lcnr
Use `Binder<Vec<Ty>>` instead of `Vec<Binder<Ty>>` in both solvers for sized/auto traits/etc. It's more conceptually justified IMO, especially when binders get implications. r? lcnr
2 parents 174bbfb + ad74788 commit 3cd89f2

File tree

9 files changed

+97
-156
lines changed

9 files changed

+97
-156
lines changed

compiler/rustc_infer/src/infer/relate/higher_ranked.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//! the end of the file for details.
33
44
use rustc_middle::ty::fold::FnMutDelegate;
5+
use rustc_middle::ty::visit::TypeVisitableExt;
56
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
67
use tracing::{debug, instrument};
78

@@ -26,8 +27,9 @@ impl<'tcx> InferCtxt<'tcx> {
2627
where
2728
T: TypeFoldable<TyCtxt<'tcx>>,
2829
{
29-
if let Some(inner) = binder.clone().no_bound_vars() {
30-
return inner;
30+
// Inlined `no_bound_vars`.
31+
if !binder.as_ref().skip_binder().has_escaping_bound_vars() {
32+
return binder.skip_binder();
3133
}
3234

3335
let next_universe = self.create_next_universe();

compiler/rustc_middle/src/ty/context.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -324,11 +324,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
324324
self.features()
325325
}
326326

327-
fn bound_coroutine_hidden_types(
327+
fn coroutine_hidden_types(
328328
self,
329329
def_id: DefId,
330-
) -> impl IntoIterator<Item = ty::EarlyBinder<'tcx, ty::Binder<'tcx, Ty<'tcx>>>> {
331-
self.bound_coroutine_hidden_types(def_id)
330+
) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>>> {
331+
self.coroutine_hidden_types(def_id)
332332
}
333333

334334
fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {

compiler/rustc_middle/src/ty/util.rs

+26-40
Original file line numberDiff line numberDiff line change
@@ -739,52 +739,38 @@ impl<'tcx> TyCtxt<'tcx> {
739739
}
740740
}
741741

742-
/// Return the set of types that should be taken into account when checking
743-
/// trait bounds on a coroutine's internal state.
744-
// FIXME(compiler-errors): We should remove this when the old solver goes away;
745-
// and all other usages of this function should go through `bound_coroutine_hidden_types`
746-
// instead.
747-
pub fn coroutine_hidden_types(
748-
self,
749-
def_id: DefId,
750-
) -> impl Iterator<Item = ty::EarlyBinder<'tcx, Ty<'tcx>>> {
751-
let coroutine_layout = self.mir_coroutine_witnesses(def_id);
752-
coroutine_layout
753-
.as_ref()
754-
.map_or_else(|| [].iter(), |l| l.field_tys.iter())
755-
.filter(|decl| !decl.ignore_for_traits)
756-
.map(|decl| ty::EarlyBinder::bind(decl.ty))
757-
}
758-
759742
/// Return the set of types that should be taken into account when checking
760743
/// trait bounds on a coroutine's internal state. This properly replaces
761744
/// `ReErased` with new existential bound lifetimes.
762-
pub fn bound_coroutine_hidden_types(
745+
pub fn coroutine_hidden_types(
763746
self,
764747
def_id: DefId,
765-
) -> impl Iterator<Item = ty::EarlyBinder<'tcx, ty::Binder<'tcx, Ty<'tcx>>>> {
748+
) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>>> {
766749
let coroutine_layout = self.mir_coroutine_witnesses(def_id);
767-
coroutine_layout
768-
.as_ref()
769-
.map_or_else(|| [].iter(), |l| l.field_tys.iter())
770-
.filter(|decl| !decl.ignore_for_traits)
771-
.map(move |decl| {
772-
let mut vars = vec![];
773-
let ty = fold_regions(self, decl.ty, |re, debruijn| {
774-
assert_eq!(re, self.lifetimes.re_erased);
775-
let var = ty::BoundVar::from_usize(vars.len());
776-
vars.push(ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon));
777-
ty::Region::new_bound(
778-
self,
779-
debruijn,
780-
ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon },
781-
)
782-
});
783-
ty::EarlyBinder::bind(ty::Binder::bind_with_vars(
784-
ty,
785-
self.mk_bound_variable_kinds(&vars),
786-
))
787-
})
750+
let mut vars = vec![];
751+
let bound_tys = self.mk_type_list_from_iter(
752+
coroutine_layout
753+
.as_ref()
754+
.map_or_else(|| [].iter(), |l| l.field_tys.iter())
755+
.filter(|decl| !decl.ignore_for_traits)
756+
.map(|decl| {
757+
let ty = fold_regions(self, decl.ty, |re, debruijn| {
758+
assert_eq!(re, self.lifetimes.re_erased);
759+
let var = ty::BoundVar::from_usize(vars.len());
760+
vars.push(ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon));
761+
ty::Region::new_bound(
762+
self,
763+
debruijn,
764+
ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon },
765+
)
766+
});
767+
ty
768+
}),
769+
);
770+
ty::EarlyBinder::bind(ty::Binder::bind_with_vars(
771+
bound_tys,
772+
self.mk_bound_variable_kinds(&vars),
773+
))
788774
}
789775

790776
/// Expands the given impl trait type, stopping if the type is recursive.

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

+32-40
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::solve::{AdtDestructorKind, EvalCtxt, Goal, NoSolution};
1818
pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<D, I>(
1919
ecx: &EvalCtxt<'_, D>,
2020
ty: I::Ty,
21-
) -> Result<Vec<ty::Binder<I, I::Ty>>, NoSolution>
21+
) -> Result<ty::Binder<I, Vec<I::Ty>>, NoSolution>
2222
where
2323
D: SolverDelegate<Interner = I>,
2424
I: Interner,
@@ -33,10 +33,10 @@ where
3333
| ty::FnPtr(..)
3434
| ty::Error(_)
3535
| ty::Never
36-
| ty::Char => Ok(vec![]),
36+
| ty::Char => Ok(ty::Binder::dummy(vec![])),
3737

3838
// Treat `str` like it's defined as `struct str([u8]);`
39-
ty::Str => Ok(vec![ty::Binder::dummy(Ty::new_slice(cx, Ty::new_u8(cx)))]),
39+
ty::Str => Ok(ty::Binder::dummy(vec![Ty::new_slice(cx, Ty::new_u8(cx))])),
4040

4141
ty::Dynamic(..)
4242
| ty::Param(..)
@@ -49,53 +49,49 @@ where
4949
}
5050

5151
ty::RawPtr(element_ty, _) | ty::Ref(_, element_ty, _) => {
52-
Ok(vec![ty::Binder::dummy(element_ty)])
52+
Ok(ty::Binder::dummy(vec![element_ty]))
5353
}
5454

5555
ty::Pat(element_ty, _) | ty::Array(element_ty, _) | ty::Slice(element_ty) => {
56-
Ok(vec![ty::Binder::dummy(element_ty)])
56+
Ok(ty::Binder::dummy(vec![element_ty]))
5757
}
5858

5959
ty::Tuple(tys) => {
6060
// (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
61-
Ok(tys.iter().map(ty::Binder::dummy).collect())
61+
Ok(ty::Binder::dummy(tys.to_vec()))
6262
}
6363

64-
ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]),
64+
ty::Closure(_, args) => Ok(ty::Binder::dummy(vec![args.as_closure().tupled_upvars_ty()])),
6565

6666
ty::CoroutineClosure(_, args) => {
67-
Ok(vec![ty::Binder::dummy(args.as_coroutine_closure().tupled_upvars_ty())])
67+
Ok(ty::Binder::dummy(vec![args.as_coroutine_closure().tupled_upvars_ty()]))
6868
}
6969

7070
ty::Coroutine(_, args) => {
7171
let coroutine_args = args.as_coroutine();
72-
Ok(vec![
73-
ty::Binder::dummy(coroutine_args.tupled_upvars_ty()),
74-
ty::Binder::dummy(coroutine_args.witness()),
75-
])
72+
Ok(ty::Binder::dummy(vec![coroutine_args.tupled_upvars_ty(), coroutine_args.witness()]))
7673
}
7774

7875
ty::CoroutineWitness(def_id, args) => Ok(ecx
7976
.cx()
80-
.bound_coroutine_hidden_types(def_id)
81-
.into_iter()
82-
.map(|bty| bty.instantiate(cx, args))
83-
.collect()),
77+
.coroutine_hidden_types(def_id)
78+
.instantiate(cx, args)
79+
.map_bound(|tys| tys.to_vec())),
8480

85-
ty::UnsafeBinder(bound_ty) => Ok(vec![bound_ty.into()]),
81+
ty::UnsafeBinder(bound_ty) => Ok(bound_ty.map_bound(|ty| vec![ty])),
8682

8783
// For `PhantomData<T>`, we pass `T`.
88-
ty::Adt(def, args) if def.is_phantom_data() => Ok(vec![ty::Binder::dummy(args.type_at(0))]),
84+
ty::Adt(def, args) if def.is_phantom_data() => Ok(ty::Binder::dummy(vec![args.type_at(0)])),
8985

9086
ty::Adt(def, args) => {
91-
Ok(def.all_field_tys(cx).iter_instantiated(cx, args).map(ty::Binder::dummy).collect())
87+
Ok(ty::Binder::dummy(def.all_field_tys(cx).iter_instantiated(cx, args).collect()))
9288
}
9389

9490
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
9591
// We can resolve the `impl Trait` to its concrete type,
9692
// which enforces a DAG between the functions requiring
9793
// the auto trait bounds in question.
98-
Ok(vec![ty::Binder::dummy(cx.type_of(def_id).instantiate(cx, args))])
94+
Ok(ty::Binder::dummy(vec![cx.type_of(def_id).instantiate(cx, args)]))
9995
}
10096
}
10197
}
@@ -104,7 +100,7 @@ where
104100
pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<D, I>(
105101
ecx: &EvalCtxt<'_, D>,
106102
ty: I::Ty,
107-
) -> Result<Vec<ty::Binder<I, I::Ty>>, NoSolution>
103+
) -> Result<ty::Binder<I, Vec<I::Ty>>, NoSolution>
108104
where
109105
D: SolverDelegate<Interner = I>,
110106
I: Interner,
@@ -130,7 +126,7 @@ where
130126
| ty::CoroutineClosure(..)
131127
| ty::Never
132128
| ty::Dynamic(_, _, ty::DynStar)
133-
| ty::Error(_) => Ok(vec![]),
129+
| ty::Error(_) => Ok(ty::Binder::dummy(vec![])),
134130

135131
ty::Str
136132
| ty::Slice(_)
@@ -145,11 +141,11 @@ where
145141
panic!("unexpected type `{ty:?}`")
146142
}
147143

148-
ty::UnsafeBinder(bound_ty) => Ok(vec![bound_ty.into()]),
144+
ty::UnsafeBinder(bound_ty) => Ok(bound_ty.map_bound(|ty| vec![ty])),
149145

150146
// impl Sized for ()
151147
// impl Sized for (T1, T2, .., Tn) where Tn: Sized if n >= 1
152-
ty::Tuple(tys) => Ok(tys.last().map_or_else(Vec::new, |ty| vec![ty::Binder::dummy(ty)])),
148+
ty::Tuple(tys) => Ok(ty::Binder::dummy(tys.last().map_or_else(Vec::new, |ty| vec![ty]))),
153149

154150
// impl Sized for Adt<Args...> where sized_constraint(Adt)<Args...>: Sized
155151
// `sized_constraint(Adt)` is the deepest struct trail that can be determined
@@ -162,9 +158,9 @@ where
162158
// if the ADT is sized for all possible args.
163159
ty::Adt(def, args) => {
164160
if let Some(sized_crit) = def.sized_constraint(ecx.cx()) {
165-
Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.cx(), args))])
161+
Ok(ty::Binder::dummy(vec![sized_crit.instantiate(ecx.cx(), args)]))
166162
} else {
167-
Ok(vec![])
163+
Ok(ty::Binder::dummy(vec![]))
168164
}
169165
}
170166
}
@@ -174,14 +170,14 @@ where
174170
pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<D, I>(
175171
ecx: &EvalCtxt<'_, D>,
176172
ty: I::Ty,
177-
) -> Result<Vec<ty::Binder<I, I::Ty>>, NoSolution>
173+
) -> Result<ty::Binder<I, Vec<I::Ty>>, NoSolution>
178174
where
179175
D: SolverDelegate<Interner = I>,
180176
I: Interner,
181177
{
182178
match ty.kind() {
183179
// impl Copy/Clone for FnDef, FnPtr
184-
ty::FnDef(..) | ty::FnPtr(..) | ty::Error(_) => Ok(vec![]),
180+
ty::FnDef(..) | ty::FnPtr(..) | ty::Error(_) => Ok(ty::Binder::dummy(vec![])),
185181

186182
// Implementations are provided in core
187183
ty::Uint(_)
@@ -197,7 +193,7 @@ where
197193

198194
// Cannot implement in core, as we can't be generic over patterns yet,
199195
// so we'd have to list all patterns and type combinations.
200-
ty::Pat(ty, ..) => Ok(vec![ty::Binder::dummy(ty)]),
196+
ty::Pat(ty, ..) => Ok(ty::Binder::dummy(vec![ty])),
201197

202198
ty::Dynamic(..)
203199
| ty::Str
@@ -215,14 +211,14 @@ where
215211
}
216212

217213
// impl Copy/Clone for (T1, T2, .., Tn) where T1: Copy/Clone, T2: Copy/Clone, .. Tn: Copy/Clone
218-
ty::Tuple(tys) => Ok(tys.iter().map(ty::Binder::dummy).collect()),
214+
ty::Tuple(tys) => Ok(ty::Binder::dummy(tys.to_vec())),
219215

220216
// impl Copy/Clone for Closure where Self::TupledUpvars: Copy/Clone
221-
ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]),
217+
ty::Closure(_, args) => Ok(ty::Binder::dummy(vec![args.as_closure().tupled_upvars_ty()])),
222218

223219
// impl Copy/Clone for CoroutineClosure where Self::TupledUpvars: Copy/Clone
224220
ty::CoroutineClosure(_, args) => {
225-
Ok(vec![ty::Binder::dummy(args.as_coroutine_closure().tupled_upvars_ty())])
221+
Ok(ty::Binder::dummy(vec![args.as_coroutine_closure().tupled_upvars_ty()]))
226222
}
227223

228224
// only when `coroutine_clone` is enabled and the coroutine is movable
@@ -232,10 +228,7 @@ where
232228
Movability::Movable => {
233229
if ecx.cx().features().coroutine_clone() {
234230
let coroutine = args.as_coroutine();
235-
Ok(vec![
236-
ty::Binder::dummy(coroutine.tupled_upvars_ty()),
237-
ty::Binder::dummy(coroutine.witness()),
238-
])
231+
Ok(ty::Binder::dummy(vec![coroutine.tupled_upvars_ty(), coroutine.witness()]))
239232
} else {
240233
Err(NoSolution)
241234
}
@@ -247,10 +240,9 @@ where
247240
// impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types
248241
ty::CoroutineWitness(def_id, args) => Ok(ecx
249242
.cx()
250-
.bound_coroutine_hidden_types(def_id)
251-
.into_iter()
252-
.map(|bty| bty.instantiate(ecx.cx(), args))
253-
.collect()),
243+
.coroutine_hidden_types(def_id)
244+
.instantiate(ecx.cx(), args)
245+
.map_bound(|tys| tys.to_vec())),
254246
}
255247
}
256248

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -967,7 +967,7 @@ where
967967

968968
/// `enter_forall`, but takes `&mut self` and passes it back through the
969969
/// callback since it can't be aliased during the call.
970-
pub(super) fn enter_forall<T: TypeFoldable<I> + Copy, U>(
970+
pub(super) fn enter_forall<T: TypeFoldable<I>, U>(
971971
&mut self,
972972
value: ty::Binder<I, T>,
973973
f: impl FnOnce(&mut Self, T) -> U,

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -1239,17 +1239,15 @@ where
12391239
constituent_tys: impl Fn(
12401240
&EvalCtxt<'_, D>,
12411241
I::Ty,
1242-
) -> Result<Vec<ty::Binder<I, I::Ty>>, NoSolution>,
1242+
) -> Result<ty::Binder<I, Vec<I::Ty>>, NoSolution>,
12431243
) -> Result<Candidate<I>, NoSolution> {
12441244
self.probe_trait_candidate(source).enter(|ecx| {
1245-
let goals = constituent_tys(ecx, goal.predicate.self_ty())?
1246-
.into_iter()
1247-
.map(|ty| {
1248-
ecx.enter_forall(ty, |ecx, ty| {
1249-
goal.with(ecx.cx(), goal.predicate.with_self_ty(ecx.cx(), ty))
1250-
})
1251-
})
1252-
.collect::<Vec<_>>();
1245+
let goals =
1246+
ecx.enter_forall(constituent_tys(ecx, goal.predicate.self_ty())?, |ecx, tys| {
1247+
tys.into_iter()
1248+
.map(|ty| goal.with(ecx.cx(), goal.predicate.with_self_ty(ecx.cx(), ty)))
1249+
.collect::<Vec<_>>()
1250+
});
12531251
ecx.add_goals(GoalSource::ImplWhereBound, goals);
12541252
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
12551253
})

0 commit comments

Comments
 (0)