Skip to content

Commit 95e10fb

Browse files
committed
Fix ICE in case of TypeId provenance being overridden with a non-type-id provenance
1 parent 47df5ea commit 95e10fb

File tree

4 files changed

+46
-6
lines changed

4 files changed

+46
-6
lines changed

compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use std::assert_matches::assert_matches;
66

77
use rustc_abi::{FieldIdx, Size};
88
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
9-
use rustc_middle::mir::interpret::GlobalAlloc;
109
use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic};
1110
use rustc_middle::ty::layout::TyAndLayout;
1211
use rustc_middle::ty::{Ty, TyCtxt};
@@ -105,15 +104,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
105104
.next(self)?
106105
.expect("we know the layout of TypeId has at least 2 array elements");
107106
let a = self.deref_pointer(&a)?;
108-
let (a, offset_a, _) = self.ptr_get_alloc_id(a.ptr(), 0)?;
109-
let GlobalAlloc::Type { ty: a } = self.tcx.global_alloc(a) else { bug!() };
107+
let (a, offset_a) = self.get_ptr_type_id(a.ptr())?;
110108

111109
let (_idx, b) = b_fields
112110
.next(self)?
113111
.expect("we know the layout of TypeId has at least 2 array elements");
114112
let b = self.deref_pointer(&b)?;
115-
let (b, offset_b, _) = self.ptr_get_alloc_id(b.ptr(), 0)?;
116-
let GlobalAlloc::Type { ty: b } = self.tcx.global_alloc(b) else { bug!() };
113+
let (b, offset_b) = self.get_ptr_type_id(b.ptr())?;
117114

118115
let provenance_matches = a == b;
119116

compiler/rustc_const_eval/src/interpret/memory.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ use std::{fmt, ptr};
1515
use rustc_abi::{Align, HasDataLayout, Size};
1616
use rustc_ast::Mutability;
1717
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
18-
use rustc_middle::bug;
1918
use rustc_middle::mir::display_allocation;
2019
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
20+
use rustc_middle::{bug, throw_ub_format};
2121
use tracing::{debug, instrument, trace};
2222

2323
use super::{
@@ -946,6 +946,19 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
946946
}
947947
}
948948

949+
/// Takes a pointer that is the first chunk of a `TypeId` and return the type that its
950+
/// provenance refers to, as well as the segment of the hash that this pointer covers.
951+
pub fn get_ptr_type_id(
952+
&self,
953+
ptr: Pointer<Option<M::Provenance>>,
954+
) -> InterpResult<'tcx, (Ty<'tcx>, Size)> {
955+
let (alloc_id, offset, _meta) = self.ptr_get_alloc_id(ptr, 0)?;
956+
let GlobalAlloc::Type { ty } = self.tcx.global_alloc(alloc_id) else {
957+
throw_ub_format!("type_id_eq: `TypeId` provenance is not a type id")
958+
};
959+
interp_ok((ty, offset))
960+
}
961+
949962
pub fn get_ptr_fn(
950963
&self,
951964
ptr: Pointer<Option<M::Provenance>>,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(const_type_id, const_trait_impl)]
2+
3+
use std::any::TypeId;
4+
5+
const _: () = {
6+
let a = TypeId::of::<()>();
7+
let mut b = TypeId::of::<()>();
8+
unsafe {
9+
let ptr = &mut b as *mut TypeId as *mut *const ();
10+
std::ptr::write(ptr.offset(0), main as fn() as *const ());
11+
}
12+
assert!(a == b);
13+
//~^ ERROR: type_id_eq: `TypeId` provenance is not a type id
14+
};
15+
16+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0080]: type_id_eq: `TypeId` provenance is not a type id
2+
--> $DIR/const_transmute_type_id4.rs:12:13
3+
|
4+
LL | assert!(a == b);
5+
| ^^^^^^ evaluation of `_` failed inside this call
6+
|
7+
note: inside `<TypeId as PartialEq>::eq`
8+
--> $SRC_DIR/core/src/any.rs:LL:COL
9+
note: inside `<TypeId as PartialEq>::eq::ct`
10+
--> $SRC_DIR/core/src/any.rs:LL:COL
11+
12+
error: aborting due to 1 previous error
13+
14+
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)