@@ -190,6 +190,48 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
190190 let b_ty = self . read_type_id ( & args[ 1 ] ) ?;
191191 self . write_scalar ( Scalar :: from_bool ( a_ty == b_ty) , dest) ?;
192192 }
193+ sym:: vtable_for => {
194+ let tp_ty = instance. args . type_at ( 0 ) ;
195+ let result_ty = instance. args . type_at ( 1 ) ;
196+
197+ ensure_monomorphic_enough ( tcx, tp_ty) ?;
198+ ensure_monomorphic_enough ( tcx, result_ty) ?;
199+ let ty:: Dynamic ( preds, _, ty:: Dyn ) = result_ty. kind ( ) else {
200+ span_bug ! (
201+ self . find_closest_untracked_caller_location( ) ,
202+ "Invalid type provided to vtable_for::<T, U>. U must be dyn Trait, got {result_ty}."
203+ ) ;
204+ } ;
205+
206+ let ( infcx, param_env) =
207+ self . tcx . infer_ctxt ( ) . build_with_typing_env ( self . typing_env ) ;
208+
209+ let ocx = ObligationCtxt :: new ( & infcx) ;
210+ ocx. register_obligations ( preds. iter ( ) . map ( |pred| {
211+ let pred = pred. with_self_ty ( tcx, tp_ty) ;
212+ // Lifetimes can only be 'static because of the bound on T
213+ let pred = pred. fold_with ( & mut ty:: BottomUpFolder {
214+ tcx,
215+ ty_op : |ty| ty,
216+ lt_op : |lt| {
217+ if lt == tcx. lifetimes . re_erased { tcx. lifetimes . re_static } else { lt }
218+ } ,
219+ ct_op : |ct| ct,
220+ } ) ;
221+ Obligation :: new ( tcx, ObligationCause :: dummy ( ) , param_env, pred)
222+ } ) ) ;
223+ let type_impls_trait = ocx. select_all_or_error ( ) . is_empty ( ) ;
224+ // Since `assumed_wf_tys=[]` the choice of LocalDefId is irrelevant, so using the "default"
225+ let regions_are_valid = ocx. resolve_regions ( CRATE_DEF_ID , param_env, [ ] ) . is_empty ( ) ;
226+
227+ if regions_are_valid && type_impls_trait {
228+ let vtable_ptr = self . get_vtable_ptr ( tp_ty, preds) ?;
229+ // Writing a non-null pointer into an `Option<NonNull>` will automatically make it `Some`.
230+ self . write_pointer ( vtable_ptr, dest) ?;
231+ } else {
232+ // Write `None`
233+ self . write_discriminant ( FIRST_VARIANT , dest) ?;
234+ }
193235 sym:: size_of => {
194236 let tp_ty = instance. args . type_at ( 0 ) ;
195237 let layout = self . layout_of ( tp_ty) ?;
0 commit comments