Skip to content

Commit 7857058

Browse files
author
jasper3108
committed
nix vtable_for intrinsic
1 parent 01627b7 commit 7857058

10 files changed

Lines changed: 48 additions & 81 deletions

File tree

compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,16 @@
44
55
mod simd;
66

7-
use rustc_abi::{FIRST_VARIANT, FieldIdx, HasDataLayout, Size, VariantIdx};
7+
use rustc_abi::{FieldIdx, HasDataLayout, Size, VariantIdx};
88
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
99
use rustc_data_structures::assert_matches;
1010
use rustc_errors::msg;
11-
use rustc_hir::def_id::CRATE_DEF_ID;
12-
use rustc_infer::infer::TyCtxtInferExt;
1311
use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, read_target_uint, write_target_uint};
1412
use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic};
1513
use rustc_middle::ty::layout::TyAndLayout;
16-
use rustc_middle::ty::{FloatTy, PolyExistentialPredicate, Ty, TyCtxt, TypeVisitableExt};
14+
use rustc_middle::ty::{FloatTy, Ty, TyCtxt, TypeVisitableExt};
1715
use rustc_middle::{bug, span_bug, ty};
1816
use rustc_span::{Symbol, sym};
19-
use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt};
2017
use tracing::trace;
2118

2219
use super::memory::MemoryKind;
@@ -227,44 +224,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
227224

228225
self.write_scalar(Scalar::from_target_usize(offset, self), dest)?;
229226
}
230-
sym::vtable_for => {
231-
let tp_ty = instance.args.type_at(0);
232-
let result_ty = instance.args.type_at(1);
233-
234-
ensure_monomorphic_enough(tcx, tp_ty)?;
235-
ensure_monomorphic_enough(tcx, result_ty)?;
236-
let ty::Dynamic(preds, _) = result_ty.kind() else {
237-
span_bug!(
238-
self.find_closest_untracked_caller_location(),
239-
"Invalid type provided to vtable_for::<T, U>. U must be dyn Trait, got {result_ty}."
240-
);
241-
};
242-
243-
let (infcx, param_env) =
244-
self.tcx.infer_ctxt().build_with_typing_env(self.typing_env);
245-
246-
let ocx = ObligationCtxt::new(&infcx);
247-
ocx.register_obligations(preds.iter().map(|pred: PolyExistentialPredicate<'_>| {
248-
let pred = pred.with_self_ty(tcx, tp_ty);
249-
// Lifetimes can only be 'static because of the bound on T
250-
let pred = ty::fold_regions(tcx, pred, |r, _| {
251-
if r == tcx.lifetimes.re_erased { tcx.lifetimes.re_static } else { r }
252-
});
253-
Obligation::new(tcx, ObligationCause::dummy(), param_env, pred)
254-
}));
255-
let type_impls_trait = ocx.evaluate_obligations_error_on_ambiguity().is_empty();
256-
// Since `assumed_wf_tys=[]` the choice of LocalDefId is irrelevant, so using the "default"
257-
let regions_are_valid = ocx.resolve_regions(CRATE_DEF_ID, param_env, []).is_empty();
258-
259-
if regions_are_valid && type_impls_trait {
260-
let vtable_ptr = self.get_vtable_ptr(tp_ty, preds)?;
261-
// Writing a non-null pointer into an `Option<NonNull>` will automatically make it `Some`.
262-
self.write_pointer(vtable_ptr, dest)?;
263-
} else {
264-
// Write `None`
265-
self.write_discriminant(FIRST_VARIANT, dest)?;
266-
}
267-
}
268227
sym::variant_count => {
269228
let tp_ty = instance.args.type_at(0);
270229
let ty = match tp_ty.kind() {

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
219219
| sym::ub_checks
220220
| sym::va_copy
221221
| sym::variant_count
222-
| sym::vtable_for
223222
| sym::wrapping_add
224223
| sym::wrapping_mul
225224
| sym::wrapping_sub
@@ -695,20 +694,6 @@ pub(crate) fn check_intrinsic_type(
695694
(0, 0, vec![Ty::new_imm_ptr(tcx, tcx.types.unit)], tcx.types.usize)
696695
}
697696

698-
sym::vtable_for => {
699-
let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, span);
700-
let dyn_metadata_adt_ref = tcx.adt_def(dyn_metadata);
701-
let dyn_metadata_args = tcx.mk_args(&[param(1).into()]);
702-
let dyn_ty = Ty::new_adt(tcx, dyn_metadata_adt_ref, dyn_metadata_args);
703-
704-
let option_did = tcx.require_lang_item(LangItem::Option, span);
705-
let option_adt_ref = tcx.adt_def(option_did);
706-
let option_args = tcx.mk_args(&[dyn_ty.into()]);
707-
let ret_ty = Ty::new_adt(tcx, option_adt_ref, option_args);
708-
709-
(2, 0, vec![], ret_ty)
710-
}
711-
712697
// This type check is not particularly useful, but the `where` bounds
713698
// on the definition in `core` do the heavy lifting for checking it.
714699
sym::aggregate_raw_ptr => (3, 0, vec![param(1), param(2)], param(0)),

compiler/rustc_span/src/symbol.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2523,7 +2523,6 @@ symbols! {
25232523
vsreg,
25242524
vsx,
25252525
vtable_align,
2526-
vtable_for,
25272526
vtable_size,
25282527
warn,
25292528
wasip2,

library/core/src/any.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,8 @@ pub const fn try_as_dyn<
10121012
>(
10131013
t: &T,
10141014
) -> Option<&U> {
1015-
let vtable: Option<ptr::DynMetadata<U>> = const { intrinsics::vtable_for::<T, U>() };
1015+
let vtable: Option<ptr::DynMetadata<U>> =
1016+
const { TypeId::of::<T>().trait_info_of::<U>().as_ref().map(TraitImpl::get_vtable) };
10161017
match vtable {
10171018
Some(dyn_metadata) => {
10181019
let pointer = ptr::from_raw_parts(t, dyn_metadata);
@@ -1065,7 +1066,8 @@ pub const fn try_as_dyn_mut<
10651066
>(
10661067
t: &mut T,
10671068
) -> Option<&mut U> {
1068-
let vtable: Option<ptr::DynMetadata<U>> = const { intrinsics::vtable_for::<T, U>() };
1069+
let vtable: Option<ptr::DynMetadata<U>> =
1070+
const { TypeId::of::<T>().trait_info_of::<U>().as_ref().map(TraitImpl::get_vtable) };
10691071
match vtable {
10701072
Some(dyn_metadata) => {
10711073
let pointer = ptr::from_raw_parts_mut(t, dyn_metadata);

library/core/src/intrinsics/mod.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2751,18 +2751,6 @@ pub unsafe fn vtable_size(ptr: *const ()) -> usize;
27512751
#[rustc_intrinsic]
27522752
pub unsafe fn vtable_align(ptr: *const ()) -> usize;
27532753

2754-
/// The intrinsic returns the `U` vtable for `T` if `T` can be coerced to the trait object type `U`.
2755-
///
2756-
/// # Compile-time failures
2757-
/// Determining whether `T` can be coerced to the trait object type `U` requires trait resolution by the compiler.
2758-
/// In some cases, that resolution can exceed the recursion limit,
2759-
/// and compilation will fail instead of this function returning `None`.
2760-
#[rustc_nounwind]
2761-
#[unstable(feature = "core_intrinsics", issue = "none")]
2762-
#[rustc_intrinsic]
2763-
pub const fn vtable_for<T, U: ptr::Pointee<Metadata = ptr::DynMetadata<U>> + ?Sized>()
2764-
-> Option<ptr::DynMetadata<U>>;
2765-
27662754
/// The size of a type in bytes.
27672755
///
27682756
/// Note that, unlike most intrinsics, this is safe to call;

library/core/src/mem/type_info.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub struct TraitImpl<T: PointeeSized> {
2626

2727
impl<T: PointeeSized> TraitImpl<T> {
2828
/// Gets the raw vtable for type reflection mapping
29-
pub fn get_vtable(&self) -> DynMetadata<T> {
29+
pub const fn get_vtable(&self) -> DynMetadata<T> {
3030
self.vtable
3131
}
3232
}

library/coretests/tests/intrinsics.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use core::any::TypeId;
2-
use core::intrinsics::{assume, vtable_for};
2+
use core::intrinsics::assume;
33
use std::fmt::Debug;
4+
use std::intrinsics::type_id_vtable;
45
use std::option::Option;
56
use std::ptr::DynMetadata;
67

@@ -198,15 +199,17 @@ fn carrying_mul_add_fallback_i128() {
198199
}
199200

200201
#[test]
201-
fn test_vtable_for() {
202+
fn test_type_id_vtable() {
202203
#[derive(Debug)]
203204
struct A {}
204205

205206
struct B {}
206207

207-
const A_VTABLE: Option<DynMetadata<dyn Debug>> = vtable_for::<A, dyn Debug>();
208+
const A_VTABLE: Option<DynMetadata<*const ()>> =
209+
type_id_vtable(TypeId::of::<A>(), TypeId::of::<dyn Debug>());
208210
assert!(A_VTABLE.is_some());
209211

210-
const B_VTABLE: Option<DynMetadata<dyn Debug>> = vtable_for::<B, dyn Debug>();
212+
const B_VTABLE: Option<DynMetadata<*const ()>> =
213+
type_id_vtable(TypeId::of::<B>(), TypeId::of::<dyn Debug>());
211214
assert!(B_VTABLE.is_none());
212215
}

library/coretests/tests/mem/type_info.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
use std::any::{Any, TypeId};
44
use std::mem::offset_of;
55
use std::mem::type_info::{Const, Generic, GenericType, Type, TypeKind};
6-
use std::ptr::DynMetadata;
76

87
#[test]
98
fn test_arrays() {
Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,20 @@
1-
error: values of the type `[u8; usize::MAX]` are too big for the target architecture
1+
error[E0080]: values of the type `[u8; usize::MAX]` are too big for the target architecture
2+
--> $SRC_DIR/core/src/any.rs:LL:COL
3+
|
4+
= note: evaluation of `std::any::try_as_dyn::<[u8; usize::MAX], dyn Trait>::{constant#0}` failed inside this call
5+
note: inside `TypeId::trait_info_of::<dyn Trait>`
6+
--> $SRC_DIR/core/src/any.rs:LL:COL
7+
note: inside `TypeId::trait_info_of_trait_type_id`
8+
--> $SRC_DIR/core/src/any.rs:LL:COL
9+
note: inside `type_info::<impl TypeId>::info`
10+
--> $SRC_DIR/core/src/mem/type_info.rs:LL:COL
11+
12+
note: the above error was encountered while instantiating `fn try_as_dyn::<[u8; usize::MAX], dyn Trait>`
13+
--> $DIR/vtable-try-as-dyn.rs:14:13
14+
|
15+
LL | let _ = std::any::try_as_dyn::<[u8; usize::MAX], dyn Trait>(x);
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
217

318
error: aborting due to 1 previous error
419

20+
For more information about this error, try `rustc --explain E0080`.
Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,20 @@
1-
error: values of the type `[u8; usize::MAX]` are too big for the target architecture
1+
error[E0080]: values of the type `[u8; usize::MAX]` are too big for the target architecture
2+
--> $SRC_DIR/core/src/any.rs:LL:COL
3+
|
4+
= note: evaluation of `std::any::try_as_dyn::<[u8; usize::MAX], dyn Trait>::{constant#0}` failed inside this call
5+
note: inside `TypeId::trait_info_of::<dyn Trait>`
6+
--> $SRC_DIR/core/src/any.rs:LL:COL
7+
note: inside `TypeId::trait_info_of_trait_type_id`
8+
--> $SRC_DIR/core/src/any.rs:LL:COL
9+
note: inside `type_info::<impl TypeId>::info`
10+
--> $SRC_DIR/core/src/mem/type_info.rs:LL:COL
11+
12+
note: the above error was encountered while instantiating `fn try_as_dyn::<[u8; usize::MAX], dyn Trait>`
13+
--> $DIR/vtable-try-as-dyn.rs:14:13
14+
|
15+
LL | let _ = std::any::try_as_dyn::<[u8; usize::MAX], dyn Trait>(x);
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
217

318
error: aborting due to 1 previous error
419

20+
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)