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.rs106
1 files changed, 76 insertions, 30 deletions
diff --git a/crates/hir-ty/src/next_solver/ty.rs b/crates/hir-ty/src/next_solver/ty.rs
index b8406fecda..58849ce9ca 100644
--- a/crates/hir-ty/src/next_solver/ty.rs
+++ b/crates/hir-ty/src/next_solver/ty.rs
@@ -25,8 +25,8 @@ use rustc_type_ir::{
};
use crate::{
- ImplTraitId,
db::{HirDatabase, InternedCoroutine},
+ lower::GenericPredicates,
next_solver::{
AdtDef, AliasTy, Binder, CallableIdWrapper, Clause, ClauseKind, ClosureIdWrapper, Const,
CoroutineIdWrapper, FnSig, GenericArg, PolyFnSig, Region, TraitRef, TypeAliasIdWrapper,
@@ -41,6 +41,7 @@ use super::{
util::{FloatExt, IntegerExt},
};
+pub type SimplifiedType = rustc_type_ir::fast_reject::SimplifiedType<SolverDefId>;
pub type TyKind<'db> = rustc_type_ir::TyKind<DbInterner<'db>>;
pub type FnHeader<'db> = rustc_type_ir::FnHeader<DbInterner<'db>>;
@@ -127,6 +128,22 @@ impl<'db> Ty<'db> {
Ty::new_tup(interner, &[])
}
+ pub fn new_imm_ptr(interner: DbInterner<'db>, ty: Ty<'db>) -> Self {
+ Ty::new_ptr(interner, ty, Mutability::Not)
+ }
+
+ pub fn new_imm_ref(interner: DbInterner<'db>, region: Region<'db>, ty: Ty<'db>) -> Self {
+ Ty::new_ref(interner, region, ty, Mutability::Not)
+ }
+
+ pub fn new_opaque(
+ interner: DbInterner<'db>,
+ def_id: SolverDefId,
+ args: GenericArgs<'db>,
+ ) -> Self {
+ Ty::new_alias(interner, AliasTyKind::Opaque, AliasTy::new_from_args(interner, def_id, args))
+ }
+
/// Returns the `Size` for primitive types (bool, uint, int, char, float).
pub fn primitive_size(self, interner: DbInterner<'db>) -> Size {
match self.kind() {
@@ -327,11 +344,40 @@ impl<'db> Ty<'db> {
}
#[inline]
+ pub fn is_bool(self) -> bool {
+ matches!(self.kind(), TyKind::Bool)
+ }
+
+ /// 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.)
+ #[inline]
+ pub fn is_scalar(self) -> bool {
+ matches!(
+ self.kind(),
+ TyKind::Bool
+ | TyKind::Char
+ | TyKind::Int(_)
+ | TyKind::Float(_)
+ | TyKind::Uint(_)
+ | TyKind::FnDef(..)
+ | TyKind::FnPtr(..)
+ | TyKind::RawPtr(_, _)
+ | TyKind::Infer(InferTy::IntVar(_) | InferTy::FloatVar(_))
+ )
+ }
+
+ #[inline]
pub fn is_infer(self) -> bool {
matches!(self.kind(), TyKind::Infer(..))
}
#[inline]
+ pub fn is_numeric(self) -> bool {
+ self.is_integral() || self.is_floating_point()
+ }
+
+ #[inline]
pub fn is_str(self) -> bool {
matches!(self.kind(), TyKind::Str)
}
@@ -346,10 +392,27 @@ impl<'db> Ty<'db> {
matches!(self.kind(), TyKind::RawPtr(..))
}
+ #[inline]
+ pub fn is_array(self) -> bool {
+ matches!(self.kind(), TyKind::Array(..))
+ }
+
+ #[inline]
+ pub fn is_slice(self) -> bool {
+ matches!(self.kind(), TyKind::Slice(..))
+ }
+
pub fn is_union(self) -> bool {
self.as_adt().is_some_and(|(adt, _)| matches!(adt, AdtId::UnionId(_)))
}
+ pub fn boxed_ty(self) -> Option<Ty<'db>> {
+ match self.kind() {
+ TyKind::Adt(adt_def, args) if adt_def.is_box() => Some(args.type_at(0)),
+ _ => None,
+ }
+ }
+
#[inline]
pub fn as_adt(self) -> Option<(AdtId, GenericArgs<'db>)> {
match self.kind() {
@@ -378,11 +441,9 @@ impl<'db> Ty<'db> {
///
/// The parameter `explicit` indicates if this is an *explicit* dereference.
/// Some types -- notably raw ptrs -- can only be dereferenced explicitly.
- pub fn builtin_deref(self, db: &dyn HirDatabase, explicit: bool) -> Option<Ty<'db>> {
+ pub fn builtin_deref(self, explicit: bool) -> Option<Ty<'db>> {
match self.kind() {
- TyKind::Adt(adt, substs) if crate::lang_items::is_box(db, adt.def_id().0) => {
- Some(substs.as_slice()[0].expect_ty())
- }
+ TyKind::Adt(adt, substs) if adt.is_box() => Some(substs.as_slice()[0].expect_ty()),
TyKind::Ref(_, ty, _) => Some(ty),
TyKind::RawPtr(ty, _) if explicit => Some(ty),
_ => None,
@@ -562,26 +623,14 @@ impl<'db> Ty<'db> {
let interner = DbInterner::new_with(db, None, None);
match self.kind() {
- TyKind::Alias(AliasTyKind::Opaque, opaque_ty) => {
- match db.lookup_intern_impl_trait_id(opaque_ty.def_id.expect_opaque_ty()) {
- ImplTraitId::ReturnTypeImplTrait(func, idx) => {
- db.return_type_impl_traits(func).map(|it| {
- let data =
- (*it).as_ref().map_bound(|rpit| &rpit.impl_traits[idx].predicates);
- data.iter_instantiated_copied(interner, opaque_ty.args.as_slice())
- .collect()
- })
- }
- ImplTraitId::TypeAliasImplTrait(alias, idx) => {
- db.type_alias_impl_traits(alias).map(|it| {
- let data =
- (*it).as_ref().map_bound(|rpit| &rpit.impl_traits[idx].predicates);
- data.iter_instantiated_copied(interner, opaque_ty.args.as_slice())
- .collect()
- })
- }
- }
- }
+ TyKind::Alias(AliasTyKind::Opaque, opaque_ty) => Some(
+ opaque_ty
+ .def_id
+ .expect_opaque_ty()
+ .predicates(db)
+ .iter_instantiated_copied(interner, opaque_ty.args.as_slice())
+ .collect(),
+ ),
TyKind::Param(param) => {
// FIXME: We shouldn't use `param.id` here.
let generic_params = db.generic_params(param.id.parent());
@@ -589,11 +638,8 @@ impl<'db> Ty<'db> {
match param_data {
TypeOrConstParamData::TypeParamData(p) => match p.provenance {
TypeParamProvenance::ArgumentImplTrait => {
- let predicates = db
- .generic_predicates(param.id.parent())
- .instantiate_identity()
- .into_iter()
- .flatten()
+ let predicates = GenericPredicates::query_all(db, param.id.parent())
+ .iter_identity_copied()
.filter(|wc| match wc.kind().skip_binder() {
ClauseKind::Trait(tr) => tr.self_ty() == self,
ClauseKind::Projection(pred) => pred.self_ty() == self,