Skip to content

Commit 616d817

Browse files
Ensure that we never try to monomorphize the upcasting of impossible dyn types
1 parent 37728dd commit 616d817

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

compiler/rustc_trait_selection/src/traits/vtable.rs

Lines changed: 22 additions & 4 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![];
@@ -316,6 +321,11 @@ pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRe
316321
"vtable trait ref should be normalized"
317322
);
318323

324+
// We're monomorphizing a dyn trait object that can never be constructed.
325+
if tcx.instantiate_and_check_impossible_predicates((key.def_id, key.args)) {
326+
return 0;
327+
}
328+
319329
let ty::Dynamic(source, _, _) = *key.self_ty().kind() else {
320330
bug!();
321331
};
@@ -375,19 +385,27 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
375385
let (source, target) = key;
376386

377387
// If the target principal is `None`, we can just return `None`.
378-
let ty::Dynamic(target, _, _) = *target.kind() else {
388+
let ty::Dynamic(target_data, _, _) = *target.kind() else {
379389
bug!();
380390
};
381-
let target_principal = tcx.instantiate_bound_regions_with_erased(target.principal()?);
391+
let target_principal = tcx.instantiate_bound_regions_with_erased(target_data.principal()?);
382392

383393
// Given that we have a target principal, it is a bug for there not to be a source principal.
384-
let ty::Dynamic(source, _, _) = *source.kind() else {
394+
let ty::Dynamic(source_data, _, _) = *source.kind() else {
385395
bug!();
386396
};
387397
let source_principal = tcx.instantiate_bound_regions_with_erased(
388-
source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self),
398+
source_data.principal().unwrap().with_self_ty(tcx, source),
389399
);
390400

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

0 commit comments

Comments
 (0)