Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uplift FnSig to rustc_type_ir #125157

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"`?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// is `extern "Rust"`?
/// 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
{
Expand Down
Loading
Loading