mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-08 01:28:18 +03:00
Avoid having traits in rustc_type_ir for FnSigKind and Abi
Instead, just use the concrete types `FnSigKind` and `rustc_abi::ExternAbi`. This simplifies the code in both rustc and rust-analyzer.
This commit is contained in:
@@ -1085,8 +1085,9 @@ fn suggest_deref_closure_return(&self, diag: &mut Diag<'_>) {
|
||||
}
|
||||
|
||||
// Build a new closure where the return type is an owned value, instead of a ref.
|
||||
let fn_sig_kind =
|
||||
FnSigKind::default().set_safe(true).set_c_variadic(liberated_sig.c_variadic());
|
||||
let fn_sig_kind = FnSigKind::default()
|
||||
.set_safety(hir::Safety::Safe)
|
||||
.set_c_variadic(liberated_sig.c_variadic());
|
||||
let closure_sig_as_fn_ptr_ty = Ty::new_fn_ptr(
|
||||
tcx,
|
||||
ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
|
||||
@@ -3590,7 +3590,7 @@ pub fn lower_fn_ty(
|
||||
|
||||
let fn_sig_kind = FnSigKind::default()
|
||||
.set_abi(abi)
|
||||
.set_safe(safety.is_safe())
|
||||
.set_safety(safety)
|
||||
.set_c_variadic(decl.fn_decl_kind.c_variadic());
|
||||
let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, fn_sig_kind);
|
||||
let fn_ptr_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
|
||||
|
||||
@@ -723,7 +723,7 @@ fn sig_of_closure_with_expectation(
|
||||
let bound_sig = expected_sig.sig.map_bound(|sig| {
|
||||
let fn_sig_kind = FnSigKind::default()
|
||||
.set_abi(ExternAbi::RustCall)
|
||||
.set_safe(true)
|
||||
.set_safety(hir::Safety::Safe)
|
||||
.set_c_variadic(sig.c_variadic());
|
||||
self.tcx.mk_fn_sig(sig.inputs().iter().cloned(), sig.output(), fn_sig_kind)
|
||||
});
|
||||
@@ -860,7 +860,7 @@ fn merge_supplied_sig_with_expectation(
|
||||
|
||||
let fn_sig_kind = FnSigKind::default()
|
||||
.set_abi(ExternAbi::RustCall)
|
||||
.set_safe(true)
|
||||
.set_safety(hir::Safety::Safe)
|
||||
.set_c_variadic(expected_sigs.liberated_sig.c_variadic());
|
||||
expected_sigs.liberated_sig =
|
||||
self.tcx.mk_fn_sig(inputs, supplied_output_ty, fn_sig_kind);
|
||||
@@ -935,7 +935,7 @@ fn supplied_sig_of_closure(
|
||||
|
||||
let fn_sig_kind = FnSigKind::default()
|
||||
.set_abi(ExternAbi::RustCall)
|
||||
.set_safe(true)
|
||||
.set_safety(hir::Safety::Safe)
|
||||
.set_c_variadic(decl.c_variadic());
|
||||
let result = ty::Binder::bind_with_vars(
|
||||
self.tcx.mk_fn_sig(supplied_arguments, supplied_return, fn_sig_kind),
|
||||
@@ -1098,7 +1098,7 @@ fn error_sig_of_closure(
|
||||
|
||||
let fn_sig_kind = FnSigKind::default()
|
||||
.set_abi(ExternAbi::RustCall)
|
||||
.set_safe(true)
|
||||
.set_safety(hir::Safety::Safe)
|
||||
.set_c_variadic(decl.c_variadic());
|
||||
let result = ty::Binder::dummy(self.tcx.mk_fn_sig(supplied_arguments, err_ty, fn_sig_kind));
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
|
||||
use rustc_type_ir::TyKind::*;
|
||||
pub use rustc_type_ir::lift::Lift;
|
||||
use rustc_type_ir::{CollectAndApply, FnSigKind, WithCachedTypeInfo, elaborate, search_graph};
|
||||
use rustc_type_ir::{CollectAndApply, WithCachedTypeInfo, elaborate, search_graph};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use crate::arena::Arena;
|
||||
@@ -66,11 +66,11 @@
|
||||
use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData, PredefinedOpaques};
|
||||
use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
|
||||
use crate::ty::{
|
||||
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
|
||||
GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, Pattern,
|
||||
PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicatePolarity,
|
||||
Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, ValTree, ValTreeKind,
|
||||
Visibility,
|
||||
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, FnSigKind, GenericArg,
|
||||
GenericArgs, GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst,
|
||||
Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind,
|
||||
PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
|
||||
ValTree, ValTreeKind, Visibility,
|
||||
};
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
|
||||
@@ -83,50 +83,6 @@ fn as_local(self) -> Option<LocalDefId> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::FSigKind<TyCtxt<'tcx>> for FnSigKind {
|
||||
fn fn_sig_kind(self) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
fn new(abi: ExternAbi, safety: hir::Safety, c_variadic: bool) -> Self {
|
||||
FnSigKind::default().set_abi(abi).set_safe(safety.is_safe()).set_c_variadic(c_variadic)
|
||||
}
|
||||
|
||||
fn abi(self) -> ExternAbi {
|
||||
self.abi()
|
||||
}
|
||||
|
||||
fn safety(self) -> hir::Safety {
|
||||
if self.is_safe() { hir::Safety::Safe } else { hir::Safety::Unsafe }
|
||||
}
|
||||
|
||||
fn c_variadic(self) -> bool {
|
||||
self.c_variadic()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for ExternAbi {
|
||||
fn abi(self) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
fn rust() -> Self {
|
||||
ExternAbi::Rust
|
||||
}
|
||||
|
||||
fn is_rust(self) -> bool {
|
||||
matches!(self, ExternAbi::Rust)
|
||||
}
|
||||
|
||||
fn pack_abi(self) -> u8 {
|
||||
self.as_packed()
|
||||
}
|
||||
|
||||
fn unpack_abi(abi_index: u8) -> Self {
|
||||
Self::from_packed(abi_index)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
|
||||
fn safe() -> Self {
|
||||
hir::Safety::Safe
|
||||
@@ -1335,7 +1291,7 @@ pub fn adjust_target_feature_sig(
|
||||
let caller_features = &self.body_codegen_attrs(caller).target_features;
|
||||
if self.is_target_feature_call_safe(&fun_features, &caller_features) {
|
||||
return Some(fun_sig.map_bound(|sig| ty::FnSig {
|
||||
fn_sig_kind: fun_sig.fn_sig_kind().set_safe(true),
|
||||
fn_sig_kind: fun_sig.fn_sig_kind().set_safety(hir::Safety::Safe),
|
||||
..sig
|
||||
}));
|
||||
}
|
||||
@@ -2104,7 +2060,10 @@ pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
|
||||
assert!(sig.safety().is_safe());
|
||||
Ty::new_fn_ptr(
|
||||
self,
|
||||
sig.map_bound(|sig| ty::FnSig { fn_sig_kind: sig.fn_sig_kind.set_safe(false), ..sig }),
|
||||
sig.map_bound(|sig| ty::FnSig {
|
||||
fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
|
||||
..sig
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2113,7 +2072,10 @@ pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
|
||||
/// unsafe.
|
||||
pub fn safe_to_unsafe_sig(self, sig: PolyFnSig<'tcx>) -> PolyFnSig<'tcx> {
|
||||
assert!(sig.safety().is_safe());
|
||||
sig.map_bound(|sig| ty::FnSig { fn_sig_kind: sig.fn_sig_kind.set_safe(false), ..sig })
|
||||
sig.map_bound(|sig| ty::FnSig {
|
||||
fn_sig_kind: sig.fn_sig_kind.set_safety(hir::Safety::Unsafe),
|
||||
..sig
|
||||
})
|
||||
}
|
||||
|
||||
/// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
|
||||
@@ -2158,7 +2120,7 @@ pub fn signature_unclosure(self, sig: PolyFnSig<'tcx>, safety: hir::Safety) -> P
|
||||
self.mk_fn_sig(
|
||||
params,
|
||||
s.output(),
|
||||
s.fn_sig_kind.set_safe(safety.is_safe()).set_abi(ExternAbi::Rust),
|
||||
s.fn_sig_kind.set_safety(safety).set_abi(ExternAbi::Rust),
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -2417,7 +2379,12 @@ pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
|
||||
// IntoIterator` instead of `I: Iterator`, and it doesn't have a slice
|
||||
// variant, because of the need to combine `inputs` and `output`. This
|
||||
// explains the lack of `_from_iter` suffix.
|
||||
pub fn mk_fn_sig<I, T>(self, inputs: I, output: I::Item, fn_sig_kind: FnSigKind) -> T::Output
|
||||
pub fn mk_fn_sig<I, T>(
|
||||
self,
|
||||
inputs: I,
|
||||
output: I::Item,
|
||||
fn_sig_kind: FnSigKind<'tcx>,
|
||||
) -> T::Output
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
|
||||
@@ -2439,7 +2406,7 @@ pub fn mk_fn_sig_rust_abi<I, T>(
|
||||
I: IntoIterator<Item = T>,
|
||||
T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
|
||||
{
|
||||
self.mk_fn_sig(inputs, output, FnSigKind::default().set_safe(safety.is_safe()))
|
||||
self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(safety))
|
||||
}
|
||||
|
||||
/// `mk_fn_sig`, but with a safe Rust ABI, and no C-variadic argument.
|
||||
@@ -2448,7 +2415,7 @@ pub fn mk_fn_sig_safe_rust_abi<I, T>(self, inputs: I, output: I::Item) -> T::Out
|
||||
I: IntoIterator<Item = T>,
|
||||
T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>,
|
||||
{
|
||||
self.mk_fn_sig(inputs, output, FnSigKind::default().set_safe(true))
|
||||
self.mk_fn_sig(inputs, output, FnSigKind::default().set_safety(hir::Safety::Safe))
|
||||
}
|
||||
|
||||
pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
use std::{debug_assert_matches, fmt};
|
||||
|
||||
use rustc_abi::ExternAbi;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
|
||||
@@ -10,9 +9,7 @@
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_span::{DUMMY_SP, Span, Symbol};
|
||||
use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem};
|
||||
use rustc_type_ir::{
|
||||
CollectAndApply, FnSigKind, Interner, TypeFoldable, Unnormalized, search_graph,
|
||||
};
|
||||
use rustc_type_ir::{CollectAndApply, Interner, TypeFoldable, Unnormalized, search_graph};
|
||||
|
||||
use crate::dep_graph::{DepKind, DepNodeIndex};
|
||||
use crate::infer::canonical::CanonicalVarKinds;
|
||||
@@ -92,9 +89,7 @@ fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
|
||||
type AllocId = crate::mir::interpret::AllocId;
|
||||
type Pat = Pattern<'tcx>;
|
||||
type PatList = &'tcx List<Pattern<'tcx>>;
|
||||
type FSigKind = FnSigKind;
|
||||
type Safety = hir::Safety;
|
||||
type Abi = ExternAbi;
|
||||
type Const = ty::Const<'tcx>;
|
||||
type Consts = &'tcx List<Self::Const>;
|
||||
|
||||
|
||||
@@ -751,7 +751,7 @@ fn pretty_print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
|
||||
if self.tcx().codegen_fn_attrs(def_id).safe_target_features {
|
||||
write!(self, "#[target_features] ")?;
|
||||
sig = sig.map_bound(|mut sig| {
|
||||
sig.fn_sig_kind = sig.fn_sig_kind.set_safe(true);
|
||||
sig.fn_sig_kind = sig.fn_sig_kind.set_safety(hir::Safety::Safe);
|
||||
sig
|
||||
});
|
||||
}
|
||||
|
||||
@@ -198,7 +198,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
rustc_hir::Safety,
|
||||
rustc_middle::mir::ConstValue,
|
||||
rustc_type_ir::BoundConstness,
|
||||
rustc_type_ir::FnSigKind,
|
||||
rustc_type_ir::PredicatePolarity,
|
||||
// tidy-alphabetical-end
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
pub type AliasTy<'tcx> = ir::AliasTy<TyCtxt<'tcx>>;
|
||||
pub type AliasTyKind<'tcx> = ir::AliasTyKind<TyCtxt<'tcx>>;
|
||||
pub type FnSig<'tcx> = ir::FnSig<TyCtxt<'tcx>>;
|
||||
pub type FnSigKind = ir::FnSigKind;
|
||||
pub type FnSigKind<'tcx> = ir::FnSigKind<TyCtxt<'tcx>>;
|
||||
pub type Binder<'tcx, T> = ir::Binder<TyCtxt<'tcx>, T>;
|
||||
pub type EarlyBinder<'tcx, T> = ir::EarlyBinder<TyCtxt<'tcx>, T>;
|
||||
pub type Unnormalized<'tcx, T> = ir::Unnormalized<TyCtxt<'tcx>, T>;
|
||||
|
||||
@@ -314,7 +314,7 @@ fn internal<'tcx>(
|
||||
) -> Self::T<'tcx> {
|
||||
let fn_sig_kind = rustc_ty::FnSigKind::default()
|
||||
.set_abi(self.abi.internal(tables, tcx))
|
||||
.set_safe(self.safety == Safety::Safe)
|
||||
.set_safety(self.safety.internal(tables, tcx))
|
||||
.set_c_variadic(self.c_variadic);
|
||||
tcx.lift(rustc_ty::FnSig {
|
||||
inputs_and_output: tcx.mk_type_list(&self.inputs_and_output.internal(tables, tcx)),
|
||||
|
||||
@@ -257,7 +257,7 @@ fn stable<'cx>(
|
||||
|
||||
// This internal type isn't publicly exposed, because it is an implementation detail.
|
||||
// But it's a public field of FnSig (which has a public mirror type), so allow conversions.
|
||||
impl<'tcx> Stable<'tcx> for ty::FnSigKind {
|
||||
impl<'tcx> Stable<'tcx> for ty::FnSigKind<'tcx> {
|
||||
type T = (bool /*c_variadic*/, crate::mir::Safety, crate::ty::Abi);
|
||||
fn stable<'cx>(
|
||||
&self,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use derive_where::derive_where;
|
||||
use rustc_abi::ExternAbi;
|
||||
use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
|
||||
use crate::solve::NoSolution;
|
||||
@@ -25,7 +26,7 @@ pub enum TypeError<I: Interner> {
|
||||
Mismatch,
|
||||
PolarityMismatch(#[type_visitable(ignore)] ExpectedFound<ty::PredicatePolarity>),
|
||||
SafetyMismatch(#[type_visitable(ignore)] ExpectedFound<I::Safety>),
|
||||
AbiMismatch(#[type_visitable(ignore)] ExpectedFound<I::Abi>),
|
||||
AbiMismatch(#[type_visitable(ignore)] ExpectedFound<ExternAbi>),
|
||||
Mutability,
|
||||
ArgumentMutability(usize),
|
||||
TupleSize(ExpectedFound<usize>),
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
use smallvec::SmallVec;
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
use crate::Interner;
|
||||
|
||||
/// This trait is implemented for every type that can be visited,
|
||||
/// providing the skeleton of the traversal.
|
||||
///
|
||||
@@ -210,5 +212,9 @@ fn generic_visit_with(&self, _visitor: &mut V) {}
|
||||
rustc_hash::FxBuildHasher,
|
||||
crate::TypeFlags,
|
||||
crate::solve::GoalSource,
|
||||
crate::FnSigKind,
|
||||
rustc_abi::ExternAbi,
|
||||
);
|
||||
|
||||
impl<I: Interner, V> GenericTypeVisitable<V> for crate::FnSigKind<I> {
|
||||
fn generic_visit_with(&self, _visitor: &mut V) {}
|
||||
}
|
||||
|
||||
@@ -205,42 +205,6 @@ pub trait Tys<I: Interner<Tys = Self>>:
|
||||
fn output(self) -> I::Ty;
|
||||
}
|
||||
|
||||
#[rust_analyzer::prefer_underscore_import]
|
||||
pub trait FSigKind<I: Interner<FSigKind = Self>>: Copy + Debug + Hash + Eq {
|
||||
/// The identity function.
|
||||
fn fn_sig_kind(self) -> Self;
|
||||
|
||||
/// Create a new FnSigKind with the given ABI, safety, and C-style variadic flag.
|
||||
fn new(abi: I::Abi, safety: I::Safety, c_variadic: bool) -> Self;
|
||||
|
||||
/// Returns the ABI.
|
||||
fn abi(self) -> I::Abi;
|
||||
|
||||
/// Returns the safety mode.
|
||||
fn safety(self) -> I::Safety;
|
||||
|
||||
/// Do the function arguments end with a C-style variadic argument?
|
||||
fn c_variadic(self) -> bool;
|
||||
}
|
||||
|
||||
#[rust_analyzer::prefer_underscore_import]
|
||||
pub trait Abi<I: Interner<Abi = Self>>: Copy + Debug + Hash + Eq {
|
||||
/// The identity function.
|
||||
fn abi(self) -> Self;
|
||||
|
||||
/// The ABI `extern "Rust"`.
|
||||
fn rust() -> I::Abi;
|
||||
|
||||
/// Whether this ABI is `extern "Rust"`.
|
||||
fn is_rust(self) -> bool;
|
||||
|
||||
/// Pack the ABI into a small dense integer, so it can be stored as packed `FnSigKind` flags.
|
||||
fn pack_abi(self) -> u8;
|
||||
|
||||
/// Unpack the ABI from packed `FnSigKind` flags.
|
||||
fn unpack_abi(abi_index: u8) -> Self;
|
||||
}
|
||||
|
||||
#[rust_analyzer::prefer_underscore_import]
|
||||
pub trait Safety<I: Interner<Safety = Self>>: Copy + Debug + Hash + Eq {
|
||||
/// The `safe` safety mode.
|
||||
|
||||
@@ -145,9 +145,7 @@ fn mk_tracked<T: Debug + Clone>(
|
||||
+ Eq
|
||||
+ TypeVisitable<Self>
|
||||
+ SliceLike<Item = Self::Pat>;
|
||||
type FSigKind: FSigKind<Self>;
|
||||
type Safety: Safety<Self>;
|
||||
type Abi: Abi<Self>;
|
||||
|
||||
// Kinds of consts
|
||||
type Const: Const<Self>;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Deref;
|
||||
|
||||
use derive_where::derive_where;
|
||||
@@ -762,18 +763,31 @@ impl<I: Interner> Eq for TypeAndMut<I> {}
|
||||
|
||||
/// Contains the packed non-type fields of a function signature.
|
||||
// FIXME(splat): add the splatted argument index as a u16
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive_where(Copy, Clone, PartialEq, Eq, Hash; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
)]
|
||||
pub struct FnSigKind {
|
||||
pub struct FnSigKind<I: Interner> {
|
||||
/// Holds the c_variadic and safety bitflags, and 6 bits for the `ExternAbi` variant and unwind
|
||||
/// flag.
|
||||
#[type_visitable(ignore)]
|
||||
#[type_foldable(identity)]
|
||||
flags: u8,
|
||||
#[type_visitable(ignore)]
|
||||
#[type_foldable(identity)]
|
||||
_marker: PhantomData<fn() -> I>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for FnSigKind {
|
||||
impl<I: Interner, J: Interner> crate::lift::Lift<J> for FnSigKind<I> {
|
||||
type Lifted = FnSigKind<J>;
|
||||
fn lift_to_interner(self, _cx: J) -> Option<Self::Lifted> {
|
||||
Some(FnSigKind { flags: self.flags, _marker: PhantomData })
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> fmt::Debug for FnSigKind<I> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let mut f = f.debug_tuple("FnSigKind");
|
||||
|
||||
@@ -793,7 +807,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
}
|
||||
|
||||
impl FnSigKind {
|
||||
impl<I: Interner> FnSigKind<I> {
|
||||
/// Mask for the `ExternAbi` variant, including the unwind flag.
|
||||
const EXTERN_ABI_MASK: u8 = 0b111111;
|
||||
|
||||
@@ -806,13 +820,21 @@ impl FnSigKind {
|
||||
/// Create a new FnSigKind with the "Rust" ABI, "Unsafe" safety, and no C-style variadic argument.
|
||||
/// To modify these flags, use the `set_*` methods, for readability.
|
||||
// FIXME: use Default instead when that trait is const stable.
|
||||
pub const fn default() -> Self {
|
||||
Self { flags: 0 }.set_abi(ExternAbi::Rust).set_safe(false).set_c_variadic(false)
|
||||
pub fn default() -> Self {
|
||||
Self { flags: 0, _marker: PhantomData }
|
||||
.set_abi(ExternAbi::Rust)
|
||||
.set_safety(I::Safety::unsafe_mode())
|
||||
.set_c_variadic(false)
|
||||
}
|
||||
|
||||
/// Create a new FnSigKind with the given ABI, safety, and C-style variadic flag.
|
||||
pub fn new(abi: ExternAbi, safety: I::Safety, c_variadic: bool) -> Self {
|
||||
Self::default().set_abi(abi).set_safety(safety).set_c_variadic(c_variadic)
|
||||
}
|
||||
|
||||
/// Set the ABI, including the unwind flag.
|
||||
#[must_use = "this method does not modify the receiver"]
|
||||
pub const fn set_abi(mut self, abi: ExternAbi) -> Self {
|
||||
pub fn set_abi(mut self, abi: ExternAbi) -> Self {
|
||||
let abi_index = abi.as_packed();
|
||||
assert!(abi_index <= Self::EXTERN_ABI_MASK);
|
||||
|
||||
@@ -824,8 +846,8 @@ pub const fn set_abi(mut self, abi: ExternAbi) -> Self {
|
||||
|
||||
/// Set the safety flag, `true` is `Safe`.
|
||||
#[must_use = "this method does not modify the receiver"]
|
||||
pub const fn set_safe(mut self, is_safe: bool) -> Self {
|
||||
if is_safe {
|
||||
pub fn set_safety(mut self, safety: I::Safety) -> Self {
|
||||
if safety.is_safe() {
|
||||
self.flags |= Self::SAFE_FLAG;
|
||||
} else {
|
||||
self.flags &= !Self::SAFE_FLAG;
|
||||
@@ -836,7 +858,7 @@ pub const fn set_safe(mut self, is_safe: bool) -> Self {
|
||||
|
||||
/// Set the C-style variadic argument flag.
|
||||
#[must_use = "this method does not modify the receiver"]
|
||||
pub const fn set_c_variadic(mut self, c_variadic: bool) -> Self {
|
||||
pub fn set_c_variadic(mut self, c_variadic: bool) -> Self {
|
||||
if c_variadic {
|
||||
self.flags |= Self::C_VARIADIC_FLAG;
|
||||
} else {
|
||||
@@ -847,18 +869,23 @@ pub const fn set_c_variadic(mut self, c_variadic: bool) -> Self {
|
||||
}
|
||||
|
||||
/// Get the ABI, including the unwind flag.
|
||||
pub const fn abi(self) -> ExternAbi {
|
||||
pub fn abi(self) -> ExternAbi {
|
||||
let abi_index = self.flags & Self::EXTERN_ABI_MASK;
|
||||
ExternAbi::from_packed(abi_index)
|
||||
}
|
||||
|
||||
/// Get the safety flag.
|
||||
pub const fn is_safe(self) -> bool {
|
||||
pub fn is_safe(self) -> bool {
|
||||
self.flags & Self::SAFE_FLAG != 0
|
||||
}
|
||||
|
||||
/// Returns the safety mode.
|
||||
pub fn safety(self) -> I::Safety {
|
||||
if self.is_safe() { I::Safety::safe() } else { I::Safety::unsafe_mode() }
|
||||
}
|
||||
|
||||
/// Do the function arguments end with a C-style variadic argument?
|
||||
pub const fn c_variadic(self) -> bool {
|
||||
pub fn c_variadic(self) -> bool {
|
||||
self.flags & Self::C_VARIADIC_FLAG != 0
|
||||
}
|
||||
}
|
||||
@@ -873,7 +900,7 @@ pub struct FnSig<I: Interner> {
|
||||
pub inputs_and_output: I::Tys,
|
||||
#[type_visitable(ignore)]
|
||||
#[type_foldable(identity)]
|
||||
pub fn_sig_kind: I::FSigKind,
|
||||
pub fn_sig_kind: FnSigKind<I>,
|
||||
}
|
||||
|
||||
impl<I: Interner> Eq for FnSig<I> {}
|
||||
@@ -888,25 +915,18 @@ pub fn output(self) -> I::Ty {
|
||||
}
|
||||
|
||||
pub fn is_fn_trait_compatible(self) -> bool {
|
||||
!self.c_variadic() && self.safety().is_safe() && self.abi().is_rust()
|
||||
!self.c_variadic() && self.safety().is_safe() && self.abi() == ExternAbi::Rust
|
||||
}
|
||||
|
||||
pub fn set_safe(self, is_safe: bool) -> Self {
|
||||
Self {
|
||||
fn_sig_kind: I::FSigKind::new(
|
||||
self.abi(),
|
||||
if is_safe { I::Safety::safe() } else { I::Safety::unsafe_mode() },
|
||||
self.c_variadic(),
|
||||
),
|
||||
..self
|
||||
}
|
||||
pub fn set_safety(self, safety: I::Safety) -> Self {
|
||||
Self { fn_sig_kind: FnSigKind::new(self.abi(), safety, self.c_variadic()), ..self }
|
||||
}
|
||||
|
||||
pub fn safety(self) -> I::Safety {
|
||||
self.fn_sig_kind.safety()
|
||||
}
|
||||
|
||||
pub fn abi(self) -> I::Abi {
|
||||
pub fn abi(self) -> ExternAbi {
|
||||
self.fn_sig_kind.abi()
|
||||
}
|
||||
|
||||
@@ -917,7 +937,7 @@ pub fn c_variadic(self) -> bool {
|
||||
pub fn dummy() -> Self {
|
||||
Self {
|
||||
inputs_and_output: Default::default(),
|
||||
fn_sig_kind: I::FSigKind::new(I::Abi::rust(), I::Safety::safe(), false),
|
||||
fn_sig_kind: FnSigKind::new(ExternAbi::Rust, I::Safety::safe(), false),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -943,7 +963,7 @@ pub fn output(self) -> ty::Binder<I, I::Ty> {
|
||||
self.map_bound(|fn_sig| fn_sig.output())
|
||||
}
|
||||
|
||||
pub fn fn_sig_kind(self) -> I::FSigKind {
|
||||
pub fn fn_sig_kind(self) -> FnSigKind<I> {
|
||||
self.skip_binder().fn_sig_kind
|
||||
}
|
||||
|
||||
@@ -955,7 +975,7 @@ pub fn safety(self) -> I::Safety {
|
||||
self.skip_binder().safety()
|
||||
}
|
||||
|
||||
pub fn abi(self) -> I::Abi {
|
||||
pub fn abi(self) -> ExternAbi {
|
||||
self.skip_binder().abi()
|
||||
}
|
||||
|
||||
@@ -976,7 +996,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let FnSig { inputs_and_output: _, fn_sig_kind } = sig;
|
||||
|
||||
write!(f, "{}", fn_sig_kind.safety().prefix_str())?;
|
||||
if !fn_sig_kind.abi().is_rust() {
|
||||
if fn_sig_kind.abi() != ExternAbi::Rust {
|
||||
write!(f, "extern \"{:?}\" ", fn_sig_kind.abi())?;
|
||||
}
|
||||
|
||||
@@ -1131,7 +1151,7 @@ pub fn output(self) -> ty::Binder<I, I::Ty> {
|
||||
pub struct FnHeader<I: Interner> {
|
||||
#[type_visitable(ignore)]
|
||||
#[type_foldable(identity)]
|
||||
pub fn_sig_kind: I::FSigKind,
|
||||
pub fn_sig_kind: FnSigKind<I>,
|
||||
}
|
||||
|
||||
impl<I: Interner> FnHeader<I> {
|
||||
@@ -1143,12 +1163,12 @@ pub fn safety(self) -> I::Safety {
|
||||
self.fn_sig_kind.safety()
|
||||
}
|
||||
|
||||
pub fn abi(self) -> I::Abi {
|
||||
pub fn abi(self) -> ExternAbi {
|
||||
self.fn_sig_kind.abi()
|
||||
}
|
||||
|
||||
pub fn dummy() -> Self {
|
||||
Self { fn_sig_kind: I::FSigKind::new(I::Abi::rust(), I::Safety::safe(), false) }
|
||||
Self { fn_sig_kind: FnSigKind::new(ExternAbi::Rust, I::Safety::safe(), false) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
use crate::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable, shift_region};
|
||||
use crate::inherent::*;
|
||||
use crate::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
||||
use crate::{self as ty, Interner};
|
||||
use crate::{self as ty, FnSigKind, Interner};
|
||||
|
||||
/// A closure can be modeled as a struct that looks like:
|
||||
/// ```ignore (illustrative)
|
||||
@@ -367,7 +367,7 @@ pub struct CoroutineClosureSignature<I: Interner> {
|
||||
/// Always safe, RustCall, non-c-variadic
|
||||
#[type_visitable(ignore)]
|
||||
#[type_foldable(identity)]
|
||||
pub fn_sig_kind: I::FSigKind,
|
||||
pub fn_sig_kind: FnSigKind<I>,
|
||||
}
|
||||
|
||||
impl<I: Interner> Eq for CoroutineClosureSignature<I> {}
|
||||
|
||||
@@ -407,7 +407,7 @@ fn call_function(
|
||||
let sig = this.tcx.mk_fn_sig(
|
||||
args.iter().map(|a| a.layout.ty),
|
||||
dest.layout.ty,
|
||||
FnSigKind::default().set_abi(caller_abi).set_safe(true),
|
||||
FnSigKind::default().set_abi(caller_abi).set_safety(rustc_hir::Safety::Safe),
|
||||
);
|
||||
let caller_fn_abi = this.fn_abi_of_fn_ptr(ty::Binder::dummy(sig), ty::List::empty())?;
|
||||
|
||||
|
||||
@@ -275,7 +275,9 @@ fn check_shim_sig<'a, const N: usize>(
|
||||
let fn_sig_binder = Binder::dummy(FnSig {
|
||||
inputs_and_output: this.machine.tcx.mk_type_list(&inputs_and_output),
|
||||
// Safety does not matter for the ABI.
|
||||
fn_sig_kind: FnSigKind::default().set_abi(shim_sig.abi).set_safe(true),
|
||||
fn_sig_kind: FnSigKind::default()
|
||||
.set_abi(shim_sig.abi)
|
||||
.set_safety(rustc_hir::Safety::Safe),
|
||||
});
|
||||
let callee_fn_abi = this.fn_abi_of_fn_ptr(fn_sig_binder, Default::default())?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user