@@ -571,64 +571,55 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
571571
572572 // Obtain the underlying trait we are working on, and the adjusted receiver argument.
573573 let recv_ty = receiver. layout . ty ;
574- let ( vptr, dyn_ty, adjusted_receiver) = match recv_ty. kind ( ) {
575- ty:: Ref ( ..) | ty:: RawPtr ( ..)
576- if matches ! (
577- recv_ty. builtin_deref( true ) . unwrap( ) . ty. kind( ) ,
578- ty:: Dynamic ( _, _, ty:: DynStar )
579- ) =>
580- {
581- let receiver = self . deref_operand ( & receiver) ?;
582- let ty:: Dynamic ( data, ..) = receiver. layout . ty . kind ( ) else { bug ! ( ) } ;
583- let ( recv, vptr) = self . unpack_dyn_star ( & receiver. into ( ) ) ?;
584- let ( dyn_ty, dyn_trait) = self . get_ptr_vtable ( vptr) ?;
585- if dyn_trait != data. principal ( ) {
586- throw_ub_format ! (
587- "`dyn*` call on a pointer whose vtable does not match its type"
588- ) ;
589- }
590- let recv = recv. assert_mem_place ( ) ; // we passed an MPlaceTy to `unpack_dyn_star` so we definitely still have one
591-
592- ( vptr, dyn_ty, recv. ptr )
593- }
574+ let receiver_place = match recv_ty. kind ( ) {
575+ ty:: Ref ( ..) | ty:: RawPtr ( ..) => self . deref_operand ( & receiver) ?,
576+ ty:: Dynamic ( _, _, ty:: Dyn ) => receiver. assert_mem_place ( ) , // unsized (`dyn`) cannot be immediate
594577 ty:: Dynamic ( _, _, ty:: DynStar ) => {
595578 // Not clear how to handle this, so far we assume the receiver is always a pointer.
596579 span_bug ! (
597580 self . cur_span( ) ,
598581 "by-value calls on a `dyn*`... are those a thing?"
599582 ) ;
600583 }
601- _ => {
602- let receiver_place = match recv_ty. kind ( ) {
603- ty:: Ref ( ..) | ty:: RawPtr ( ..) => self . deref_operand ( & receiver) ?,
604- ty:: Dynamic ( _, _, ty:: Dyn ) => receiver. assert_mem_place ( ) , // unsized (`dyn`) cannot be immediate
605- _ => bug ! ( ) ,
606- } ;
607- // Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`.
608- // (For that reason we also cannot use `unpack_dyn_trait`.)
609- let receiver_tail = self . tcx . struct_tail_erasing_lifetimes (
610- receiver_place. layout . ty ,
611- self . param_env ,
584+ _ => bug ! ( ) ,
585+ } ;
586+ let ( vptr, dyn_ty, adjusted_receiver) = if let ty:: Dynamic ( data, _, ty:: DynStar ) =
587+ receiver_place. layout . ty . kind ( )
588+ {
589+ let ( recv, vptr) = self . unpack_dyn_star ( & receiver_place. into ( ) ) ?;
590+ let ( dyn_ty, dyn_trait) = self . get_ptr_vtable ( vptr) ?;
591+ if dyn_trait != data. principal ( ) {
592+ throw_ub_format ! (
593+ "`dyn*` call on a pointer whose vtable does not match its type"
612594 ) ;
613- let ty:: Dynamic ( data, _, ty:: Dyn ) = receiver_tail. kind ( ) else {
595+ }
596+ let recv = recv. assert_mem_place ( ) ; // we passed an MPlaceTy to `unpack_dyn_star` so we definitely still have one
597+
598+ ( vptr, dyn_ty, recv. ptr )
599+ } else {
600+ // Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`.
601+ // (For that reason we also cannot use `unpack_dyn_trait`.)
602+ let receiver_tail = self
603+ . tcx
604+ . struct_tail_erasing_lifetimes ( receiver_place. layout . ty , self . param_env ) ;
605+ let ty:: Dynamic ( data, _, ty:: Dyn ) = receiver_tail. kind ( ) else {
614606 span_bug ! ( self . cur_span( ) , "dynamic call on non-`dyn` type {}" , receiver_tail)
615607 } ;
616- assert ! ( receiver_place. layout. is_unsized( ) ) ;
617-
618- // Get the required information from the vtable.
619- let vptr = receiver_place. meta . unwrap_meta ( ) . to_pointer ( self ) ?;
620- let ( dyn_ty, dyn_trait) = self . get_ptr_vtable ( vptr) ?;
621- if dyn_trait != data. principal ( ) {
622- throw_ub_format ! (
623- "`dyn` call on a pointer whose vtable does not match its type"
624- ) ;
625- }
608+ assert ! ( receiver_place. layout. is_unsized( ) ) ;
626609
627- // It might be surprising that we use a pointer as the receiver even if this
628- // is a by-val case; this works because by-val passing of an unsized `dyn
629- // Trait` to a function is actually desugared to a pointer.
630- ( vptr, dyn_ty, receiver_place. ptr )
610+ // Get the required information from the vtable.
611+ let vptr = receiver_place. meta . unwrap_meta ( ) . to_pointer ( self ) ?;
612+ let ( dyn_ty, dyn_trait) = self . get_ptr_vtable ( vptr) ?;
613+ if dyn_trait != data. principal ( ) {
614+ throw_ub_format ! (
615+ "`dyn` call on a pointer whose vtable does not match its type"
616+ ) ;
631617 }
618+
619+ // It might be surprising that we use a pointer as the receiver even if this
620+ // is a by-val case; this works because by-val passing of an unsized `dyn
621+ // Trait` to a function is actually desugared to a pointer.
622+ ( vptr, dyn_ty, receiver_place. ptr )
632623 } ;
633624
634625 // Now determine the actual method to call. We can do that in two different ways and
0 commit comments