@@ -543,11 +543,13 @@ fn fn_abi_new_uncached<'tcx>(
543543 instance : Option < ty:: Instance < ' tcx > > ,
544544) -> Result < & ' tcx FnAbi < ' tcx , Ty < ' tcx > > , & ' tcx FnAbiError < ' tcx > > {
545545 let tcx = cx. tcx ( ) ;
546- let ( caller_location, fn_def_id, is_virtual_call) = if let Some ( instance) = instance {
546+ let ( caller_location, determined_fn_def_id, is_virtual_call) = if let Some ( instance) = instance
547+ {
548+ let is_virtual_call = matches ! ( instance. def, ty:: InstanceKind :: Virtual ( ..) ) ;
547549 (
548550 instance. def . requires_caller_location ( tcx) . then ( || tcx. caller_location_ty ( ) ) ,
549- Some ( instance. def_id ( ) ) ,
550- matches ! ( instance . def , ty :: InstanceKind :: Virtual ( .. ) ) ,
551+ if is_virtual_call { None } else { Some ( instance. def_id ( ) ) } ,
552+ is_virtual_call ,
551553 )
552554 } else {
553555 ( None , None , false )
@@ -577,7 +579,7 @@ fn fn_abi_new_uncached<'tcx>(
577579 } ;
578580
579581 let is_drop_in_place =
580- fn_def_id . is_some_and ( |def_id| tcx. is_lang_item ( def_id, LangItem :: DropInPlace ) ) ;
582+ determined_fn_def_id . is_some_and ( |def_id| tcx. is_lang_item ( def_id, LangItem :: DropInPlace ) ) ;
581583
582584 let arg_of = |ty : Ty < ' tcx > , arg_idx : Option < usize > | -> Result < _ , & ' tcx FnAbiError < ' tcx > > {
583585 let span = tracing:: debug_span!( "arg_of" ) ;
@@ -633,7 +635,12 @@ fn fn_abi_new_uncached<'tcx>(
633635 c_variadic : sig. c_variadic ,
634636 fixed_count : inputs. len ( ) as u32 ,
635637 conv,
636- can_unwind : fn_can_unwind ( cx. tcx ( ) , fn_def_id, sig. abi ) ,
638+ can_unwind : fn_can_unwind (
639+ tcx,
640+ // Since `#[rustc_nounwind]` can change unwinding, we cannot infer unwinding by `fn_def_id` for a virtual call.
641+ determined_fn_def_id,
642+ sig. abi ,
643+ ) ,
637644 } ;
638645 fn_abi_adjust_for_abi (
639646 cx,
@@ -642,7 +649,7 @@ fn fn_abi_new_uncached<'tcx>(
642649 // If this is a virtual call, we cannot pass the `fn_def_id`, as it might call other
643650 // functions from vtable. Internally, `deduced_param_attrs` attempts to infer attributes by
644651 // visit the function body.
645- fn_def_id . filter ( |_| !is_virtual_call ) ,
652+ determined_fn_def_id ,
646653 ) ;
647654 debug ! ( "fn_abi_new_uncached = {:?}" , fn_abi) ;
648655 fn_abi_sanity_check ( cx, & fn_abi, sig. abi ) ;
0 commit comments