Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/next_solver/ty.rs')
-rw-r--r--crates/hir-ty/src/next_solver/ty.rs45
1 files changed, 41 insertions, 4 deletions
diff --git a/crates/hir-ty/src/next_solver/ty.rs b/crates/hir-ty/src/next_solver/ty.rs
index c89831bd40..66a24d3949 100644
--- a/crates/hir-ty/src/next_solver/ty.rs
+++ b/crates/hir-ty/src/next_solver/ty.rs
@@ -26,6 +26,7 @@ use rustc_type_ir::{
};
use crate::{
+ FnAbi,
db::{HirDatabase, InternedCoroutine},
lower::GenericPredicates,
next_solver::{
@@ -382,6 +383,11 @@ impl<'db> Ty<'db> {
matches!(self.kind(), TyKind::Bool)
}
+ #[inline]
+ pub fn is_char(self) -> bool {
+ matches!(self.kind(), TyKind::Char)
+ }
+
/// A scalar type is one that denotes an atomic datum, with no sub-components.
/// (A RawPtr is scalar because it represents a non-managed pointer, so its
/// contents are abstract to rustc.)
@@ -422,6 +428,11 @@ impl<'db> Ty<'db> {
}
#[inline]
+ pub fn is_u8(self) -> bool {
+ matches!(self.kind(), TyKind::Uint(UintTy::U8))
+ }
+
+ #[inline]
pub fn is_raw_ptr(self) -> bool {
matches!(self.kind(), TyKind::RawPtr(..))
}
@@ -456,6 +467,14 @@ impl<'db> Ty<'db> {
}
#[inline]
+ pub fn as_slice(self) -> Option<Ty<'db>> {
+ match self.kind() {
+ TyKind::Slice(ty) => Some(ty),
+ _ => None,
+ }
+ }
+
+ #[inline]
pub fn ty_vid(self) -> Option<TyVid> {
match self.kind() {
TyKind::Infer(rustc_type_ir::TyVar(vid)) => Some(vid),
@@ -495,10 +514,9 @@ impl<'db> Ty<'db> {
Some(interner.fn_sig(callable).instantiate(interner, args))
}
TyKind::FnPtr(sig, hdr) => Some(sig.with(hdr)),
- TyKind::Closure(_, closure_args) => closure_args
- .split_closure_args_untupled()
- .closure_sig_as_fn_ptr_ty
- .callable_sig(interner),
+ TyKind::Closure(_, closure_args) => {
+ Some(interner.signature_unclosure(closure_args.as_closure().sig(), Safety::Safe))
+ }
TyKind::CoroutineClosure(coroutine_id, args) => {
Some(args.as_coroutine_closure().coroutine_closure_sig().map_bound(|sig| {
let unit_ty = Ty::new_unit(interner);
@@ -1426,3 +1444,22 @@ impl<'db> PlaceholderLike<DbInterner<'db>> for PlaceholderTy {
Placeholder { universe: ui, bound: BoundTy { var, kind: BoundTyKind::Anon } }
}
}
+
+impl<'db> DbInterner<'db> {
+ /// Given a closure signature, returns an equivalent fn signature. Detuples
+ /// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
+ /// you would get a `fn(u32, i32)`.
+ /// `unsafety` determines the unsafety of the fn signature. If you pass
+ /// `Safety::Unsafe` in the previous example, then you would get
+ /// an `unsafe fn (u32, i32)`.
+ /// It cannot convert a closure that requires unsafe.
+ pub fn signature_unclosure(self, sig: PolyFnSig<'db>, safety: Safety) -> PolyFnSig<'db> {
+ sig.map_bound(|s| {
+ let params = match s.inputs()[0].kind() {
+ TyKind::Tuple(params) => params,
+ _ => panic!(),
+ };
+ self.mk_fn_sig(params, s.output(), s.c_variadic, safety, FnAbi::Rust)
+ })
+ }
+}