@@ -545,11 +545,13 @@ fn fn_abi_new_uncached<'tcx>(
545545 instance : Option < ty:: Instance < ' tcx > > ,
546546) -> Result < & ' tcx FnAbi < ' tcx , Ty < ' tcx > > , & ' tcx FnAbiError < ' tcx > > {
547547 let tcx = cx. tcx ( ) ;
548- let ( caller_location, fn_def_id, is_virtual_call) = if let Some ( instance) = instance {
548+ let ( caller_location, determined_fn_def_id, is_virtual_call) = if let Some ( instance) = instance
549+ {
550+ let is_virtual_call = matches ! ( instance. def, ty:: InstanceKind :: Virtual ( ..) ) ;
549551 (
550552 instance. def . requires_caller_location ( tcx) . then ( || tcx. caller_location_ty ( ) ) ,
551- Some ( instance. def_id ( ) ) ,
552- matches ! ( instance . def , ty :: InstanceKind :: Virtual ( .. ) ) ,
553+ if is_virtual_call { None } else { Some ( instance. def_id ( ) ) } ,
554+ is_virtual_call ,
553555 )
554556 } else {
555557 ( None , None , false )
@@ -579,7 +581,7 @@ fn fn_abi_new_uncached<'tcx>(
579581 } ;
580582
581583 let is_drop_in_place =
582- fn_def_id . is_some_and ( |def_id| tcx. is_lang_item ( def_id, LangItem :: DropInPlace ) ) ;
584+ determined_fn_def_id . is_some_and ( |def_id| tcx. is_lang_item ( def_id, LangItem :: DropInPlace ) ) ;
583585
584586 let arg_of = |ty : Ty < ' tcx > , arg_idx : Option < usize > | -> Result < _ , & ' tcx FnAbiError < ' tcx > > {
585587 let span = tracing:: debug_span!( "arg_of" ) ;
@@ -635,7 +637,12 @@ fn fn_abi_new_uncached<'tcx>(
635637 c_variadic : sig. c_variadic ,
636638 fixed_count : inputs. len ( ) as u32 ,
637639 conv,
638- can_unwind : fn_can_unwind ( cx. tcx ( ) , fn_def_id, sig. abi ) ,
640+ can_unwind : fn_can_unwind (
641+ tcx,
642+ // Since `#[rustc_nounwind]` can change unwinding, we cannot infer unwinding by `fn_def_id` for a virtual call.
643+ determined_fn_def_id,
644+ sig. abi ,
645+ ) ,
639646 } ;
640647 fn_abi_adjust_for_abi (
641648 cx,
@@ -644,7 +651,7 @@ fn fn_abi_new_uncached<'tcx>(
644651 // If this is a virtual call, we cannot pass the `fn_def_id`, as it might call other
645652 // functions from vtable. Internally, `deduced_param_attrs` attempts to infer attributes by
646653 // visit the function body.
647- fn_def_id . filter ( |_| !is_virtual_call ) ,
654+ determined_fn_def_id ,
648655 ) ;
649656 debug ! ( "fn_abi_new_uncached = {:?}" , fn_abi) ;
650657 fn_abi_sanity_check ( cx, & fn_abi, sig. abi ) ;
0 commit comments