Uplift FnSig
This commit is contained in:
parent
1871252fc8
commit
312ba4da3c
11 changed files with 168 additions and 122 deletions
|
@ -112,6 +112,12 @@ impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::UnevaluatedConst
|
|||
}
|
||||
}
|
||||
|
||||
impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::FnSig<I> {
|
||||
fn into_diag_arg(self) -> rustc_errors::DiagArgValue {
|
||||
format!("{self:?}").into_diag_arg()
|
||||
}
|
||||
}
|
||||
|
||||
into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
|
||||
|
||||
impl IntoDiagArg for bool {
|
||||
|
|
|
@ -3191,7 +3191,7 @@ pub enum Unsafety {
|
|||
}
|
||||
|
||||
impl Unsafety {
|
||||
pub fn prefix_str(&self) -> &'static str {
|
||||
pub fn prefix_str(self) -> &'static str {
|
||||
match self {
|
||||
Self::Unsafe => "unsafe ",
|
||||
Self::Normal => "",
|
||||
|
|
|
@ -92,7 +92,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>;
|
||||
type AdtDef = ty::AdtDef<'tcx>;
|
||||
type GenericArgs = ty::GenericArgsRef<'tcx>;
|
||||
type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
|
||||
type OwnItemArgs = &'tcx [ty::GenericArg<'tcx>];
|
||||
type GenericArg = ty::GenericArg<'tcx>;
|
||||
|
||||
type Term = ty::Term<'tcx>;
|
||||
|
@ -103,6 +103,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
type CanonicalVars = CanonicalVarInfos<'tcx>;
|
||||
type Ty = Ty<'tcx>;
|
||||
type Tys = &'tcx List<Ty<'tcx>>;
|
||||
type FnInputTys = &'tcx [Ty<'tcx>];
|
||||
type ParamTy = ParamTy;
|
||||
type BoundTy = ty::BoundTy;
|
||||
type PlaceholderTy = ty::PlaceholderType;
|
||||
|
@ -113,21 +114,24 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
type AllocId = crate::mir::interpret::AllocId;
|
||||
|
||||
type Pat = Pattern<'tcx>;
|
||||
type Unsafety = hir::Unsafety;
|
||||
type Abi = abi::Abi;
|
||||
|
||||
type Const = ty::Const<'tcx>;
|
||||
type AliasConst = ty::UnevaluatedConst<'tcx>;
|
||||
type PlaceholderConst = ty::PlaceholderConst;
|
||||
type ParamConst = ty::ParamConst;
|
||||
type BoundConst = ty::BoundVar;
|
||||
type ValueConst = ty::ValTree<'tcx>;
|
||||
|
||||
type ExprConst = ty::Expr<'tcx>;
|
||||
|
||||
type Region = Region<'tcx>;
|
||||
type EarlyParamRegion = ty::EarlyParamRegion;
|
||||
type LateParamRegion = ty::LateParamRegion;
|
||||
type BoundRegion = ty::BoundRegion;
|
||||
type InferRegion = ty::RegionVid;
|
||||
|
||||
type PlaceholderRegion = ty::PlaceholderRegion;
|
||||
|
||||
type Predicate = Predicate<'tcx>;
|
||||
type TraitPredicate = ty::TraitPredicate<'tcx>;
|
||||
type RegionOutlivesPredicate = ty::RegionOutlivesPredicate<'tcx>;
|
||||
|
@ -135,10 +139,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
type ProjectionPredicate = ty::ProjectionPredicate<'tcx>;
|
||||
type NormalizesTo = ty::NormalizesTo<'tcx>;
|
||||
type SubtypePredicate = ty::SubtypePredicate<'tcx>;
|
||||
|
||||
type CoercePredicate = ty::CoercePredicate<'tcx>;
|
||||
type ClosureKind = ty::ClosureKind;
|
||||
|
||||
type Clauses = ty::Clauses<'tcx>;
|
||||
|
||||
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
|
||||
self.mk_canonical_var_infos(infos)
|
||||
}
|
||||
|
@ -191,7 +197,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
self,
|
||||
def_id: Self::DefId,
|
||||
args: Self::GenericArgs,
|
||||
) -> (rustc_type_ir::TraitRef<Self>, Self::GenericArgsSlice) {
|
||||
) -> (rustc_type_ir::TraitRef<Self>, Self::OwnItemArgs) {
|
||||
assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
|
||||
let trait_def_id = self.parent(def_id);
|
||||
assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
|
||||
|
@ -223,6 +229,18 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for abi::Abi {
|
||||
fn is_rust(self) -> bool {
|
||||
matches!(self, abi::Abi::Rust)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::Unsafety<TyCtxt<'tcx>> for hir::Unsafety {
|
||||
fn prefix_str(self) -> &'static str {
|
||||
self.prefix_str()
|
||||
}
|
||||
}
|
||||
|
||||
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
|
||||
|
||||
pub struct CtxtInterners<'tcx> {
|
||||
|
|
|
@ -3034,6 +3034,16 @@ forward_display_to_print! {
|
|||
define_print! {
|
||||
(self, cx):
|
||||
|
||||
ty::FnSig<'tcx> {
|
||||
p!(write("{}", self.unsafety.prefix_str()));
|
||||
|
||||
if self.abi != Abi::Rust {
|
||||
p!(write("extern {} ", self.abi));
|
||||
}
|
||||
|
||||
p!("fn", pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
|
||||
}
|
||||
|
||||
ty::TraitRef<'tcx> {
|
||||
p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
|
||||
}
|
||||
|
@ -3169,16 +3179,6 @@ define_print_and_forward_display! {
|
|||
p!("{{", comma_sep(self.iter()), "}}")
|
||||
}
|
||||
|
||||
ty::FnSig<'tcx> {
|
||||
p!(write("{}", self.unsafety.prefix_str()));
|
||||
|
||||
if self.abi != Abi::Rust {
|
||||
p!(write("extern {} ", self.abi));
|
||||
}
|
||||
|
||||
p!("fn", pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
|
||||
}
|
||||
|
||||
TraitRefPrintOnlyTraitPath<'tcx> {
|
||||
p!(print_def_path(self.0.def_id, self.0.args));
|
||||
}
|
||||
|
|
|
@ -83,49 +83,6 @@ impl fmt::Debug for ty::LateParamRegion {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for ty::FnSig<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
WithInfcx::with_no_infcx(self).fmt(f)
|
||||
}
|
||||
}
|
||||
impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::FnSig<'tcx> {
|
||||
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
||||
this: WithInfcx<'_, Infcx, &Self>,
|
||||
f: &mut core::fmt::Formatter<'_>,
|
||||
) -> core::fmt::Result {
|
||||
let sig = this.data;
|
||||
let ty::FnSig { inputs_and_output: _, c_variadic, unsafety, abi } = sig;
|
||||
|
||||
write!(f, "{}", unsafety.prefix_str())?;
|
||||
match abi {
|
||||
rustc_target::spec::abi::Abi::Rust => (),
|
||||
abi => write!(f, "extern \"{abi:?}\" ")?,
|
||||
};
|
||||
|
||||
write!(f, "fn(")?;
|
||||
let inputs = sig.inputs();
|
||||
match inputs.len() {
|
||||
0 if *c_variadic => write!(f, "...)")?,
|
||||
0 => write!(f, ")")?,
|
||||
_ => {
|
||||
for ty in &sig.inputs()[0..(sig.inputs().len() - 1)] {
|
||||
write!(f, "{:?}, ", &this.wrap(ty))?;
|
||||
}
|
||||
write!(f, "{:?}", &this.wrap(sig.inputs().last().unwrap()))?;
|
||||
if *c_variadic {
|
||||
write!(f, "...")?;
|
||||
}
|
||||
write!(f, ")")?;
|
||||
}
|
||||
}
|
||||
|
||||
match sig.output().kind() {
|
||||
ty::Tuple(list) if list.is_empty() => Ok(()),
|
||||
_ => write!(f, " -> {:?}", &this.wrap(sig.output())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ty::DebugWithInfcx<TyCtxt<'tcx>> for Ty<'tcx> {
|
||||
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
||||
this: WithInfcx<'_, Infcx, &Self>,
|
||||
|
|
|
@ -39,6 +39,7 @@ use super::GenericParamDefKind;
|
|||
pub type TyKind<'tcx> = ir::TyKind<TyCtxt<'tcx>>;
|
||||
pub type TypeAndMut<'tcx> = ir::TypeAndMut<TyCtxt<'tcx>>;
|
||||
pub type AliasTy<'tcx> = ir::AliasTy<TyCtxt<'tcx>>;
|
||||
pub type FnSig<'tcx> = ir::FnSig<TyCtxt<'tcx>>;
|
||||
|
||||
pub trait Article {
|
||||
fn article(&self) -> &'static str;
|
||||
|
@ -985,14 +986,6 @@ impl<'tcx, T> Binder<'tcx, T> {
|
|||
Binder { value: &self.value, bound_vars: self.bound_vars }
|
||||
}
|
||||
|
||||
pub fn map_bound_ref_unchecked<F, U>(&self, f: F) -> Binder<'tcx, U>
|
||||
where
|
||||
F: FnOnce(&T) -> U,
|
||||
{
|
||||
let value = f(&self.value);
|
||||
Binder { value, bound_vars: self.bound_vars }
|
||||
}
|
||||
|
||||
pub fn map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U>
|
||||
where
|
||||
F: FnOnce(&T) -> U,
|
||||
|
@ -1109,73 +1102,37 @@ pub struct GenSig<'tcx> {
|
|||
pub return_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
/// Signature of a function type, which we have arbitrarily
|
||||
/// decided to use to refer to the input/output types.
|
||||
///
|
||||
/// - `inputs`: is the list of arguments and their modes.
|
||||
/// - `output`: is the return type.
|
||||
/// - `c_variadic`: indicates whether this is a C-variadic function.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
|
||||
pub struct FnSig<'tcx> {
|
||||
pub inputs_and_output: &'tcx List<Ty<'tcx>>,
|
||||
pub c_variadic: bool,
|
||||
pub unsafety: hir::Unsafety,
|
||||
pub abi: abi::Abi,
|
||||
}
|
||||
|
||||
impl<'tcx> FnSig<'tcx> {
|
||||
pub fn inputs(&self) -> &'tcx [Ty<'tcx>] {
|
||||
&self.inputs_and_output[..self.inputs_and_output.len() - 1]
|
||||
}
|
||||
|
||||
pub fn output(&self) -> Ty<'tcx> {
|
||||
self.inputs_and_output[self.inputs_and_output.len() - 1]
|
||||
}
|
||||
|
||||
// Creates a minimal `FnSig` to be used when encountering a `TyKind::Error` in a fallible
|
||||
// method.
|
||||
fn fake() -> FnSig<'tcx> {
|
||||
FnSig {
|
||||
inputs_and_output: List::empty(),
|
||||
c_variadic: false,
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
abi: abi::Abi::Rust,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> IntoDiagArg for FnSig<'tcx> {
|
||||
fn into_diag_arg(self) -> DiagArgValue {
|
||||
self.to_string().into_diag_arg()
|
||||
}
|
||||
}
|
||||
|
||||
pub type PolyFnSig<'tcx> = Binder<'tcx, FnSig<'tcx>>;
|
||||
|
||||
impl<'tcx> PolyFnSig<'tcx> {
|
||||
#[inline]
|
||||
pub fn inputs(&self) -> Binder<'tcx, &'tcx [Ty<'tcx>]> {
|
||||
self.map_bound_ref_unchecked(|fn_sig| fn_sig.inputs())
|
||||
self.map_bound_ref(|fn_sig| fn_sig.inputs())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
pub fn input(&self, index: usize) -> ty::Binder<'tcx, Ty<'tcx>> {
|
||||
self.map_bound_ref(|fn_sig| fn_sig.inputs()[index])
|
||||
}
|
||||
|
||||
pub fn inputs_and_output(&self) -> ty::Binder<'tcx, &'tcx List<Ty<'tcx>>> {
|
||||
self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn output(&self) -> ty::Binder<'tcx, Ty<'tcx>> {
|
||||
self.map_bound_ref(|fn_sig| fn_sig.output())
|
||||
}
|
||||
|
||||
pub fn c_variadic(&self) -> bool {
|
||||
self.skip_binder().c_variadic
|
||||
}
|
||||
|
||||
pub fn unsafety(&self) -> hir::Unsafety {
|
||||
self.skip_binder().unsafety
|
||||
}
|
||||
|
||||
pub fn abi(&self) -> abi::Abi {
|
||||
self.skip_binder().abi
|
||||
}
|
||||
|
@ -2031,7 +1988,12 @@ impl<'tcx> Ty<'tcx> {
|
|||
FnPtr(f) => *f,
|
||||
Error(_) => {
|
||||
// ignore errors (#54954)
|
||||
ty::Binder::dummy(FnSig::fake())
|
||||
ty::Binder::dummy(ty::FnSig {
|
||||
inputs_and_output: ty::List::empty(),
|
||||
c_variadic: false,
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
abi: abi::Abi::Rust,
|
||||
})
|
||||
}
|
||||
Closure(..) => bug!(
|
||||
"to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",
|
||||
|
@ -2624,6 +2586,13 @@ impl<'tcx> Ty<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::Tys<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> {
|
||||
fn split_inputs_and_output(self) -> (&'tcx [Ty<'tcx>], Ty<'tcx>) {
|
||||
let (output, inputs) = self.split_last().unwrap();
|
||||
(inputs, *output)
|
||||
}
|
||||
}
|
||||
|
||||
/// Extra information about why we ended up with a particular variance.
|
||||
/// This is only used to add more information to error messages, and
|
||||
/// has no effect on soundness. While choosing the 'wrong' `VarianceDiagInfo`
|
||||
|
|
|
@ -26,6 +26,21 @@ pub trait Ty<I: Interner<Ty = Self>>:
|
|||
fn new_alias(interner: I, kind: AliasTyKind, alias_ty: AliasTy<I>) -> Self;
|
||||
}
|
||||
|
||||
pub trait Tys<I: Interner<Tys = Self>>:
|
||||
Copy + Debug + Hash + Eq + IntoIterator<Item = I::Ty> + Deref<Target: Deref<Target = [I::Ty]>>
|
||||
{
|
||||
fn split_inputs_and_output(self) -> (I::FnInputTys, I::Ty);
|
||||
}
|
||||
|
||||
pub trait Abi<I: Interner<Abi = Self>>: Copy + Debug + Hash + Eq {
|
||||
/// Whether this ABI is `extern "Rust"`.
|
||||
fn is_rust(self) -> bool;
|
||||
}
|
||||
|
||||
pub trait Unsafety<I: Interner<Unsafety = Self>>: Copy + Debug + Hash + Eq {
|
||||
fn prefix_str(self) -> &'static str;
|
||||
}
|
||||
|
||||
pub trait Region<I: Interner<Region = Self>>:
|
||||
Copy + DebugWithInfcx<I> + Hash + Eq + Into<I::GenericArg> + IntoKind<Kind = RegionKind<I>> + Flags
|
||||
{
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
use smallvec::SmallVec;
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
use std::ops::Deref;
|
||||
|
||||
use crate::inherent::*;
|
||||
use crate::ir_print::IrPrint;
|
||||
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
||||
use crate::{
|
||||
AliasTerm, AliasTermKind, AliasTy, AliasTyKind, CanonicalVarInfo, CoercePredicate,
|
||||
DebugWithInfcx, ExistentialProjection, ExistentialTraitRef, NormalizesTo, ProjectionPredicate,
|
||||
SubtypePredicate, TraitPredicate, TraitRef,
|
||||
DebugWithInfcx, ExistentialProjection, ExistentialTraitRef, FnSig, NormalizesTo,
|
||||
ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef,
|
||||
};
|
||||
|
||||
pub trait Interner:
|
||||
|
@ -24,13 +25,16 @@ pub trait Interner:
|
|||
+ IrPrint<NormalizesTo<Self>>
|
||||
+ IrPrint<SubtypePredicate<Self>>
|
||||
+ IrPrint<CoercePredicate<Self>>
|
||||
+ IrPrint<FnSig<Self>>
|
||||
{
|
||||
type DefId: Copy + Debug + Hash + Eq;
|
||||
type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable<Self>;
|
||||
type AdtDef: Copy + Debug + Hash + Eq;
|
||||
|
||||
type GenericArgs: GenericArgs<Self>;
|
||||
type GenericArgsSlice: Copy + Debug + Hash + Eq;
|
||||
/// The slice of args for a specific item. For a GAT like `type Foo<'a>`, it will be `['a]`,
|
||||
/// not including the args from the parent item (trait or impl).
|
||||
type OwnItemArgs: Copy + Debug + Hash + Eq;
|
||||
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
||||
type Term: Copy + Debug + Hash + Eq;
|
||||
|
||||
|
@ -42,7 +46,8 @@ pub trait Interner:
|
|||
|
||||
// Kinds of tys
|
||||
type Ty: Ty<Self>;
|
||||
type Tys: Copy + Debug + Hash + Eq + IntoIterator<Item = Self::Ty>;
|
||||
type Tys: Tys<Self>;
|
||||
type FnInputTys: Copy + Debug + Hash + Eq + Deref<Target = [Self::Ty]>;
|
||||
type ParamTy: Copy + Debug + Hash + Eq;
|
||||
type BoundTy: Copy + Debug + Hash + Eq;
|
||||
type PlaceholderTy: PlaceholderLike;
|
||||
|
@ -53,6 +58,8 @@ pub trait Interner:
|
|||
type PolyFnSig: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
||||
type AllocId: Copy + Debug + Hash + Eq;
|
||||
type Pat: Copy + Debug + Hash + Eq + DebugWithInfcx<Self>;
|
||||
type Unsafety: Unsafety<Self>;
|
||||
type Abi: Abi<Self>;
|
||||
|
||||
// Kinds of consts
|
||||
type Const: Const<Self>;
|
||||
|
@ -99,7 +106,7 @@ pub trait Interner:
|
|||
self,
|
||||
def_id: Self::DefId,
|
||||
args: Self::GenericArgs,
|
||||
) -> (TraitRef<Self>, Self::GenericArgsSlice);
|
||||
) -> (TraitRef<Self>, Self::OwnItemArgs);
|
||||
|
||||
fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs;
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::fmt;
|
||||
|
||||
use crate::{
|
||||
AliasTerm, AliasTy, CoercePredicate, ExistentialProjection, ExistentialTraitRef, Interner,
|
||||
NormalizesTo, ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef,
|
||||
AliasTerm, AliasTy, CoercePredicate, ExistentialProjection, ExistentialTraitRef, FnSig,
|
||||
Interner, NormalizesTo, ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef,
|
||||
};
|
||||
|
||||
pub trait IrPrint<T> {
|
||||
|
@ -45,6 +45,7 @@ define_display_via_print!(
|
|||
CoercePredicate,
|
||||
AliasTy,
|
||||
AliasTerm,
|
||||
FnSig,
|
||||
);
|
||||
|
||||
define_debug_via_print!(TraitRef, ExistentialTraitRef, ExistentialProjection);
|
||||
|
|
|
@ -497,7 +497,7 @@ impl<I: Interner> AliasTerm<I> {
|
|||
/// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
|
||||
/// then this function would return a `T: StreamingIterator` trait reference and
|
||||
/// `['a]` as the own args.
|
||||
pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::GenericArgsSlice) {
|
||||
pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::OwnItemArgs) {
|
||||
interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
|
||||
}
|
||||
|
||||
|
|
|
@ -342,7 +342,7 @@ impl<I: Interner> PartialEq for TyKind<I> {
|
|||
impl<I: Interner> DebugWithInfcx<I> for TyKind<I> {
|
||||
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
|
||||
this: WithInfcx<'_, Infcx, &Self>,
|
||||
f: &mut core::fmt::Formatter<'_>,
|
||||
f: &mut fmt::Formatter<'_>,
|
||||
) -> fmt::Result {
|
||||
match this.data {
|
||||
Bool => write!(f, "bool"),
|
||||
|
@ -514,7 +514,7 @@ impl<I: Interner> AliasTy<I> {
|
|||
/// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
|
||||
/// then this function would return a `T: StreamingIterator` trait reference and
|
||||
/// `['a]` as the own args.
|
||||
pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::GenericArgsSlice) {
|
||||
pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::OwnItemArgs) {
|
||||
debug_assert_eq!(self.kind(interner), AliasTyKind::Projection);
|
||||
interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
|
||||
}
|
||||
|
@ -561,8 +561,8 @@ impl<I: Interner> fmt::Debug for AliasTy<I> {
|
|||
impl<I: Interner> DebugWithInfcx<I> for AliasTy<I> {
|
||||
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
|
||||
this: WithInfcx<'_, Infcx, &Self>,
|
||||
f: &mut core::fmt::Formatter<'_>,
|
||||
) -> core::fmt::Result {
|
||||
f: &mut fmt::Formatter<'_>,
|
||||
) -> fmt::Result {
|
||||
f.debug_struct("AliasTy")
|
||||
.field("args", &this.map(|data| data.args))
|
||||
.field("def_id", &this.data.def_id)
|
||||
|
@ -952,3 +952,76 @@ pub struct TypeAndMut<I: Interner> {
|
|||
pub ty: I::Ty,
|
||||
pub mutbl: Mutability,
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Hash(bound = "")
|
||||
)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct FnSig<I: Interner> {
|
||||
pub inputs_and_output: I::Tys,
|
||||
pub c_variadic: bool,
|
||||
pub unsafety: I::Unsafety,
|
||||
pub abi: I::Abi,
|
||||
}
|
||||
|
||||
impl<I: Interner> FnSig<I> {
|
||||
pub fn split_inputs_and_output(self) -> (I::FnInputTys, I::Ty) {
|
||||
self.inputs_and_output.split_inputs_and_output()
|
||||
}
|
||||
|
||||
pub fn inputs(self) -> I::FnInputTys {
|
||||
self.split_inputs_and_output().0
|
||||
}
|
||||
|
||||
pub fn output(self) -> I::Ty {
|
||||
self.split_inputs_and_output().1
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> fmt::Debug for FnSig<I> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
WithInfcx::with_no_infcx(self).fmt(f)
|
||||
}
|
||||
}
|
||||
impl<I: Interner> DebugWithInfcx<I> for FnSig<I> {
|
||||
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
|
||||
this: WithInfcx<'_, Infcx, &Self>,
|
||||
f: &mut fmt::Formatter<'_>,
|
||||
) -> fmt::Result {
|
||||
let sig = this.data;
|
||||
let FnSig { inputs_and_output: _, c_variadic, unsafety, abi } = sig;
|
||||
|
||||
write!(f, "{}", unsafety.prefix_str())?;
|
||||
if !abi.is_rust() {
|
||||
write!(f, "extern \"{abi:?}\" ")?;
|
||||
}
|
||||
|
||||
write!(f, "fn(")?;
|
||||
let (inputs, output) = sig.split_inputs_and_output();
|
||||
for (i, ty) in inputs.iter().enumerate() {
|
||||
if i > 0 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "{:?}", &this.wrap(ty))?;
|
||||
}
|
||||
if *c_variadic {
|
||||
if inputs.is_empty() {
|
||||
write!(f, "...")?;
|
||||
} else {
|
||||
write!(f, ", ...")?;
|
||||
}
|
||||
}
|
||||
write!(f, ")")?;
|
||||
|
||||
match output.kind() {
|
||||
Tuple(list) if list.is_empty() => Ok(()),
|
||||
_ => write!(f, " -> {:?}", &this.wrap(sig.output())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue