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.rs | 45 |
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) + }) + } +} |