Skip to content

Commit

Permalink
Uplift FnSig
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed May 16, 2024
1 parent 1871252 commit 9d0b5be
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 122 deletions.
6 changes: 6 additions & 0 deletions compiler/rustc_errors/src/diagnostic_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => "",
Expand Down
26 changes: 22 additions & 4 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
Expand All @@ -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;
Expand All @@ -113,32 +114,37 @@ 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>;
type TypeOutlivesPredicate = ty::TypeOutlivesPredicate<'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)
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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> {
Expand Down
20 changes: 10 additions & 10 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()))
}
Expand Down Expand Up @@ -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));
}
Expand Down
43 changes: 0 additions & 43 deletions compiler/rustc_middle/src/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand Down
73 changes: 21 additions & 52 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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()`",
Expand Down Expand Up @@ -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`
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_type_ir/src/inherent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
// 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
{
Expand Down
Loading

0 comments on commit 9d0b5be

Please sign in to comment.