Skip to content

Commit 526d71e

Browse files
Ensure that we never try to monomorphize the upcasting of impossible dyn types
1 parent e96ffdd commit 526d71e

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

compiler/rustc_codegen_ssa/src/meth.rs

+2
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ fn dyn_trait_in_self<'tcx>(
8080
if let GenericArgKind::Type(ty) = arg.unpack()
8181
&& let ty::Dynamic(data, _, _) = ty.kind()
8282
{
83+
// FIXME(arbitrary_self_types): This is likely broken for receivers which
84+
// have a "non-self" trait objects as a generic argument.
8385
return data
8486
.principal()
8587
.map(|principal| tcx.instantiate_bound_regions_with_erased(principal));

compiler/rustc_trait_selection/src/traits/vtable.rs

+26-5
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,11 @@ fn vtable_entries<'tcx>(
232232
"vtable trait ref should be normalized"
233233
);
234234

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

237242
let mut entries = vec![];
@@ -318,9 +323,17 @@ pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRe
318323
bug!();
319324
};
320325
let source_principal = tcx.instantiate_bound_regions_with_erased(
321-
source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self),
326+
source.principal().unwrap().with_self_ty(tcx, key.self_ty()),
322327
);
323328

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

326339
let vtable_segment_callback = {
@@ -373,19 +386,27 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
373386
let (source, target) = key;
374387

375388
// If the target principal is `None`, we can just return `None`.
376-
let ty::Dynamic(target, _, _) = *target.kind() else {
389+
let ty::Dynamic(target_data, _, _) = *target.kind() else {
377390
bug!();
378391
};
379-
let target_principal = tcx.instantiate_bound_regions_with_erased(target.principal()?);
392+
let target_principal = tcx.instantiate_bound_regions_with_erased(target_data.principal()?);
380393

381394
// Given that we have a target principal, it is a bug for there not to be a source principal.
382-
let ty::Dynamic(source, _, _) = *source.kind() else {
395+
let ty::Dynamic(source_data, _, _) = *source.kind() else {
383396
bug!();
384397
};
385398
let source_principal = tcx.instantiate_bound_regions_with_erased(
386-
source.principal().unwrap().with_self_ty(tcx, tcx.types.trait_object_dummy_self),
399+
source_data.principal().unwrap().with_self_ty(tcx, source),
387400
);
388401

402+
// We're monomorphizing a dyn trait object that can never be constructed.
403+
if tcx.instantiate_and_check_impossible_predicates((
404+
source_principal.def_id,
405+
source_principal.args,
406+
)) {
407+
return None;
408+
}
409+
389410
let vtable_segment_callback = {
390411
let mut vptr_offset = 0;
391412
move |segment| {
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)