Rollup merge of #144936 - rcvalle:rust-cfi-fix-144641, r=lcnr
CFI: Fix types that implement Fn, FnMut, or FnOnce When looking for instances which could either be dynamically called through a vtable or through a concrete trait method, we missed `FnPtrShim`, instead only looking at `Item` and closure-likes. Fixes rust-lang/rust#144641. cc ```@1c3t3a``` ```@Jakob-Koschel```
This commit is contained in:
@@ -10,9 +10,8 @@ use rustc_hir as hir;
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::{
|
||||
self, AssocContainer, ExistentialPredicateStableCmpExt as _, Instance, InstanceKind, IntTy,
|
||||
List, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
|
||||
UintTy,
|
||||
self, AssocContainer, ExistentialPredicateStableCmpExt as _, Instance, IntTy, List, TraitRef,
|
||||
Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UintTy,
|
||||
};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::{DUMMY_SP, sym};
|
||||
@@ -459,6 +458,30 @@ pub(crate) fn transform_instance<'tcx>(
|
||||
instance
|
||||
}
|
||||
|
||||
fn default_or_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Option<DefId> {
|
||||
match instance.def {
|
||||
ty::InstanceKind::Item(def_id) | ty::InstanceKind::FnPtrShim(def_id, _) => {
|
||||
tcx.opt_associated_item(def_id).map(|item| item.def_id)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines if an instance represents a trait method implementation and returns the necessary
|
||||
/// information for type erasure.
|
||||
///
|
||||
/// This function handles two main cases:
|
||||
///
|
||||
/// * **Implementation in an `impl` block**: When the instance represents a concrete implementation
|
||||
/// of a trait method in an `impl` block, it extracts the trait reference, method ID, and trait
|
||||
/// ID from the implementation. The method ID is obtained from the `trait_item_def_id` field of
|
||||
/// the associated item, which points to the original trait method definition.
|
||||
///
|
||||
/// * **Provided method in a `trait` block or synthetic `shim`**: When the instance represents a
|
||||
/// default implementation provided in the trait definition itself or a synthetic shim, it uses
|
||||
/// the instance's own `def_id` as the method ID and determines the trait ID from the associated
|
||||
/// item.
|
||||
///
|
||||
fn implemented_method<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
@@ -476,10 +499,11 @@ fn implemented_method<'tcx>(
|
||||
trait_id = trait_ref.skip_binder().def_id;
|
||||
impl_id
|
||||
} else if let AssocContainer::Trait = assoc.container
|
||||
&& let InstanceKind::Item(def_id) = instance.def
|
||||
&& let Some(trait_method_def_id) = default_or_shim(tcx, instance)
|
||||
{
|
||||
// Provided method in a `trait` block or a synthetic `shim`
|
||||
trait_method = assoc;
|
||||
method_id = def_id;
|
||||
method_id = trait_method_def_id;
|
||||
trait_id = tcx.parent(method_id);
|
||||
trait_ref = ty::EarlyBinder::bind(TraitRef::from_assoc(tcx, trait_id, instance.args));
|
||||
trait_id
|
||||
|
||||
Reference in New Issue
Block a user