1
Fork 0

Rename InstanceDef -> InstanceKind

This commit is contained in:
Michael Goulet 2024-06-16 21:35:16 -04:00
parent 55cac26a9e
commit 342c1b03d6
53 changed files with 421 additions and 418 deletions

View file

@ -19,10 +19,10 @@ use tracing::{debug, instrument};
use std::assert_matches::assert_matches;
use std::fmt;
/// A monomorphized `InstanceDef`.
/// An `InstanceKind` along with the args that are needed to substitute the instance.
///
/// Monomorphization happens on-the-fly and no monomorphized MIR is ever created. Instead, this type
/// simply couples a potentially generic `InstanceDef` with some args, and codegen and const eval
/// simply couples a potentially generic `InstanceKind` with some args, and codegen and const eval
/// will do all required instantiations as they run.
///
/// Note: the `Lift` impl is currently not used by rustc, but is used by
@ -30,7 +30,7 @@ use std::fmt;
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable, Lift, TypeFoldable, TypeVisitable)]
pub struct Instance<'tcx> {
pub def: InstanceDef<'tcx>,
pub def: InstanceKind<'tcx>,
pub args: GenericArgsRef<'tcx>,
}
@ -58,7 +58,7 @@ pub enum ReifyReason {
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
pub enum InstanceDef<'tcx> {
pub enum InstanceKind<'tcx> {
/// A user-defined callable item.
///
/// This includes:
@ -69,7 +69,7 @@ pub enum InstanceDef<'tcx> {
/// An intrinsic `fn` item (with `"rust-intrinsic"` or `"platform-intrinsic"` ABI).
///
/// Alongside `Virtual`, this is the only `InstanceDef` that does not have its own callable MIR.
/// Alongside `Virtual`, this is the only `InstanceKind` that does not have its own callable MIR.
/// Instead, codegen and const eval "magically" evaluate calls to intrinsics purely in the
/// caller.
Intrinsic(DefId),
@ -85,7 +85,7 @@ pub enum InstanceDef<'tcx> {
///
/// One example is `<dyn Trait as Trait>::fn`, where the shim contains
/// a virtual call, which codegen supports only via a direct call to the
/// `<dyn Trait as Trait>::fn` instance (an `InstanceDef::Virtual`).
/// `<dyn Trait as Trait>::fn` instance (an `InstanceKind::Virtual`).
///
/// Another example is functions annotated with `#[track_caller]`, which
/// must have their implicit caller location argument populated for a call.
@ -107,7 +107,7 @@ pub enum InstanceDef<'tcx> {
/// Dynamic dispatch to `<dyn Trait as Trait>::fn`.
///
/// This `InstanceDef` does not have callable MIR. Calls to `Virtual` instances must be
/// This `InstanceKind` does not have callable MIR. Calls to `Virtual` instances must be
/// codegen'd as virtual calls through the vtable.
///
/// If this is reified to a `fn` pointer, a `ReifyShim` is used (see `ReifyShim` above for more
@ -216,10 +216,10 @@ impl<'tcx> Instance<'tcx> {
}
match self.def {
InstanceDef::Item(def) => tcx
InstanceKind::Item(def) => tcx
.upstream_monomorphizations_for(def)
.and_then(|monos| monos.get(&self.args).cloned()),
InstanceDef::DropGlue(_, Some(_)) | InstanceDef::AsyncDropGlueCtorShim(_, _) => {
InstanceKind::DropGlue(_, Some(_)) | InstanceKind::AsyncDropGlueCtorShim(_, _) => {
tcx.upstream_drop_glue_for(self.args)
}
_ => None,
@ -227,48 +227,48 @@ impl<'tcx> Instance<'tcx> {
}
}
impl<'tcx> InstanceDef<'tcx> {
impl<'tcx> InstanceKind<'tcx> {
#[inline]
pub fn def_id(self) -> DefId {
match self {
InstanceDef::Item(def_id)
| InstanceDef::VTableShim(def_id)
| InstanceDef::ReifyShim(def_id, _)
| InstanceDef::FnPtrShim(def_id, _)
| InstanceDef::Virtual(def_id, _)
| InstanceDef::Intrinsic(def_id)
| InstanceDef::ThreadLocalShim(def_id)
| InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ }
| ty::InstanceDef::ConstructCoroutineInClosureShim {
InstanceKind::Item(def_id)
| InstanceKind::VTableShim(def_id)
| InstanceKind::ReifyShim(def_id, _)
| InstanceKind::FnPtrShim(def_id, _)
| InstanceKind::Virtual(def_id, _)
| InstanceKind::Intrinsic(def_id)
| InstanceKind::ThreadLocalShim(def_id)
| InstanceKind::ClosureOnceShim { call_once: def_id, track_caller: _ }
| ty::InstanceKind::ConstructCoroutineInClosureShim {
coroutine_closure_def_id: def_id,
receiver_by_ref: _,
}
| ty::InstanceDef::CoroutineKindShim { coroutine_def_id: def_id }
| InstanceDef::DropGlue(def_id, _)
| InstanceDef::CloneShim(def_id, _)
| InstanceDef::FnPtrAddrShim(def_id, _)
| InstanceDef::AsyncDropGlueCtorShim(def_id, _) => def_id,
| ty::InstanceKind::CoroutineKindShim { coroutine_def_id: def_id }
| InstanceKind::DropGlue(def_id, _)
| InstanceKind::CloneShim(def_id, _)
| InstanceKind::FnPtrAddrShim(def_id, _)
| InstanceKind::AsyncDropGlueCtorShim(def_id, _) => def_id,
}
}
/// Returns the `DefId` of instances which might not require codegen locally.
pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option<DefId> {
match self {
ty::InstanceDef::Item(def) => Some(def),
ty::InstanceDef::DropGlue(def_id, Some(_))
| InstanceDef::AsyncDropGlueCtorShim(def_id, _)
| InstanceDef::ThreadLocalShim(def_id) => Some(def_id),
InstanceDef::VTableShim(..)
| InstanceDef::ReifyShim(..)
| InstanceDef::FnPtrShim(..)
| InstanceDef::Virtual(..)
| InstanceDef::Intrinsic(..)
| InstanceDef::ClosureOnceShim { .. }
| ty::InstanceDef::ConstructCoroutineInClosureShim { .. }
| ty::InstanceDef::CoroutineKindShim { .. }
| InstanceDef::DropGlue(..)
| InstanceDef::CloneShim(..)
| InstanceDef::FnPtrAddrShim(..) => None,
ty::InstanceKind::Item(def) => Some(def),
ty::InstanceKind::DropGlue(def_id, Some(_))
| InstanceKind::AsyncDropGlueCtorShim(def_id, _)
| InstanceKind::ThreadLocalShim(def_id) => Some(def_id),
InstanceKind::VTableShim(..)
| InstanceKind::ReifyShim(..)
| InstanceKind::FnPtrShim(..)
| InstanceKind::Virtual(..)
| InstanceKind::Intrinsic(..)
| InstanceKind::ClosureOnceShim { .. }
| ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
| ty::InstanceKind::CoroutineKindShim { .. }
| InstanceKind::DropGlue(..)
| InstanceKind::CloneShim(..)
| InstanceKind::FnPtrAddrShim(..) => None,
}
}
@ -289,10 +289,10 @@ impl<'tcx> InstanceDef<'tcx> {
pub fn requires_inline(&self, tcx: TyCtxt<'tcx>) -> bool {
use rustc_hir::definitions::DefPathData;
let def_id = match *self {
ty::InstanceDef::Item(def) => def,
ty::InstanceDef::DropGlue(_, Some(_)) => return false,
ty::InstanceDef::AsyncDropGlueCtorShim(_, Some(_)) => return false,
ty::InstanceDef::ThreadLocalShim(_) => return false,
ty::InstanceKind::Item(def) => def,
ty::InstanceKind::DropGlue(_, Some(_)) => return false,
ty::InstanceKind::AsyncDropGlueCtorShim(_, Some(_)) => return false,
ty::InstanceKind::ThreadLocalShim(_) => return false,
_ => return true,
};
matches!(
@ -312,7 +312,7 @@ impl<'tcx> InstanceDef<'tcx> {
if self.requires_inline(tcx) {
return true;
}
if let ty::InstanceDef::DropGlue(.., Some(ty)) = *self {
if let ty::InstanceKind::DropGlue(.., Some(ty)) = *self {
// Drop glue generally wants to be instantiated at every codegen
// unit, but without an #[inline] hint. We should make this
// available to normal end-users.
@ -332,7 +332,7 @@ impl<'tcx> InstanceDef<'tcx> {
.map_or_else(|| adt_def.is_enum(), |dtor| tcx.cross_crate_inlinable(dtor.did))
});
}
if let ty::InstanceDef::ThreadLocalShim(..) = *self {
if let ty::InstanceKind::ThreadLocalShim(..) = *self {
return false;
}
tcx.cross_crate_inlinable(self.def_id())
@ -340,10 +340,10 @@ impl<'tcx> InstanceDef<'tcx> {
pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool {
match *self {
InstanceDef::Item(def_id) | InstanceDef::Virtual(def_id, _) => {
InstanceKind::Item(def_id) | InstanceKind::Virtual(def_id, _) => {
tcx.body_codegen_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
}
InstanceDef::ClosureOnceShim { call_once: _, track_caller } => track_caller,
InstanceKind::ClosureOnceShim { call_once: _, track_caller } => track_caller,
_ => false,
}
}
@ -356,22 +356,22 @@ impl<'tcx> InstanceDef<'tcx> {
/// body should perform necessary instantiations.
pub fn has_polymorphic_mir_body(&self) -> bool {
match *self {
InstanceDef::CloneShim(..)
| InstanceDef::ThreadLocalShim(..)
| InstanceDef::FnPtrAddrShim(..)
| InstanceDef::FnPtrShim(..)
| InstanceDef::DropGlue(_, Some(_))
| InstanceDef::AsyncDropGlueCtorShim(_, Some(_)) => false,
InstanceDef::ClosureOnceShim { .. }
| InstanceDef::ConstructCoroutineInClosureShim { .. }
| InstanceDef::CoroutineKindShim { .. }
| InstanceDef::DropGlue(..)
| InstanceDef::AsyncDropGlueCtorShim(..)
| InstanceDef::Item(_)
| InstanceDef::Intrinsic(..)
| InstanceDef::ReifyShim(..)
| InstanceDef::Virtual(..)
| InstanceDef::VTableShim(..) => true,
InstanceKind::CloneShim(..)
| InstanceKind::ThreadLocalShim(..)
| InstanceKind::FnPtrAddrShim(..)
| InstanceKind::FnPtrShim(..)
| InstanceKind::DropGlue(_, Some(_))
| InstanceKind::AsyncDropGlueCtorShim(_, Some(_)) => false,
InstanceKind::ClosureOnceShim { .. }
| InstanceKind::ConstructCoroutineInClosureShim { .. }
| InstanceKind::CoroutineKindShim { .. }
| InstanceKind::DropGlue(..)
| InstanceKind::AsyncDropGlueCtorShim(..)
| InstanceKind::Item(_)
| InstanceKind::Intrinsic(..)
| InstanceKind::ReifyShim(..)
| InstanceKind::Virtual(..)
| InstanceKind::VTableShim(..) => true,
}
}
}
@ -395,24 +395,24 @@ fn fmt_instance(
})?;
match instance.def {
InstanceDef::Item(_) => Ok(()),
InstanceDef::VTableShim(_) => write!(f, " - shim(vtable)"),
InstanceDef::ReifyShim(_, None) => write!(f, " - shim(reify)"),
InstanceDef::ReifyShim(_, Some(ReifyReason::FnPtr)) => write!(f, " - shim(reify-fnptr)"),
InstanceDef::ReifyShim(_, Some(ReifyReason::Vtable)) => write!(f, " - shim(reify-vtable)"),
InstanceDef::ThreadLocalShim(_) => write!(f, " - shim(tls)"),
InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"),
InstanceDef::Virtual(_, num) => write!(f, " - virtual#{num}"),
InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({ty})"),
InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"),
InstanceDef::ConstructCoroutineInClosureShim { .. } => write!(f, " - shim"),
InstanceDef::CoroutineKindShim { .. } => write!(f, " - shim"),
InstanceDef::DropGlue(_, None) => write!(f, " - shim(None)"),
InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({ty}))"),
InstanceDef::CloneShim(_, ty) => write!(f, " - shim({ty})"),
InstanceDef::FnPtrAddrShim(_, ty) => write!(f, " - shim({ty})"),
InstanceDef::AsyncDropGlueCtorShim(_, None) => write!(f, " - shim(None)"),
InstanceDef::AsyncDropGlueCtorShim(_, Some(ty)) => write!(f, " - shim(Some({ty}))"),
InstanceKind::Item(_) => Ok(()),
InstanceKind::VTableShim(_) => write!(f, " - shim(vtable)"),
InstanceKind::ReifyShim(_, None) => write!(f, " - shim(reify)"),
InstanceKind::ReifyShim(_, Some(ReifyReason::FnPtr)) => write!(f, " - shim(reify-fnptr)"),
InstanceKind::ReifyShim(_, Some(ReifyReason::Vtable)) => write!(f, " - shim(reify-vtable)"),
InstanceKind::ThreadLocalShim(_) => write!(f, " - shim(tls)"),
InstanceKind::Intrinsic(_) => write!(f, " - intrinsic"),
InstanceKind::Virtual(_, num) => write!(f, " - virtual#{num}"),
InstanceKind::FnPtrShim(_, ty) => write!(f, " - shim({ty})"),
InstanceKind::ClosureOnceShim { .. } => write!(f, " - shim"),
InstanceKind::ConstructCoroutineInClosureShim { .. } => write!(f, " - shim"),
InstanceKind::CoroutineKindShim { .. } => write!(f, " - shim"),
InstanceKind::DropGlue(_, None) => write!(f, " - shim(None)"),
InstanceKind::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({ty}))"),
InstanceKind::CloneShim(_, ty) => write!(f, " - shim({ty})"),
InstanceKind::FnPtrAddrShim(_, ty) => write!(f, " - shim({ty})"),
InstanceKind::AsyncDropGlueCtorShim(_, None) => write!(f, " - shim(None)"),
InstanceKind::AsyncDropGlueCtorShim(_, Some(ty)) => write!(f, " - shim(Some({ty}))"),
}
}
@ -434,9 +434,9 @@ impl<'tcx> Instance<'tcx> {
pub fn new(def_id: DefId, args: GenericArgsRef<'tcx>) -> Instance<'tcx> {
assert!(
!args.has_escaping_bound_vars(),
"args of instance {def_id:?} not normalized for codegen: {args:?}"
"args of instance {def_id:?} has escaping bound vars: {args:?}"
);
Instance { def: InstanceDef::Item(def_id), args }
Instance { def: InstanceKind::Item(def_id), args }
}
pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> {
@ -526,13 +526,13 @@ impl<'tcx> Instance<'tcx> {
let reason = tcx.sess.is_sanitizer_kcfi_enabled().then_some(ReifyReason::FnPtr);
Instance::resolve(tcx, param_env, def_id, args).ok().flatten().map(|mut resolved| {
match resolved.def {
InstanceDef::Item(def) if resolved.def.requires_caller_location(tcx) => {
InstanceKind::Item(def) if resolved.def.requires_caller_location(tcx) => {
debug!(" => fn pointer created for function with #[track_caller]");
resolved.def = InstanceDef::ReifyShim(def, reason);
resolved.def = InstanceKind::ReifyShim(def, reason);
}
InstanceDef::Virtual(def_id, _) => {
InstanceKind::Virtual(def_id, _) => {
debug!(" => fn pointer created for virtual call");
resolved.def = InstanceDef::ReifyShim(def_id, reason);
resolved.def = InstanceKind::ReifyShim(def_id, reason);
}
// Reify `Trait::method` implementations if KCFI is enabled
// FIXME(maurer) only reify it if it is a vtable-safe function
@ -544,7 +544,7 @@ impl<'tcx> Instance<'tcx> {
{
// If this function could also go in a vtable, we need to `ReifyShim` it with
// KCFI because it can only attach one type per function.
resolved.def = InstanceDef::ReifyShim(resolved.def_id(), reason)
resolved.def = InstanceKind::ReifyShim(resolved.def_id(), reason)
}
// Reify `::call`-like method implementations if KCFI is enabled
_ if tcx.sess.is_sanitizer_kcfi_enabled()
@ -553,7 +553,7 @@ impl<'tcx> Instance<'tcx> {
// Reroute through a reify via the *unresolved* instance. The resolved one can't
// be directly reified because it's closure-like. The reify can handle the
// unresolved instance.
resolved = Instance { def: InstanceDef::ReifyShim(def_id, reason), args }
resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args }
}
_ => {}
}
@ -575,12 +575,12 @@ impl<'tcx> Instance<'tcx> {
&& tcx.generics_of(def_id).has_self;
if is_vtable_shim {
debug!(" => associated item with unsizeable self: Self");
Some(Instance { def: InstanceDef::VTableShim(def_id), args })
Some(Instance { def: InstanceKind::VTableShim(def_id), args })
} else {
let reason = tcx.sess.is_sanitizer_kcfi_enabled().then_some(ReifyReason::Vtable);
Instance::resolve(tcx, param_env, def_id, args).ok().flatten().map(|mut resolved| {
match resolved.def {
InstanceDef::Item(def) => {
InstanceKind::Item(def) => {
// We need to generate a shim when we cannot guarantee that
// the caller of a trait object method will be aware of
// `#[track_caller]` - this ensures that the caller
@ -614,18 +614,18 @@ impl<'tcx> Instance<'tcx> {
// Create a shim for the `FnOnce/FnMut/Fn` method we are calling
// - unlike functions, invoking a closure always goes through a
// trait.
resolved = Instance { def: InstanceDef::ReifyShim(def_id, reason), args };
resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args };
} else {
debug!(
" => vtable fn pointer created for function with #[track_caller]: {:?}", def
);
resolved.def = InstanceDef::ReifyShim(def, reason);
resolved.def = InstanceKind::ReifyShim(def, reason);
}
}
}
InstanceDef::Virtual(def_id, _) => {
InstanceKind::Virtual(def_id, _) => {
debug!(" => vtable fn pointer created for virtual call");
resolved.def = InstanceDef::ReifyShim(def_id, reason)
resolved.def = InstanceKind::ReifyShim(def_id, reason)
}
_ => {}
}
@ -676,7 +676,7 @@ impl<'tcx> Instance<'tcx> {
.def_id;
let track_caller =
tcx.codegen_fn_attrs(closure_did).flags.contains(CodegenFnAttrFlags::TRACK_CALLER);
let def = ty::InstanceDef::ClosureOnceShim { call_once, track_caller };
let def = ty::InstanceKind::ClosureOnceShim { call_once, track_caller };
let self_ty = Ty::new_closure(tcx, closure_did, args);
@ -733,10 +733,10 @@ impl<'tcx> Instance<'tcx> {
// If the closure's kind ty disagrees with the identity closure's kind ty,
// then this must be a coroutine generated by one of the `ConstructCoroutineInClosureShim`s.
if args.as_coroutine().kind_ty() == id_args.as_coroutine().kind_ty() {
Some(Instance { def: ty::InstanceDef::Item(coroutine_def_id), args })
Some(Instance { def: ty::InstanceKind::Item(coroutine_def_id), args })
} else {
Some(Instance {
def: ty::InstanceDef::CoroutineKindShim { coroutine_def_id },
def: ty::InstanceKind::CoroutineKindShim { coroutine_def_id },
args,
})
}
@ -749,7 +749,7 @@ impl<'tcx> Instance<'tcx> {
}
}
/// Depending on the kind of `InstanceDef`, the MIR body associated with an
/// Depending on the kind of `InstanceKind`, the MIR body associated with an
/// instance is expressed in terms of the generic parameters of `self.def_id()`, and in other
/// cases the MIR body is expressed in terms of the types found in the generic parameter array.
/// In the former case, we want to instantiate those generic types and replace them with the
@ -832,7 +832,7 @@ impl<'tcx> Instance<'tcx> {
fn polymorphize<'tcx>(
tcx: TyCtxt<'tcx>,
instance: ty::InstanceDef<'tcx>,
instance: ty::InstanceKind<'tcx>,
args: GenericArgsRef<'tcx>,
) -> GenericArgsRef<'tcx> {
debug!("polymorphize({:?}, {:?})", instance, args);
@ -873,7 +873,7 @@ fn polymorphize<'tcx>(
match *ty.kind() {
ty::Closure(def_id, args) => {
let polymorphized_args =
polymorphize(self.tcx, ty::InstanceDef::Item(def_id), args);
polymorphize(self.tcx, ty::InstanceKind::Item(def_id), args);
if args == polymorphized_args {
ty
} else {
@ -882,7 +882,7 @@ fn polymorphize<'tcx>(
}
ty::Coroutine(def_id, args) => {
let polymorphized_args =
polymorphize(self.tcx, ty::InstanceDef::Item(def_id), args);
polymorphize(self.tcx, ty::InstanceKind::Item(def_id), args);
if args == polymorphized_args {
ty
} else {