1
Fork 0

Deduplicate some rustc_middle function bodies by calling the rustc_type_ir equivalent

This commit is contained in:
Oli Scherer 2025-04-03 10:43:32 +00:00
parent b6d74b5e15
commit 6189594c0a
3 changed files with 67 additions and 99 deletions

View file

@ -8,7 +8,7 @@ use std::iter;
use std::ops::{ControlFlow, Range};
use hir::def::{CtorKind, DefKind};
use rustc_abi::{ExternAbi, FIRST_VARIANT, FieldIdx, VariantIdx};
use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
use rustc_errors::{ErrorGuaranteed, MultiSpan};
use rustc_hir as hir;
use rustc_hir::LangItem;
@ -1441,23 +1441,7 @@ impl<'tcx> Ty<'tcx> {
#[tracing::instrument(level = "trace", skip(tcx))]
pub fn fn_sig(self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
match self.kind() {
FnDef(def_id, args) => tcx.fn_sig(*def_id).instantiate(tcx, args),
FnPtr(sig_tys, hdr) => sig_tys.with(*hdr),
Error(_) => {
// ignore errors (#54954)
Binder::dummy(ty::FnSig {
inputs_and_output: ty::List::empty(),
c_variadic: false,
safety: hir::Safety::Safe,
abi: ExternAbi::Rust,
})
}
Closure(..) => bug!(
"to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",
),
_ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self),
}
self.kind().fn_sig(tcx)
}
#[inline]
@ -2043,32 +2027,7 @@ impl<'tcx> Ty<'tcx> {
/// nested types may be further simplified, the outermost [`TyKind`] or
/// type constructor remains the same.
pub fn is_known_rigid(self) -> bool {
match self.kind() {
Bool
| Char
| Int(_)
| Uint(_)
| Float(_)
| Adt(_, _)
| Foreign(_)
| Str
| Array(_, _)
| Pat(_, _)
| Slice(_)
| RawPtr(_, _)
| Ref(_, _, _)
| FnDef(_, _)
| FnPtr(..)
| Dynamic(_, _, _)
| Closure(_, _)
| CoroutineClosure(_, _)
| Coroutine(_, _)
| CoroutineWitness(..)
| Never
| Tuple(_)
| UnsafeBinder(_) => true,
Error(_) | Infer(_) | Alias(_, _) | Param(_) | Bound(_, _) | Placeholder(_) => false,
}
self.kind().is_known_rigid()
}
}

View file

@ -146,67 +146,14 @@ pub trait Ty<I: Interner<Ty = Self>>:
fn has_unsafe_fields(self) -> bool;
fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
match self.kind() {
ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr),
ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, args),
ty::Error(_) => {
// ignore errors (#54954)
ty::Binder::dummy(ty::FnSig {
inputs_and_output: Default::default(),
c_variadic: false,
safety: I::Safety::safe(),
abi: I::Abi::rust(),
})
}
ty::Closure(..) => panic!(
"to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",
),
_ => panic!("Ty::fn_sig() called on non-fn type: {:?}", self),
}
self.kind().fn_sig(interner)
}
fn discriminant_ty(self, interner: I) -> I::Ty;
fn async_destructor_ty(self, interner: I) -> I::Ty;
/// Returns `true` when the outermost type cannot be further normalized,
/// resolved, or instantiated. This includes all primitive types, but also
/// things like ADTs and trait objects, since even if their arguments or
/// nested types may be further simplified, the outermost [`ty::TyKind`] or
/// type constructor remains the same.
fn is_known_rigid(self) -> bool {
match self.kind() {
ty::Bool
| ty::Char
| ty::Int(_)
| ty::Uint(_)
| ty::Float(_)
| ty::Adt(_, _)
| ty::Foreign(_)
| ty::Str
| ty::Array(_, _)
| ty::Pat(_, _)
| ty::Slice(_)
| ty::RawPtr(_, _)
| ty::Ref(_, _, _)
| ty::FnDef(_, _)
| ty::FnPtr(..)
| ty::UnsafeBinder(_)
| ty::Dynamic(_, _, _)
| ty::Closure(_, _)
| ty::CoroutineClosure(_, _)
| ty::Coroutine(_, _)
| ty::CoroutineWitness(..)
| ty::Never
| ty::Tuple(_) => true,
ty::Error(_)
| ty::Infer(_)
| ty::Alias(_, _)
| ty::Param(_)
| ty::Bound(_, _)
| ty::Placeholder(_) => false,
}
self.kind().is_known_rigid()
}
}

View file

@ -273,6 +273,68 @@ pub enum TyKind<I: Interner> {
Error(I::ErrorGuaranteed),
}
impl<I: Interner> TyKind<I> {
pub fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
match self {
ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr),
ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, args),
ty::Error(_) => {
// ignore errors (#54954)
ty::Binder::dummy(ty::FnSig {
inputs_and_output: Default::default(),
c_variadic: false,
safety: I::Safety::safe(),
abi: I::Abi::rust(),
})
}
ty::Closure(..) => panic!(
"to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",
),
_ => panic!("Ty::fn_sig() called on non-fn type: {:?}", self),
}
}
/// Returns `true` when the outermost type cannot be further normalized,
/// resolved, or instantiated. This includes all primitive types, but also
/// things like ADTs and trait objects, since even if their arguments or
/// nested types may be further simplified, the outermost [`ty::TyKind`] or
/// type constructor remains the same.
pub fn is_known_rigid(self) -> bool {
match self {
ty::Bool
| ty::Char
| ty::Int(_)
| ty::Uint(_)
| ty::Float(_)
| ty::Adt(_, _)
| ty::Foreign(_)
| ty::Str
| ty::Array(_, _)
| ty::Pat(_, _)
| ty::Slice(_)
| ty::RawPtr(_, _)
| ty::Ref(_, _, _)
| ty::FnDef(_, _)
| ty::FnPtr(..)
| ty::UnsafeBinder(_)
| ty::Dynamic(_, _, _)
| ty::Closure(_, _)
| ty::CoroutineClosure(_, _)
| ty::Coroutine(_, _)
| ty::CoroutineWitness(..)
| ty::Never
| ty::Tuple(_) => true,
ty::Error(_)
| ty::Infer(_)
| ty::Alias(_, _)
| ty::Param(_)
| ty::Bound(_, _)
| ty::Placeholder(_) => false,
}
}
}
// This is manually implemented because a derive would require `I: Debug`
impl<I: Interner> fmt::Debug for TyKind<I> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {