Skip to content

Commit ac9d9e7

Browse files
authored
Rollup merge of rust-lang#109240 - compiler-errors:dont-binder-twice, r=oli-obk
Walk un-shifted nested `impl Trait` in trait when setting up default trait method assumptions Fixes a double subtraction in some binder math in return-position `impl Trait` in trait handling code. Fixes rust-lang#109239
2 parents 6dbd539 + 239ec6c commit ac9d9e7

File tree

3 files changed

+33
-30
lines changed

3 files changed

+33
-30
lines changed

compiler/rustc_middle/src/ty/fold.rs

+1-14
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,7 @@ where
5151
// Region folder
5252

5353
impl<'tcx> TyCtxt<'tcx> {
54-
/// Folds the escaping and free regions in `value` using `f`, and
55-
/// sets `skipped_regions` to true if any late-bound region was found
56-
/// and skipped.
54+
/// Folds the escaping and free regions in `value` using `f`.
5755
pub fn fold_regions<T>(
5856
self,
5957
value: T,
@@ -64,17 +62,6 @@ impl<'tcx> TyCtxt<'tcx> {
6462
{
6563
value.fold_with(&mut RegionFolder::new(self, &mut f))
6664
}
67-
68-
pub fn super_fold_regions<T>(
69-
self,
70-
value: T,
71-
mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
72-
) -> T
73-
where
74-
T: TypeSuperFoldable<TyCtxt<'tcx>>,
75-
{
76-
value.super_fold_with(&mut RegionFolder::new(self, &mut f))
77-
}
7865
}
7966

8067
/// Folds over the substructure of a type, visiting its component

compiler/rustc_ty_utils/src/ty.rs

+26-16
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ use rustc_middle::ty::{
77
TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor,
88
};
99
use rustc_session::config::TraitSolver;
10-
use rustc_span::def_id::{DefId, CRATE_DEF_ID};
10+
use rustc_span::{
11+
def_id::{DefId, CRATE_DEF_ID},
12+
DUMMY_SP,
13+
};
1114
use rustc_trait_selection::traits;
1215

1316
fn sized_constraint_for_ty<'tcx>(
@@ -275,16 +278,22 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
275278
}
276279

277280
fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> {
278-
if let ty::Alias(ty::Projection, alias_ty) = *ty.kind()
279-
&& self.tcx.is_impl_trait_in_trait(alias_ty.def_id)
280-
&& self.tcx.impl_trait_in_trait_parent_fn(alias_ty.def_id) == self.fn_def_id
281-
&& self.seen.insert(alias_ty.def_id)
281+
if let ty::Alias(ty::Projection, unshifted_alias_ty) = *ty.kind()
282+
&& self.tcx.is_impl_trait_in_trait(unshifted_alias_ty.def_id)
283+
&& self.tcx.impl_trait_in_trait_parent_fn(unshifted_alias_ty.def_id) == self.fn_def_id
284+
&& self.seen.insert(unshifted_alias_ty.def_id)
282285
{
283286
// We have entered some binders as we've walked into the
284287
// bounds of the RPITIT. Shift these binders back out when
285288
// constructing the top-level projection predicate.
286-
let alias_ty = self.tcx.fold_regions(alias_ty, |re, _| {
289+
let shifted_alias_ty = self.tcx.fold_regions(unshifted_alias_ty, |re, depth| {
287290
if let ty::ReLateBound(index, bv) = re.kind() {
291+
if depth != ty::INNERMOST {
292+
return self.tcx.mk_re_error_with_message(
293+
DUMMY_SP,
294+
"we shouldn't walk non-predicate binders with `impl Trait`...",
295+
);
296+
}
288297
self.tcx.mk_re_late_bound(index.shifted_out_to_binder(self.depth), bv)
289298
} else {
290299
re
@@ -295,26 +304,27 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
295304
// the `type_of` of the trait's associated item. If we're using the old lowering
296305
// strategy, then just reinterpret the associated type like an opaque :^)
297306
let default_ty = if self.tcx.lower_impl_trait_in_trait_to_assoc_ty() {
298-
self
299-
.tcx
300-
.type_of(alias_ty.def_id)
301-
.subst(self.tcx, alias_ty.substs)
307+
self.tcx.type_of(shifted_alias_ty.def_id).subst(self.tcx, shifted_alias_ty.substs)
302308
} else {
303-
self.tcx.mk_alias(ty::Opaque, alias_ty)
309+
self.tcx.mk_alias(ty::Opaque, shifted_alias_ty)
304310
};
305311

306312
self.predicates.push(
307313
ty::Binder::bind_with_vars(
308-
ty::ProjectionPredicate {
309-
projection_ty: alias_ty,
310-
term: default_ty.into(),
311-
},
314+
ty::ProjectionPredicate { projection_ty: shifted_alias_ty, term: default_ty.into() },
312315
self.bound_vars,
313316
)
314317
.to_predicate(self.tcx),
315318
);
316319

317-
for bound in self.tcx.item_bounds(alias_ty.def_id).subst_iter(self.tcx, alias_ty.substs)
320+
// We walk the *un-shifted* alias ty, because we're tracking the de bruijn
321+
// binder depth, and if we were to walk `shifted_alias_ty` instead, we'd
322+
// have to reset `self.depth` back to `ty::INNERMOST` or something. It's
323+
// easier to just do this.
324+
for bound in self
325+
.tcx
326+
.item_bounds(unshifted_alias_ty.def_id)
327+
.subst_iter(self.tcx, unshifted_alias_ty.substs)
318328
{
319329
bound.visit_with(self);
320330
}

tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs

+6
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,10 @@ trait Trait {
1313
fn method(&self) -> impl Trait<Type = impl Sized + '_>;
1414
}
1515

16+
trait Trait2 {
17+
type Type;
18+
19+
fn method(&self) -> impl Trait2<Type = impl Trait2<Type = impl Sized + '_> + '_>;
20+
}
21+
1622
fn main() {}

0 commit comments

Comments
 (0)