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 | 67 |
1 files changed, 64 insertions, 3 deletions
diff --git a/crates/hir-ty/src/next_solver/ty.rs b/crates/hir-ty/src/next_solver/ty.rs index a25996ab48..5ccd84af8d 100644 --- a/crates/hir-ty/src/next_solver/ty.rs +++ b/crates/hir-ty/src/next_solver/ty.rs @@ -3,7 +3,8 @@ use std::iter; use std::ops::ControlFlow; -use hir_def::{GenericDefId, TypeOrConstParamId, TypeParamId}; +use hir_def::type_ref::Rawness; +use hir_def::{AdtId, GenericDefId, TypeOrConstParamId, TypeParamId}; use intern::{Interned, Symbol, sym}; use rustc_abi::{Float, Integer, Size}; use rustc_ast_ir::{Mutability, try_visit, visit::VisitorResult}; @@ -13,7 +14,7 @@ use rustc_type_ir::{ IntTy, IntVid, Interner, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, WithCachedTypeInfo, inherent::{ - Abi, AdtDef, BoundVarLike, Const as _, GenericArgs as _, IntoKind, ParamLike, + Abi, AdtDef as _, BoundVarLike, Const as _, GenericArgs as _, IntoKind, ParamLike, PlaceholderLike, Safety as _, SliceLike, Ty as _, }, relate::Relate, @@ -23,6 +24,7 @@ use rustc_type_ir::{ use salsa::plumbing::{AsId, FromId}; use smallvec::SmallVec; +use crate::next_solver::{AdtDef, Binder}; use crate::{ FnAbi, db::HirDatabase, @@ -75,6 +77,10 @@ impl<'db> Ty<'db> { .unwrap() } + pub fn new_adt(interner: DbInterner<'db>, adt_id: AdtId, args: GenericArgs<'db>) -> Self { + Ty::new(interner, TyKind::Adt(AdtDef::new(adt_id, interner), args)) + } + pub fn new_param(interner: DbInterner<'db>, id: TypeParamId, index: u32, name: Symbol) -> Self { Ty::new(interner, TyKind::Param(ParamTy { id, index })) } @@ -338,6 +344,23 @@ impl<'db> Ty<'db> { } #[inline] + pub fn is_raw_ptr(self) -> bool { + matches!(self.kind(), TyKind::RawPtr(..)) + } + + pub fn is_union(self) -> bool { + self.as_adt().is_some_and(|(adt, _)| matches!(adt, AdtId::UnionId(_))) + } + + #[inline] + pub fn as_adt(self) -> Option<(AdtId, GenericArgs<'db>)> { + match self.kind() { + TyKind::Adt(adt_def, args) => Some((adt_def.def_id().0, args)), + _ => None, + } + } + + #[inline] pub fn ty_vid(self) -> Option<TyVid> { match self.kind() { TyKind::Infer(rustc_type_ir::TyVar(vid)) => Some(vid), @@ -372,6 +395,38 @@ impl<'db> Ty<'db> { pub fn references_non_lt_error(self) -> bool { self.references_error() && self.visit_with(&mut ReferencesNonLifetimeError).is_break() } + + pub fn callable_sig(self, interner: DbInterner<'db>) -> Option<Binder<'db, FnSig<'db>>> { + match self.kind() { + TyKind::FnDef(callable, args) => { + Some(interner.fn_sig(callable).instantiate(interner, args)) + } + TyKind::FnPtr(sig, hdr) => Some(sig.with(hdr)), + TyKind::Closure(closure_id, closure_args) => closure_args + .split_closure_args_untupled() + .closure_sig_as_fn_ptr_ty + .callable_sig(interner), + _ => None, + } + } + + pub fn as_reference_or_ptr(self) -> Option<(Ty<'db>, Rawness, Mutability)> { + match self.kind() { + TyKind::Ref(_, ty, mutability) => Some((ty, Rawness::Ref, mutability)), + TyKind::RawPtr(ty, mutability) => Some((ty, Rawness::RawPtr, mutability)), + _ => None, + } + } + + /// Replace infer vars with errors. + /// + /// This needs to be called for every type that may contain infer vars and is yielded to outside inference, + /// as things other than inference do not expect to see infer vars. + pub fn replace_infer_with_error(self, interner: DbInterner<'db>) -> Ty<'db> { + self.fold_with(&mut crate::next_solver::infer::resolve::ReplaceInferWithError::new( + interner, + )) + } } struct ReferencesNonLifetimeError; @@ -928,11 +983,17 @@ impl<'db> rustc_type_ir::inherent::Ty<DbInterner<'db>> for Ty<'db> { interned_vec_db!(Tys, Ty); +impl<'db> Tys<'db> { + pub fn inputs(&self) -> &[Ty<'db>] { + self.as_slice().split_last().unwrap().1 + } +} + impl<'db> rustc_type_ir::inherent::Tys<DbInterner<'db>> for Tys<'db> { fn inputs(self) -> <DbInterner<'db> as rustc_type_ir::Interner>::FnInputTys { Tys::new_from_iter( DbInterner::conjure(), - self.as_slice().split_last().unwrap().1.iter().cloned(), + self.as_slice().split_last().unwrap().1.iter().copied(), ) } |