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.rs176
1 files changed, 118 insertions, 58 deletions
diff --git a/crates/hir-ty/src/next_solver/ty.rs b/crates/hir-ty/src/next_solver/ty.rs
index 39abdaf079..c43e04b9d0 100644
--- a/crates/hir-ty/src/next_solver/ty.rs
+++ b/crates/hir-ty/src/next_solver/ty.rs
@@ -9,15 +9,15 @@ use hir_def::{
use hir_def::{TraitId, type_ref::Rawness};
use intern::{Interned, InternedRef, impl_internable};
use macros::GenericTypeVisitable;
-use rustc_abi::{Float, Integer, Size};
+use rustc_abi::{ExternAbi, Float, Integer, Size};
use rustc_ast_ir::{Mutability, try_visit, visit::VisitorResult};
use rustc_type_ir::{
- AliasTyKind, BoundVar, BoundVarIndexKind, ClosureKind, CoroutineArgs, CoroutineArgsParts,
- DebruijnIndex, FlagComputation, Flags, FloatTy, FloatVid, GenericTypeVisitable, InferTy, IntTy,
- IntVid, Interner, TyVid, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
- TypeVisitableExt, TypeVisitor, UintTy, Upcast, WithCachedTypeInfo,
+ BoundVar, BoundVarIndexKind, ClosureKind, DebruijnIndex, FlagComputation, Flags, FloatTy,
+ FloatVid, GenericTypeVisitable, InferTy, IntTy, IntVid, Interner, TyVid, TypeFoldable,
+ TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy,
+ Upcast, WithCachedTypeInfo,
inherent::{
- AdtDef as _, BoundExistentialPredicates, Const as _, GenericArgs as _, IntoKind, ParamLike,
+ AdtDef as _, BoundExistentialPredicates, GenericArgs as _, IntoKind, ParamLike,
Safety as _, SliceLike, Ty as _,
},
relate::Relate,
@@ -26,13 +26,12 @@ use rustc_type_ir::{
};
use crate::{
- FnAbi,
- db::{HirDatabase, InternedClosure},
+ db::{HirDatabase, InternedOpaqueTyId},
lower::GenericPredicates,
next_solver::{
AdtDef, AliasTy, Binder, CallableIdWrapper, Clause, ClauseKind, ClosureIdWrapper, Const,
- CoroutineClosureIdWrapper, CoroutineIdWrapper, FnSig, GenericArgKind, PolyFnSig, Region,
- TraitRef, TypeAliasIdWrapper,
+ CoroutineClosureIdWrapper, CoroutineIdWrapper, FnSig, GenericArgKind, PolyFnSig, Predicate,
+ Region, TraitRef, TypeAliasIdWrapper, Unnormalized,
abi::Safety,
impl_foldable_for_interned_slice, impl_stored_interned, interned_slice,
util::{CoroutineArgsExt, IntegerTypeExt},
@@ -47,6 +46,9 @@ use super::{
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>>;
+pub type AliasTyKind<'db> = rustc_type_ir::AliasTyKind<DbInterner<'db>>;
+pub type AliasTermKind<'db> = rustc_type_ir::AliasTermKind<DbInterner<'db>>;
+pub type FnSigKind<'db> = rustc_type_ir::FnSigKind<DbInterner<'db>>;
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct Ty<'db> {
@@ -174,15 +176,44 @@ impl<'db> Ty<'db> {
pub fn new_opaque(
interner: DbInterner<'db>,
- def_id: SolverDefId,
+ def_id: InternedOpaqueTyId,
args: GenericArgs<'db>,
) -> Self {
Ty::new_alias(
interner,
- AliasTy::new_from_args(interner, AliasTyKind::Opaque { def_id }, args),
+ AliasTy::new_from_args(interner, AliasTyKind::Opaque { def_id: def_id.into() }, args),
)
}
+ /// Note: this needs an interner with crate.
+ pub fn new_array(interner: DbInterner<'db>, ty: Ty<'db>, n: u128) -> Ty<'db> {
+ Ty::new(
+ interner,
+ TyKind::Array(
+ ty,
+ crate::consteval::usize_const(interner.db, Some(n), interner.expect_crate()),
+ ),
+ )
+ }
+
+ fn new_generic_adt(interner: DbInterner<'db>, adt_id: AdtId, ty_param: Ty<'db>) -> Ty<'db> {
+ let args = GenericArgs::fill_with_defaults(
+ interner,
+ adt_id.into(),
+ [ty_param.into()],
+ |_, _, _| panic!("all params except the first should have defaults"),
+ );
+ Ty::new_adt(interner, adt_id, args)
+ }
+
+ /// Note: Unlike most other constructors, this require the interner to have a crate, because this needs lang items.
+ pub fn new_box(interner: DbInterner<'db>, ty: Ty<'db>) -> Ty<'db> {
+ let Some(def_id) = interner.lang_items().OwnedBox else {
+ return Ty::new_error(interner, ErrorGuaranteed);
+ };
+ Ty::new_generic_adt(interner, def_id.into(), ty)
+ }
+
/// Returns the `Size` for primitive types (bool, uint, int, char, float).
pub fn primitive_size(self, interner: DbInterner<'db>) -> Size {
match self.kind() {
@@ -252,9 +283,9 @@ impl<'db> Ty<'db> {
tys.last().is_none_or(|ty| ty.has_trivial_sizedness(tcx, sizedness))
}
- TyKind::Adt(def, args) => def
- .sizedness_constraint(tcx, sizedness)
- .is_none_or(|ty| ty.instantiate(tcx, args).has_trivial_sizedness(tcx, sizedness)),
+ TyKind::Adt(def, args) => def.sizedness_constraint(tcx, sizedness).is_none_or(|ty| {
+ ty.instantiate(tcx, args).skip_norm_wip().has_trivial_sizedness(tcx, sizedness)
+ }),
TyKind::Alias(..) | TyKind::Param(_) | TyKind::Placeholder(..) | TyKind::Bound(..) => {
false
@@ -472,10 +503,14 @@ impl<'db> Ty<'db> {
}
}
+ pub fn is_box(self) -> bool {
+ matches!(self.kind(), TyKind::Adt(adt_def, _) if adt_def.is_box())
+ }
+
#[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)),
+ TyKind::Adt(adt_def, args) => Some((adt_def.def_id(), args)),
_ => None,
}
}
@@ -501,7 +536,7 @@ impl<'db> Ty<'db> {
/// unsafe.
pub fn safe_to_unsafe_fn_ty(interner: DbInterner<'db>, sig: PolyFnSig<'db>) -> Ty<'db> {
assert!(sig.safety().is_safe());
- Ty::new_fn_ptr(interner, sig.map_bound(|sig| FnSig { safety: Safety::Unsafe, ..sig }))
+ Ty::new_fn_ptr(interner, sig.map_bound(|sig| sig.set_safety(Safety::Unsafe)))
}
/// Returns the type of `*ty`.
@@ -538,7 +573,7 @@ impl<'db> Ty<'db> {
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))
+ Some(interner.fn_sig(callable).instantiate(interner, args).skip_norm_wip())
}
TyKind::FnPtr(sig, hdr) => Some(sig.with(hdr)),
TyKind::Closure(_, closure_args) => {
@@ -546,23 +581,13 @@ impl<'db> Ty<'db> {
}
TyKind::CoroutineClosure(coroutine_id, args) => {
Some(args.as_coroutine_closure().coroutine_closure_sig().map_bound(|sig| {
- let unit_ty = Ty::new_unit(interner);
- let return_ty = Ty::new_coroutine(
+ let closure_args = args.as_coroutine_closure();
+ let return_ty = sig.to_coroutine(
interner,
+ closure_args.parent_args(),
+ closure_args.kind_ty(),
interner.coroutine_for_closure(coroutine_id),
- CoroutineArgs::new(
- interner,
- CoroutineArgsParts {
- parent_args: args.as_coroutine_closure().parent_args(),
- kind_ty: unit_ty,
- resume_ty: unit_ty,
- yield_ty: unit_ty,
- return_ty: sig.return_ty,
- // FIXME: Deduce this from the coroutine closure's upvars.
- tupled_upvars_ty: unit_ty,
- },
- )
- .args,
+ closure_args.tupled_upvars_ty(),
);
FnSig {
inputs_and_output: Tys::new_from_iter(
@@ -572,9 +597,7 @@ impl<'db> Ty<'db> {
.iter()
.chain(std::iter::once(return_ty)),
),
- c_variadic: sig.c_variadic,
- safety: sig.safety,
- abi: sig.abi,
+ fn_sig_kind: sig.fn_sig_kind,
}
}))
}
@@ -597,6 +620,10 @@ impl<'db> Ty<'db> {
}
}
+ pub fn is_tuple(self) -> bool {
+ matches!(self.kind(), TyKind::Tuple(_))
+ }
+
pub fn as_tuple(self) -> Option<Tys<'db>> {
match self.kind() {
TyKind::Tuple(tys) => Some(tys),
@@ -704,9 +731,10 @@ impl<'db> Ty<'db> {
match self.kind() {
TyKind::Alias(AliasTy { kind: AliasTyKind::Opaque { def_id }, args, .. }) => Some(
def_id
- .expect_opaque_ty()
+ .0
.predicates(db)
.iter_instantiated_copied(interner, args.as_slice())
+ .map(Unnormalized::skip_norm_wip)
.collect(),
),
TyKind::Param(param) => {
@@ -718,6 +746,7 @@ impl<'db> Ty<'db> {
TypeParamProvenance::ArgumentImplTrait => {
let predicates = GenericPredicates::query_all(db, param.id.parent())
.iter_identity()
+ .map(Unnormalized::skip_norm_wip)
.filter(|wc| match wc.kind().skip_binder() {
ClauseKind::Trait(tr) => tr.self_ty() == self,
ClauseKind::Projection(pred) => pred.self_ty() == self,
@@ -734,7 +763,7 @@ impl<'db> Ty<'db> {
}
}
TyKind::Coroutine(coroutine_id, _args) => {
- let InternedClosure(owner, _) = coroutine_id.0.loc(db);
+ let owner = coroutine_id.0.loc(db).owner;
let krate = owner.krate(db);
if let Some(future_trait) = hir_def::lang_item::lang_items(db, krate).Future {
// This is only used by type walking.
@@ -784,25 +813,11 @@ impl<'db> Ty<'db> {
}
pub fn references_non_lt_error<'db, T: TypeVisitableExt<DbInterner<'db>>>(t: &T) -> bool {
- t.references_error() && t.visit_with(&mut ReferencesNonLifetimeError).is_break()
-}
-
-struct ReferencesNonLifetimeError;
-
-impl<'db> TypeVisitor<DbInterner<'db>> for ReferencesNonLifetimeError {
- type Result = ControlFlow<()>;
-
- fn visit_ty(&mut self, ty: Ty<'db>) -> Self::Result {
- if ty.is_ty_error() { ControlFlow::Break(()) } else { ty.super_visit_with(self) }
- }
-
- fn visit_const(&mut self, c: Const<'db>) -> Self::Result {
- if c.is_ct_error() { ControlFlow::Break(()) } else { c.super_visit_with(self) }
- }
+ t.has_non_region_error()
}
pub fn references_only_ty_error<'db, T: TypeVisitableExt<DbInterner<'db>>>(t: &T) -> bool {
- t.references_error() && t.visit_with(&mut ReferencesOnlyTyError).is_break()
+ references_non_lt_error(t) && t.visit_with(&mut ReferencesOnlyTyError).is_break()
}
struct ReferencesOnlyTyError;
@@ -811,7 +826,29 @@ impl<'db> TypeVisitor<DbInterner<'db>> for ReferencesOnlyTyError {
type Result = ControlFlow<()>;
fn visit_ty(&mut self, ty: Ty<'db>) -> Self::Result {
- if ty.is_ty_error() { ControlFlow::Break(()) } else { ty.super_visit_with(self) }
+ if !ty.references_non_lt_error() {
+ ControlFlow::Continue(())
+ } else if ty.is_ty_error() {
+ ControlFlow::Break(())
+ } else {
+ ty.super_visit_with(self)
+ }
+ }
+
+ fn visit_const(&mut self, c: Const<'db>) -> Self::Result {
+ if !references_non_lt_error(&c) {
+ ControlFlow::Continue(())
+ } else {
+ c.super_visit_with(self)
+ }
+ }
+
+ fn visit_predicate(&mut self, p: Predicate<'db>) -> Self::Result {
+ if !references_non_lt_error(&p) {
+ ControlFlow::Continue(())
+ } else {
+ p.super_visit_with(self)
+ }
}
}
@@ -847,6 +884,15 @@ impl<'db> TypeVisitable<DbInterner<'db>> for Ty<'db> {
}
}
+impl<'db> TypeVisitable<DbInterner<'db>> for StoredTy {
+ fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
+ &self,
+ visitor: &mut V,
+ ) -> V::Result {
+ self.as_ref().visit_with(visitor)
+ }
+}
+
impl<'db> TypeSuperVisitable<DbInterner<'db>> for Ty<'db> {
fn super_visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
&self,
@@ -913,6 +959,18 @@ impl<'db> TypeFoldable<DbInterner<'db>> for Ty<'db> {
}
}
+impl<'db> TypeFoldable<DbInterner<'db>> for StoredTy {
+ fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
+ self,
+ folder: &mut F,
+ ) -> Result<Self, F::Error> {
+ Ok(self.as_ref().try_fold_with(folder)?.store())
+ }
+ fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
+ self.as_ref().fold_with(folder).store()
+ }
+}
+
impl<'db> TypeSuperFoldable<DbInterner<'db>> for Ty<'db> {
fn try_super_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
self,
@@ -1294,9 +1352,11 @@ impl<'db> rustc_type_ir::inherent::Ty<DbInterner<'db>> for Ty<'db> {
false
}
- fn discriminant_ty(self, interner: DbInterner<'db>) -> <DbInterner<'db> as Interner>::Ty {
+ fn discriminant_ty(self, interner: DbInterner<'db>) -> Ty<'db> {
match self.kind() {
- TyKind::Adt(adt, _) if adt.is_enum() => adt.repr().discr_type().to_ty(interner),
+ TyKind::Adt(adt, _) if adt.is_enum() => {
+ adt.repr(interner.db).discr_type().to_ty(interner)
+ }
TyKind::Coroutine(_, args) => args.as_coroutine().discr_ty(interner),
TyKind::Param(_) | TyKind::Alias(..) | TyKind::Infer(InferTy::TyVar(_)) => {
@@ -1444,7 +1504,7 @@ impl<'db> DbInterner<'db> {
TyKind::Tuple(params) => params,
_ => panic!(),
};
- self.mk_fn_sig(params, s.output(), s.c_variadic, safety, FnAbi::Rust)
+ self.mk_fn_sig(params, s.output(), s.c_variadic(), safety, ExternAbi::Rust)
})
}
}