@@ -571,64 +571,55 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
571
571
572
572
// Obtain the underlying trait we are working on, and the adjusted receiver argument.
573
573
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
594
577
ty:: Dynamic ( _, _, ty:: DynStar ) => {
595
578
// Not clear how to handle this, so far we assume the receiver is always a pointer.
596
579
span_bug ! (
597
580
self . cur_span( ) ,
598
581
"by-value calls on a `dyn*`... are those a thing?"
599
582
) ;
600
583
}
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"
612
594
) ;
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 {
614
606
span_bug ! ( self . cur_span( ) , "dynamic call on non-`dyn` type {}" , receiver_tail)
615
607
} ;
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( ) ) ;
626
609
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
+ ) ;
631
617
}
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 )
632
623
} ;
633
624
634
625
// Now determine the actual method to call. We can do that in two different ways and
0 commit comments