summaryrefslogtreecommitdiff
path: root/compiler/rustc_symbol_mangling
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_symbol_mangling')
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs12
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid.rs15
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs35
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs8
4 files changed, 48 insertions, 22 deletions
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 1c62ce2d214..f68668a91e6 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -2,7 +2,7 @@ use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
use rustc_hir::def_id::CrateNum;
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc_middle::ty::print::{PrettyPrinter, Print, PrintError, Printer};
-use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, Instance, ReifyReason, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{GenericArg, GenericArgKind};
use std::fmt::{self, Write};
@@ -71,8 +71,14 @@ pub(super) fn mangle<'tcx>(
ty::InstanceDef::VTableShim(..) => {
printer.write_str("{{vtable-shim}}").unwrap();
}
- ty::InstanceDef::ReifyShim(..) => {
- printer.write_str("{{reify-shim}}").unwrap();
+ ty::InstanceDef::ReifyShim(_, reason) => {
+ printer.write_str("{{reify-shim").unwrap();
+ match reason {
+ Some(ReifyReason::FnPtr) => printer.write_str("-fnptr").unwrap(),
+ Some(ReifyReason::Vtable) => printer.write_str("-vtable").unwrap(),
+ None => (),
+ }
+ printer.write_str("}}").unwrap();
}
// FIXME(async_closures): This shouldn't be needed when we fix
// `Instance::ty`/`Instance::def_id`.
diff --git a/compiler/rustc_symbol_mangling/src/typeid.rs b/compiler/rustc_symbol_mangling/src/typeid.rs
index fc1e8e46e8d..862ba285db8 100644
--- a/compiler/rustc_symbol_mangling/src/typeid.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid.rs
@@ -4,7 +4,7 @@
/// For more information about LLVM CFI and cross-language LLVM CFI support for the Rust compiler,
/// see design document in the tracking issue #89653.
use bitflags::bitflags;
-use rustc_middle::ty::{Instance, Ty, TyCtxt};
+use rustc_middle::ty::{Instance, InstanceDef, ReifyReason, Ty, TyCtxt};
use rustc_target::abi::call::FnAbi;
use std::hash::Hasher;
use twox_hash::XxHash64;
@@ -24,9 +24,9 @@ bitflags! {
/// `-fsanitize-cfi-icall-experimental-normalize-integers` option for cross-language LLVM
/// CFI and KCFI support.
const NORMALIZE_INTEGERS = 4;
- /// Do not perform self type erasure for attaching a secondary type id to methods with their
- /// concrete self so they can be used as function pointers.
- const NO_SELF_TYPE_ERASURE = 8;
+ /// Generalize the instance by erasing the concrete `Self` type where possible.
+ /// Only has an effect on `{kcfi_,}typeid_for_instance`.
+ const ERASE_SELF_TYPE = 8;
}
}
@@ -67,8 +67,13 @@ pub fn kcfi_typeid_for_fnabi<'tcx>(
pub fn kcfi_typeid_for_instance<'tcx>(
tcx: TyCtxt<'tcx>,
instance: Instance<'tcx>,
- options: TypeIdOptions,
+ mut options: TypeIdOptions,
) -> u32 {
+ // If we receive a `ReifyShim` intended to produce a function pointer, we need to remain
+ // concrete - abstraction is for vtables.
+ if matches!(instance.def, InstanceDef::ReifyShim(_, Some(ReifyReason::FnPtr))) {
+ options.remove(TypeIdOptions::ERASE_SELF_TYPE);
+ }
// A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the
// xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.)
let mut hash: XxHash64 = Default::default();
diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
index 85f1cd27cde..c632712f5a9 100644
--- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
@@ -1098,7 +1098,7 @@ pub fn typeid_for_instance<'tcx>(
instance.args = tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1));
}
- if !options.contains(EncodeTyOptions::NO_SELF_TYPE_ERASURE) {
+ if options.contains(EncodeTyOptions::ERASE_SELF_TYPE) {
if let Some(impl_id) = tcx.impl_of_method(instance.def_id())
&& let Some(trait_ref) = tcx.impl_trait_ref(impl_id)
{
@@ -1144,22 +1144,35 @@ pub fn typeid_for_instance<'tcx>(
let trait_id = tcx.fn_trait_kind_to_def_id(closure_args.kind()).unwrap();
let tuple_args =
tcx.instantiate_bound_regions_with_erased(closure_args.sig()).inputs()[0];
- (trait_id, tuple_args)
+ (trait_id, Some(tuple_args))
}
- ty::Coroutine(..) => (
- tcx.require_lang_item(LangItem::Coroutine, None),
- instance.args.as_coroutine().resume_ty(),
- ),
+ ty::Coroutine(..) => match tcx.coroutine_kind(instance.def_id()).unwrap() {
+ hir::CoroutineKind::Coroutine(..) => (
+ tcx.require_lang_item(LangItem::Coroutine, None),
+ Some(instance.args.as_coroutine().resume_ty()),
+ ),
+ hir::CoroutineKind::Desugared(desugaring, _) => {
+ let lang_item = match desugaring {
+ hir::CoroutineDesugaring::Async => LangItem::Future,
+ hir::CoroutineDesugaring::AsyncGen => LangItem::AsyncIterator,
+ hir::CoroutineDesugaring::Gen => LangItem::Iterator,
+ };
+ (tcx.require_lang_item(lang_item, None), None)
+ }
+ },
ty::CoroutineClosure(..) => (
tcx.require_lang_item(LangItem::FnOnce, None),
- tcx.instantiate_bound_regions_with_erased(
- instance.args.as_coroutine_closure().coroutine_closure_sig(),
- )
- .tupled_inputs_ty,
+ Some(
+ tcx.instantiate_bound_regions_with_erased(
+ instance.args.as_coroutine_closure().coroutine_closure_sig(),
+ )
+ .tupled_inputs_ty,
+ ),
),
x => bug!("Unexpected type kind for closure-like: {x:?}"),
};
- let trait_ref = ty::TraitRef::new(tcx, trait_id, [closure_ty, inputs]);
+ let concrete_args = tcx.mk_args_trait(closure_ty, inputs.map(Into::into));
+ let trait_ref = ty::TraitRef::new(tcx, trait_id, concrete_args);
let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref));
let abstract_args = tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1));
// There should be exactly one method on this trait, and it should be the one we're
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 4369f020d27..8cb5370bb4a 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -8,8 +8,8 @@ use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::print::{Print, PrintError, Printer};
use rustc_middle::ty::{
- self, EarlyBinder, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeVisitable, TypeVisitableExt,
- UintTy,
+ self, EarlyBinder, FloatTy, Instance, IntTy, ReifyReason, Ty, TyCtxt, TypeVisitable,
+ TypeVisitableExt, UintTy,
};
use rustc_middle::ty::{GenericArg, GenericArgKind};
use rustc_span::symbol::kw;
@@ -44,7 +44,9 @@ pub(super) fn mangle<'tcx>(
let shim_kind = match instance.def {
ty::InstanceDef::ThreadLocalShim(_) => Some("tls"),
ty::InstanceDef::VTableShim(_) => Some("vtable"),
- ty::InstanceDef::ReifyShim(_) => Some("reify"),
+ ty::InstanceDef::ReifyShim(_, None) => Some("reify"),
+ ty::InstanceDef::ReifyShim(_, Some(ReifyReason::FnPtr)) => Some("reify-fnptr"),
+ ty::InstanceDef::ReifyShim(_, Some(ReifyReason::Vtable)) => Some("reify-vtable"),
ty::InstanceDef::ConstructCoroutineInClosureShim { .. }
| ty::InstanceDef::CoroutineKindShim { .. } => Some("fn_once"),