Skip to content

Commit 88f19a7

Browse files
committed
Auto merge of #57355 - arielb1:correct-subst, r=nikomatsakis
use the correct supertrait substitution in `object_ty_for_trait` beta-nominating because regression. Fixes #57156.
2 parents 729d3f0 + 85c4b4c commit 88f19a7

File tree

2 files changed

+47
-9
lines changed

2 files changed

+47
-9
lines changed

src/librustc/traits/object_safety.rs

+24-9
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
252252
method: &ty::AssociatedItem)
253253
-> Option<MethodViolationCode>
254254
{
255+
debug!("object_safety_violation_for_method({:?}, {:?})", trait_def_id, method);
255256
// Any method that has a `Self : Sized` requisite is otherwise
256257
// exempt from the regulations.
257258
if self.generics_require_sized_self(method.def_id) {
@@ -270,6 +271,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
270271
method: &ty::AssociatedItem)
271272
-> bool
272273
{
274+
debug!("is_vtable_safe_method({:?}, {:?})", trait_def_id, method);
273275
// Any method that has a `Self : Sized` requisite can't be called.
274276
if self.generics_require_sized_self(method.def_id) {
275277
return false;
@@ -402,6 +404,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
402404
fn receiver_for_self_ty(
403405
self, receiver_ty: Ty<'tcx>, self_ty: Ty<'tcx>, method_def_id: DefId
404406
) -> Ty<'tcx> {
407+
debug!("receiver_for_self_ty({:?}, {:?}, {:?})", receiver_ty, self_ty, method_def_id);
405408
let substs = Substs::for_item(self, method_def_id, |param, _| {
406409
if param.index == 0 {
407410
self_ty.into()
@@ -410,7 +413,10 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
410413
}
411414
});
412415

413-
receiver_ty.subst(self, substs)
416+
let result = receiver_ty.subst(self, substs);
417+
debug!("receiver_for_self_ty({:?}, {:?}, {:?}) = {:?}",
418+
receiver_ty, self_ty, method_def_id, result);
419+
result
414420
}
415421

416422
/// creates the object type for the current trait. For example,
@@ -426,18 +432,26 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
426432
);
427433

428434
let mut associated_types = traits::supertraits(self, ty::Binder::dummy(trait_ref))
429-
.flat_map(|trait_ref| self.associated_items(trait_ref.def_id()))
430-
.filter(|item| item.kind == ty::AssociatedKind::Type)
435+
.flat_map(|super_trait_ref| {
436+
self.associated_items(super_trait_ref.def_id())
437+
.map(move |item| (super_trait_ref, item))
438+
})
439+
.filter(|(_, item)| item.kind == ty::AssociatedKind::Type)
431440
.collect::<Vec<_>>();
432441

433442
// existential predicates need to be in a specific order
434-
associated_types.sort_by_cached_key(|item| self.def_path_hash(item.def_id));
435-
436-
let projection_predicates = associated_types.into_iter().map(|item| {
443+
associated_types.sort_by_cached_key(|(_, item)| self.def_path_hash(item.def_id));
444+
445+
let projection_predicates = associated_types.into_iter().map(|(super_trait_ref, item)| {
446+
// We *can* get bound lifetimes here in cases like
447+
// `trait MyTrait: for<'s> OtherTrait<&'s T, Output=bool>`.
448+
//
449+
// binder moved to (*)...
450+
let super_trait_ref = super_trait_ref.skip_binder();
437451
ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
438-
ty: self.mk_projection(item.def_id, trait_ref.substs),
452+
ty: self.mk_projection(item.def_id, super_trait_ref.substs),
439453
item_def_id: item.def_id,
440-
substs: trait_ref.substs,
454+
substs: super_trait_ref.substs,
441455
})
442456
});
443457

@@ -446,7 +460,8 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
446460
);
447461

448462
let object_ty = self.mk_dynamic(
449-
ty::Binder::dummy(existential_predicates),
463+
// (*) ... binder re-introduced here
464+
ty::Binder::bind(existential_predicates),
450465
lifetime,
451466
);
452467

src/test/ui/issues/issue-57156.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// compile-pass
2+
3+
trait Foo<Args> {
4+
type Output;
5+
}
6+
7+
trait Bar<'a, T>: for<'s> Foo<&'s T, Output=bool> {
8+
fn cb(&self) -> Box<dyn Bar<'a, T, Output=bool>>;
9+
}
10+
11+
impl<'s> Foo<&'s ()> for () {
12+
type Output = bool;
13+
}
14+
15+
impl<'a> Bar<'a, ()> for () {
16+
fn cb(&self) -> Box<dyn Bar<'a, (), Output=bool>> {
17+
Box::new(*self)
18+
}
19+
}
20+
21+
fn main() {
22+
let _t = ().cb();
23+
}

0 commit comments

Comments
 (0)