Skip to content

Commit 83fb0ff

Browse files
Ensure that we never try to monomorphize the upcasting of impossible dyn types
1 parent 8a460d3 commit 83fb0ff

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

compiler/rustc_trait_selection/src/traits/vtable.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ fn vtable_entries<'tcx>(
234234
"vtable trait ref should be normalized"
235235
);
236236

237+
// We're monomorphizing a dyn trait object that can never be constructed.
238+
if tcx.instantiate_and_check_impossible_predicates((trait_ref.def_id, trait_ref.args)) {
239+
return TyCtxt::COMMON_VTABLE_ENTRIES;
240+
}
241+
237242
debug!("vtable_entries({:?})", trait_ref);
238243

239244
let mut entries = vec![];
@@ -323,6 +328,14 @@ pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRe
323328
source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self),
324329
);
325330

331+
// We're monomorphizing a dyn trait object that can never be constructed.
332+
if tcx.instantiate_and_check_impossible_predicates((
333+
source_principal.def_id,
334+
source_principal.args,
335+
)) {
336+
return 0;
337+
}
338+
326339
let target_principal = ty::ExistentialTraitRef::erase_self_ty(tcx, key);
327340

328341
let vtable_segment_callback = {
@@ -388,6 +401,14 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
388401
source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self),
389402
);
390403

404+
// We're monomorphizing a dyn trait object that can never be constructed.
405+
if tcx.instantiate_and_check_impossible_predicates((
406+
source_principal.def_id,
407+
source_principal.args,
408+
)) {
409+
return None;
410+
}
411+
391412
let vtable_segment_callback = {
392413
let mut vptr_offset = 0;
393414
move |segment| {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#![feature(trait_upcasting)]
2+
3+
trait Supertrait<T> {
4+
fn method(&self) {}
5+
}
6+
impl<T> Supertrait<T> for () {}
7+
8+
trait WithAssoc {
9+
type Assoc;
10+
}
11+
trait Trait<P: WithAssoc>: Supertrait<P::Assoc> + Supertrait<()> {}
12+
13+
fn upcast<P>(x: &dyn Trait<P>) -> &dyn Supertrait<()> {
14+
x
15+
}
16+
17+
fn call<P>(x: &dyn Trait<P>) {
18+
x.method();
19+
}
20+
21+
fn main() {
22+
println!("{:p}", upcast::<()> as *const ());
23+
println!("{:p}", call::<()> as *const ());
24+
}

0 commit comments

Comments
 (0)