@@ -505,7 +505,7 @@ impl<'tcx> Instance<'tcx> {
505
505
// below is more likely to ignore the bounds in scope (e.g. if the only
506
506
// generic parameters mentioned by `args` were lifetime ones).
507
507
let args = tcx. erase_regions ( args) ;
508
- tcx. resolve_instance ( tcx. erase_regions ( param_env. and ( ( def_id, args) ) ) )
508
+ tcx. resolve_instance_raw ( tcx. erase_regions ( param_env. and ( ( def_id, args) ) ) )
509
509
}
510
510
511
511
pub fn expect_resolve (
@@ -571,77 +571,81 @@ impl<'tcx> Instance<'tcx> {
571
571
} )
572
572
}
573
573
574
- pub fn resolve_for_vtable (
574
+ pub fn expect_resolve_for_vtable (
575
575
tcx : TyCtxt < ' tcx > ,
576
576
param_env : ty:: ParamEnv < ' tcx > ,
577
577
def_id : DefId ,
578
578
args : GenericArgsRef < ' tcx > ,
579
- ) -> Option < Instance < ' tcx > > {
579
+ ) -> Instance < ' tcx > {
580
580
debug ! ( "resolve_for_vtable(def_id={:?}, args={:?})" , def_id, args) ;
581
581
let fn_sig = tcx. fn_sig ( def_id) . instantiate_identity ( ) ;
582
582
let is_vtable_shim = !fn_sig. inputs ( ) . skip_binder ( ) . is_empty ( )
583
583
&& fn_sig. input ( 0 ) . skip_binder ( ) . is_param ( 0 )
584
584
&& tcx. generics_of ( def_id) . has_self ;
585
+
585
586
if is_vtable_shim {
586
587
debug ! ( " => associated item with unsizeable self: Self" ) ;
587
- Some ( Instance { def : InstanceKind :: VTableShim ( def_id) , args } )
588
- } else {
589
- let reason = tcx. sess . is_sanitizer_kcfi_enabled ( ) . then_some ( ReifyReason :: Vtable ) ;
590
- Instance :: resolve ( tcx, param_env, def_id, args) . ok ( ) . flatten ( ) . map ( |mut resolved| {
591
- match resolved. def {
592
- InstanceKind :: Item ( def) => {
593
- // We need to generate a shim when we cannot guarantee that
594
- // the caller of a trait object method will be aware of
595
- // `#[track_caller]` - this ensures that the caller
596
- // and callee ABI will always match.
597
- //
598
- // The shim is generated when all of these conditions are met:
599
- //
600
- // 1) The underlying method expects a caller location parameter
601
- // in the ABI
602
- if resolved. def . requires_caller_location ( tcx)
603
- // 2) The caller location parameter comes from having `#[track_caller]`
604
- // on the implementation, and *not* on the trait method.
605
- && !tcx. should_inherit_track_caller ( def)
606
- // If the method implementation comes from the trait definition itself
607
- // (e.g. `trait Foo { #[track_caller] my_fn() { /* impl */ } }`),
608
- // then we don't need to generate a shim. This check is needed because
609
- // `should_inherit_track_caller` returns `false` if our method
610
- // implementation comes from the trait block, and not an impl block
611
- && !matches ! (
612
- tcx. opt_associated_item( def) ,
613
- Some ( ty:: AssocItem {
614
- container: ty:: AssocItemContainer :: TraitContainer ,
615
- ..
616
- } )
617
- )
618
- {
619
- if tcx. is_closure_like ( def) {
620
- debug ! ( " => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}" ,
621
- def, def_id, args) ;
622
-
623
- // Create a shim for the `FnOnce/FnMut/Fn` method we are calling
624
- // - unlike functions, invoking a closure always goes through a
625
- // trait.
626
- resolved = Instance { def : InstanceKind :: ReifyShim ( def_id, reason) , args } ;
627
- } else {
628
- debug ! (
629
- " => vtable fn pointer created for function with #[track_caller]: {:?}" , def
630
- ) ;
631
- resolved. def = InstanceKind :: ReifyShim ( def, reason) ;
632
- }
633
- }
634
- }
635
- InstanceKind :: Virtual ( def_id, _) => {
636
- debug ! ( " => vtable fn pointer created for virtual call" ) ;
637
- resolved. def = InstanceKind :: ReifyShim ( def_id, reason)
588
+ return Instance { def : InstanceKind :: VTableShim ( def_id) , args } ;
589
+ }
590
+
591
+ let mut resolved = Instance :: expect_resolve ( tcx, param_env, def_id, args) ;
592
+
593
+ let reason = tcx. sess . is_sanitizer_kcfi_enabled ( ) . then_some ( ReifyReason :: Vtable ) ;
594
+ match resolved. def {
595
+ InstanceKind :: Item ( def) => {
596
+ // We need to generate a shim when we cannot guarantee that
597
+ // the caller of a trait object method will be aware of
598
+ // `#[track_caller]` - this ensures that the caller
599
+ // and callee ABI will always match.
600
+ //
601
+ // The shim is generated when all of these conditions are met:
602
+ //
603
+ // 1) The underlying method expects a caller location parameter
604
+ // in the ABI
605
+ if resolved. def . requires_caller_location ( tcx)
606
+ // 2) The caller location parameter comes from having `#[track_caller]`
607
+ // on the implementation, and *not* on the trait method.
608
+ && !tcx. should_inherit_track_caller ( def)
609
+ // If the method implementation comes from the trait definition itself
610
+ // (e.g. `trait Foo { #[track_caller] my_fn() { /* impl */ } }`),
611
+ // then we don't need to generate a shim. This check is needed because
612
+ // `should_inherit_track_caller` returns `false` if our method
613
+ // implementation comes from the trait block, and not an impl block
614
+ && !matches ! (
615
+ tcx. opt_associated_item( def) ,
616
+ Some ( ty:: AssocItem {
617
+ container: ty:: AssocItemContainer :: TraitContainer ,
618
+ ..
619
+ } )
620
+ )
621
+ {
622
+ if tcx. is_closure_like ( def) {
623
+ debug ! (
624
+ " => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}" ,
625
+ def, def_id, args
626
+ ) ;
627
+
628
+ // Create a shim for the `FnOnce/FnMut/Fn` method we are calling
629
+ // - unlike functions, invoking a closure always goes through a
630
+ // trait.
631
+ resolved = Instance { def : InstanceKind :: ReifyShim ( def_id, reason) , args } ;
632
+ } else {
633
+ debug ! (
634
+ " => vtable fn pointer created for function with #[track_caller]: {:?}" ,
635
+ def
636
+ ) ;
637
+ resolved. def = InstanceKind :: ReifyShim ( def, reason) ;
638
638
}
639
- _ => { }
640
639
}
641
-
642
- resolved
643
- } )
640
+ }
641
+ InstanceKind :: Virtual ( def_id, _) => {
642
+ debug ! ( " => vtable fn pointer created for virtual call" ) ;
643
+ resolved. def = InstanceKind :: ReifyShim ( def_id, reason)
644
+ }
645
+ _ => { }
644
646
}
647
+
648
+ resolved
645
649
}
646
650
647
651
pub fn resolve_closure (
0 commit comments