Skip to content

Commit ca8e62d

Browse files
committed
Introduce vtable_for intrinsic. Passes hir analysis, far from functional
1 parent 1b61d43 commit ca8e62d

File tree

5 files changed

+60
-0
lines changed

5 files changed

+60
-0
lines changed

compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,22 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
6767
let val = self.const_val_to_op(val, dest.layout.ty, Some(dest.layout))?;
6868
self.copy_op(&val, dest)?;
6969
}
70+
sym::vtable_for => {
71+
let tp_ty = instance.args.type_at(0);
72+
let result_ty = instance.args.type_at(1);
73+
//let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, span);
74+
75+
ensure_monomorphic_enough(tcx, tp_ty)?;
76+
ensure_monomorphic_enough(tcx, result_ty)?;
77+
78+
// Get vtable
79+
//let vtable_ptr = self.get_vtable_ptr(tp_ty, result_ty.into())?;
80+
81+
//let dyn_metadata = metadata(vtable_ptr);
82+
//let val = ConstValue::from_u128(tcx.type_id_hash(tp_ty).as_u128());
83+
//let val = self.const_val_to_op(val, dest.layout.ty, Some(dest.layout))?;
84+
//self.copy_op(&val, dest)?;
85+
}
7086
sym::variant_count => {
7187
let tp_ty = instance.args.type_at(0);
7288
let ty = match tp_ty.kind() {

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
9393
| sym::three_way_compare
9494
| sym::discriminant_value
9595
| sym::type_id
96+
| sym::vtable_for
9697
| sym::select_unpredictable
9798
| sym::cold_path
9899
| sym::ptr_guaranteed_cmp
@@ -543,6 +544,20 @@ pub(crate) fn check_intrinsic_type(
543544
(0, 0, vec![Ty::new_imm_ptr(tcx, tcx.types.unit)], tcx.types.usize)
544545
}
545546

547+
sym::vtable_for => {
548+
let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, span);
549+
let dyn_metadata_adt_ref = tcx.adt_def(dyn_metadata);
550+
let dyn_metadata_args = tcx.mk_args(&[param(1).into()]);
551+
let dyn_ty = Ty::new_adt(tcx, dyn_metadata_adt_ref, dyn_metadata_args);
552+
553+
let option_did = tcx.require_lang_item(LangItem::Option, span);
554+
let option_adt_ref = tcx.adt_def(option_did);
555+
let option_args = tcx.mk_args(&[dyn_ty.into()]);
556+
let ret_ty = Ty::new_adt(tcx, option_adt_ref, option_args);
557+
558+
(2, 0, vec![], ret_ty)
559+
}
560+
546561
// This type check is not particularly useful, but the `where` bounds
547562
// on the definition in `core` do the heavy lifting for checking it.
548563
sym::aggregate_raw_ptr => (3, 0, vec![param(1), param(2)], param(0)),

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2345,6 +2345,7 @@ symbols! {
23452345
vreg_low16,
23462346
vsx,
23472347
vtable_align,
2348+
vtable_for,
23482349
vtable_size,
23492350
warn,
23502351
wasip2,

library/core/src/intrinsics/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2626,6 +2626,17 @@ pub unsafe fn vtable_size(ptr: *const ()) -> usize;
26262626
#[rustc_intrinsic]
26272627
pub unsafe fn vtable_align(ptr: *const ()) -> usize;
26282628

2629+
/// FIXME: write actual docs (ivarflakstad)
2630+
/// The intrinsic will return the vtable of `t` through the lens of `U`.
2631+
///
2632+
/// # Safety
2633+
///
2634+
/// `ptr` must point to a vtable.
2635+
#[rustc_nounwind]
2636+
#[unstable(feature = "core_intrinsics", issue = "none")]
2637+
#[rustc_intrinsic]
2638+
pub const fn vtable_for<T: 'static, U: ?Sized + 'static>() -> Option<ptr::DynMetadata<U>>;
2639+
26292640
/// The size of a type in bytes.
26302641
///
26312642
/// Note that, unlike most intrinsics, this is safe to call;

library/coretests/tests/intrinsics.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,20 @@ fn carrying_mul_add_fallback_i128() {
193193
(u128::MAX - 1, -(i128::MIN / 2)),
194194
);
195195
}
196+
197+
#[test]
198+
fn test_vtable_for() {
199+
use std::fmt::Debug;
200+
use std::intrinsics::vtable_for;
201+
use std::option::Option;
202+
use std::ptr::DynMetadata;
203+
204+
#[allow(dead_code)]
205+
#[derive(Debug)]
206+
struct A {
207+
index: usize,
208+
}
209+
const debug_vtable: Option<DynMetadata<dyn Debug>> = vtable_for::<A, dyn Debug>();
210+
211+
println!("{debug_vtable:?}");
212+
}

0 commit comments

Comments
 (0)