Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/lib.rs')
-rw-r--r--crates/hir-ty/src/lib.rs517
1 files changed, 217 insertions, 300 deletions
diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs
index 281cf6b2d4..734483a823 100644
--- a/crates/hir-ty/src/lib.rs
+++ b/crates/hir-ty/src/lib.rs
@@ -21,10 +21,11 @@ extern crate ra_ap_rustc_type_ir as rustc_type_ir;
extern crate ra_ap_rustc_next_trait_solver as rustc_next_trait_solver;
+extern crate self as hir_ty;
+
mod builder;
mod chalk_db;
mod chalk_ext;
-mod drop;
mod infer;
mod inhabitedness;
mod interner;
@@ -38,10 +39,11 @@ mod utils;
pub mod autoderef;
pub mod consteval;
-pub mod consteval_nextsolver;
+mod consteval_chalk;
pub mod db;
pub mod diagnostics;
pub mod display;
+pub mod drop;
pub mod dyn_compatibility;
pub mod generics;
pub mod lang_items;
@@ -60,11 +62,10 @@ mod variance;
use std::hash::Hash;
use chalk_ir::{
- NoSolution, VariableKinds,
+ VariableKinds,
fold::{Shift, TypeFoldable},
interner::HasInterner,
};
-use either::Either;
use hir_def::{CallableDefId, GeneralConstId, TypeOrConstParamId, hir::ExprId, type_ref::Rawness};
use hir_expand::name::Name;
use indexmap::{IndexMap, map::Entry};
@@ -73,15 +74,16 @@ use la_arena::{Arena, Idx};
use mir::{MirEvalError, VTableMap};
use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet};
use rustc_type_ir::{
- UpcastFrom,
- inherent::{SliceLike, Ty as _},
+ TypeSuperVisitable, TypeVisitableExt, UpcastFrom,
+ inherent::{IntoKind, SliceLike, Ty as _},
};
use syntax::ast::{ConstArg, make};
use traits::FnTrait;
use triomphe::Arc;
+#[cfg(not(debug_assertions))]
+use crate::next_solver::ErrorGuaranteed;
use crate::{
- consteval::unknown_const,
db::HirDatabase,
display::{DisplayTarget, HirDisplay},
generics::Generics,
@@ -95,7 +97,6 @@ use crate::{
pub use autoderef::autoderef;
pub use builder::{ParamKind, TyBuilder};
pub use chalk_ext::*;
-pub use drop::DropGlue;
pub use infer::{
Adjust, Adjustment, AutoBorrow, BindingMode, InferenceDiagnostic, InferenceResult,
InferenceTyDiagnosticSource, OverloadedDeref, PointerCast,
@@ -104,17 +105,17 @@ pub use infer::{
could_coerce, could_unify, could_unify_deeply,
};
pub use interner::Interner;
-pub use lower::{
- ImplTraitLoweringMode, LifetimeElisionKind, ParamLoweringMode, TyDefId, TyLoweringContext,
- ValueTyDefId, diagnostics::*,
+pub use lower::{ImplTraitLoweringMode, ParamLoweringMode, TyDefId, ValueTyDefId, diagnostics::*};
+pub use lower_nextsolver::{
+ LifetimeElisionKind, TyLoweringContext, associated_type_shorthand_candidates,
};
-pub use lower_nextsolver::associated_type_shorthand_candidates;
pub use mapping::{
ToChalk, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx,
lt_from_placeholder_idx, lt_to_placeholder_idx, to_assoc_type_id, to_chalk_trait_id,
to_foreign_def_id, to_placeholder_idx, to_placeholder_idx_no_index,
};
pub use method_resolution::check_orphan_rules;
+pub use next_solver::interner::{attach_db, attach_db_allow_change, with_attached_db};
pub use target_feature::TargetFeatures;
pub use traits::TraitEnvironment;
pub use utils::{
@@ -123,20 +124,16 @@ pub use utils::{
};
pub use variance::Variance;
-pub use chalk_ir::{
- AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind,
- cast::Cast,
- visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor},
-};
+use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Safety, Scalar};
-pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>;
-pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
-pub type FnDefId = chalk_ir::FnDefId<Interner>;
-pub type ClosureId = chalk_ir::ClosureId<Interner>;
-pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
-pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
+pub(crate) type ForeignDefId = chalk_ir::ForeignDefId<Interner>;
+pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
+pub(crate) type FnDefId = chalk_ir::FnDefId<Interner>;
+pub(crate) type ClosureId = chalk_ir::ClosureId<Interner>;
+pub(crate) type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
+pub(crate) type PlaceholderIndex = chalk_ir::PlaceholderIndex;
-pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;
+pub(crate) type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;
pub(crate) type VariableKind = chalk_ir::VariableKind<Interner>;
/// Represents generic parameters and an item bound by them. When the item has parent, the binders
@@ -147,49 +144,48 @@ pub(crate) type VariableKind = chalk_ir::VariableKind<Interner>;
/// parameters/arguments for an item MUST come before those for its parent. This is to facilitate
/// the integration with chalk-solve, which mildly puts constraints as such. See #13335 for its
/// motivation in detail.
-pub type Binders<T> = chalk_ir::Binders<T>;
+pub(crate) type Binders<T> = chalk_ir::Binders<T>;
/// Interned list of generic arguments for an item. When an item has parent, the `Substitution` for
/// it contains generic arguments for both its parent and itself. See chalk's documentation for
/// details.
///
/// See `Binders` for the constraint on the ordering.
-pub type Substitution = chalk_ir::Substitution<Interner>;
-pub type GenericArg = chalk_ir::GenericArg<Interner>;
-pub type GenericArgData = chalk_ir::GenericArgData<Interner>;
+pub(crate) type Substitution = chalk_ir::Substitution<Interner>;
+pub(crate) type GenericArg = chalk_ir::GenericArg<Interner>;
+pub(crate) type GenericArgData = chalk_ir::GenericArgData<Interner>;
-pub type Ty = chalk_ir::Ty<Interner>;
+pub(crate) type Ty = chalk_ir::Ty<Interner>;
pub type TyKind = chalk_ir::TyKind<Interner>;
-pub type TypeFlags = chalk_ir::TypeFlags;
+pub(crate) type TypeFlags = chalk_ir::TypeFlags;
pub(crate) type DynTy = chalk_ir::DynTy<Interner>;
-pub type FnPointer = chalk_ir::FnPointer<Interner>;
+pub(crate) type FnPointer = chalk_ir::FnPointer<Interner>;
pub(crate) use chalk_ir::FnSubst; // a re-export so we don't lose the tuple constructor
pub type AliasTy = chalk_ir::AliasTy<Interner>;
-pub type ProjectionTy = chalk_ir::ProjectionTy<Interner>;
+pub(crate) type ProjectionTy = chalk_ir::ProjectionTy<Interner>;
pub(crate) type OpaqueTy = chalk_ir::OpaqueTy<Interner>;
-pub(crate) type InferenceVar = chalk_ir::InferenceVar;
pub(crate) type Lifetime = chalk_ir::Lifetime<Interner>;
pub(crate) type LifetimeData = chalk_ir::LifetimeData<Interner>;
pub(crate) type LifetimeOutlives = chalk_ir::LifetimeOutlives<Interner>;
-pub type ConstValue = chalk_ir::ConstValue<Interner>;
+pub(crate) type ConstValue = chalk_ir::ConstValue<Interner>;
-pub type Const = chalk_ir::Const<Interner>;
+pub(crate) type Const = chalk_ir::Const<Interner>;
pub(crate) type ConstData = chalk_ir::ConstData<Interner>;
pub(crate) type ConcreteConst = chalk_ir::ConcreteConst<Interner>;
-pub type TraitRef = chalk_ir::TraitRef<Interner>;
-pub type QuantifiedWhereClause = Binders<WhereClause>;
-pub type Canonical<T> = chalk_ir::Canonical<T>;
+pub(crate) type TraitRef = chalk_ir::TraitRef<Interner>;
+pub(crate) type QuantifiedWhereClause = Binders<WhereClause>;
+pub(crate) type Canonical<T> = chalk_ir::Canonical<T>;
pub(crate) type ChalkTraitId = chalk_ir::TraitId<Interner>;
pub(crate) type QuantifiedWhereClauses = chalk_ir::QuantifiedWhereClauses<Interner>;
pub(crate) type FnSig = chalk_ir::FnSig<Interner>;
-pub type InEnvironment<T> = chalk_ir::InEnvironment<T>;
+pub(crate) type InEnvironment<T> = chalk_ir::InEnvironment<T>;
pub type AliasEq = chalk_ir::AliasEq<Interner>;
pub type WhereClause = chalk_ir::WhereClause<Interner>;
@@ -233,7 +229,7 @@ impl ComplexMemoryMap<'_> {
}
impl<'db> MemoryMap<'db> {
- pub fn vtable_ty(&self, id: usize) -> Result<crate::next_solver::Ty<'db>, MirEvalError> {
+ pub fn vtable_ty(&self, id: usize) -> Result<crate::next_solver::Ty<'db>, MirEvalError<'db>> {
match self {
MemoryMap::Empty | MemoryMap::Simple(_) => Err(MirEvalError::InvalidVTableId(id)),
MemoryMap::Complex(cm) => cm.vtable.ty(id),
@@ -249,8 +245,8 @@ impl<'db> MemoryMap<'db> {
/// allocator function as `f` and it will return a mapping of old addresses to new addresses.
fn transform_addresses(
&self,
- mut f: impl FnMut(&[u8], usize) -> Result<usize, MirEvalError>,
- ) -> Result<FxHashMap<usize, usize>, MirEvalError> {
+ mut f: impl FnMut(&[u8], usize) -> Result<usize, MirEvalError<'db>>,
+ ) -> Result<FxHashMap<usize, usize>, MirEvalError<'db>> {
let mut transform = |(addr, val): (&usize, &[u8])| {
let addr = *addr;
let align = if addr == 0 { 64 } else { (addr - (addr & (addr - 1))).min(64) };
@@ -646,7 +642,7 @@ impl TypeFoldable<Interner> for CallableSig {
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub enum ImplTraitId {
- ReturnTypeImplTrait(hir_def::FunctionId, ImplTraitIdx),
+ ReturnTypeImplTrait(hir_def::FunctionId, ImplTraitIdx), // FIXME(next-solver): Should be crate::nextsolver::ImplTraitIdx.
TypeAliasImplTrait(hir_def::TypeAliasId, ImplTraitIdx),
AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId),
}
@@ -713,219 +709,170 @@ pub(crate) fn fold_free_vars<T: HasInterner<Interner = Interner> + TypeFoldable<
t.fold_with(&mut FreeVarFolder(for_ty, for_const), DebruijnIndex::INNERMOST)
}
-pub(crate) fn fold_tys<T: HasInterner<Interner = Interner> + TypeFoldable<Interner>>(
- t: T,
- mut for_ty: impl FnMut(Ty, DebruijnIndex) -> Ty,
- binders: DebruijnIndex,
-) -> T {
- fold_tys_and_consts(
- t,
- |x, d| match x {
- Either::Left(x) => Either::Left(for_ty(x, d)),
- Either::Right(x) => Either::Right(x),
- },
- binders,
- )
-}
-
-pub(crate) fn fold_tys_and_consts<T: HasInterner<Interner = Interner> + TypeFoldable<Interner>>(
- t: T,
- f: impl FnMut(Either<Ty, Const>, DebruijnIndex) -> Either<Ty, Const>,
- binders: DebruijnIndex,
-) -> T {
- use chalk_ir::fold::{TypeFolder, TypeSuperFoldable};
- #[derive(chalk_derive::FallibleTypeFolder)]
- #[has_interner(Interner)]
- struct TyFolder<F: FnMut(Either<Ty, Const>, DebruijnIndex) -> Either<Ty, Const>>(F);
- impl<F: FnMut(Either<Ty, Const>, DebruijnIndex) -> Either<Ty, Const>> TypeFolder<Interner>
- for TyFolder<F>
- {
- fn as_dyn(&mut self) -> &mut dyn TypeFolder<Interner> {
- self
- }
-
- fn interner(&self) -> Interner {
- Interner
- }
-
- fn fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Ty {
- let ty = ty.super_fold_with(self.as_dyn(), outer_binder);
- self.0(Either::Left(ty), outer_binder).left().unwrap()
- }
-
- fn fold_const(&mut self, c: Const, outer_binder: DebruijnIndex) -> Const {
- self.0(Either::Right(c), outer_binder).right().unwrap()
- }
- }
- t.fold_with(&mut TyFolder(f), binders)
-}
-
-pub(crate) fn fold_generic_args<T: HasInterner<Interner = Interner> + TypeFoldable<Interner>>(
- t: T,
- f: impl FnMut(GenericArgData, DebruijnIndex) -> GenericArgData,
- binders: DebruijnIndex,
-) -> T {
- use chalk_ir::fold::{TypeFolder, TypeSuperFoldable};
- #[derive(chalk_derive::FallibleTypeFolder)]
- #[has_interner(Interner)]
- struct TyFolder<F: FnMut(GenericArgData, DebruijnIndex) -> GenericArgData>(F);
- impl<F: FnMut(GenericArgData, DebruijnIndex) -> GenericArgData> TypeFolder<Interner>
- for TyFolder<F>
- {
- fn as_dyn(&mut self) -> &mut dyn TypeFolder<Interner> {
- self
- }
-
- fn interner(&self) -> Interner {
- Interner
- }
-
- fn fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Ty {
- let ty = ty.super_fold_with(self.as_dyn(), outer_binder);
- self.0(GenericArgData::Ty(ty), outer_binder)
- .intern(Interner)
- .ty(Interner)
- .unwrap()
- .clone()
- }
-
- fn fold_const(&mut self, c: Const, outer_binder: DebruijnIndex) -> Const {
- self.0(GenericArgData::Const(c), outer_binder)
- .intern(Interner)
- .constant(Interner)
- .unwrap()
- .clone()
- }
-
- fn fold_lifetime(&mut self, lt: Lifetime, outer_binder: DebruijnIndex) -> Lifetime {
- let lt = lt.super_fold_with(self.as_dyn(), outer_binder);
- self.0(GenericArgData::Lifetime(lt), outer_binder)
- .intern(Interner)
- .lifetime(Interner)
- .unwrap()
- .clone()
- }
- }
- t.fold_with(&mut TyFolder(f), binders)
-}
-
/// 'Canonicalizes' the `t` by replacing any errors with new variables. Also
/// ensures there are no unbound variables or inference variables anywhere in
/// the `t`.
-pub fn replace_errors_with_variables<T>(t: &T) -> Canonical<T>
+pub fn replace_errors_with_variables<'db, T>(
+ interner: DbInterner<'db>,
+ t: &T,
+) -> crate::next_solver::Canonical<'db, T>
where
- T: HasInterner<Interner = Interner> + TypeFoldable<Interner> + Clone,
+ T: rustc_type_ir::TypeFoldable<DbInterner<'db>> + Clone,
{
- use chalk_ir::{
- Fallible,
- fold::{FallibleTypeFolder, TypeSuperFoldable},
- };
- struct ErrorReplacer {
- vars: usize,
+ use rustc_type_ir::{FallibleTypeFolder, TypeSuperFoldable};
+ struct ErrorReplacer<'db> {
+ interner: DbInterner<'db>,
+ vars: Vec<crate::next_solver::CanonicalVarKind<'db>>,
+ binder: rustc_type_ir::DebruijnIndex,
}
- impl FallibleTypeFolder<Interner> for ErrorReplacer {
- type Error = NoSolution;
-
- fn as_dyn(&mut self) -> &mut dyn FallibleTypeFolder<Interner, Error = Self::Error> {
- self
- }
-
- fn interner(&self) -> Interner {
- Interner
- }
+ impl<'db> FallibleTypeFolder<DbInterner<'db>> for ErrorReplacer<'db> {
+ #[cfg(debug_assertions)]
+ type Error = ();
+ #[cfg(not(debug_assertions))]
+ type Error = std::convert::Infallible;
- fn try_fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Fallible<Ty> {
- if let TyKind::Error = ty.kind(Interner) {
- let index = self.vars;
- self.vars += 1;
- Ok(TyKind::BoundVar(BoundVar::new(outer_binder, index)).intern(Interner))
- } else {
- ty.try_super_fold_with(self.as_dyn(), outer_binder)
- }
+ fn cx(&self) -> DbInterner<'db> {
+ self.interner
}
- fn try_fold_inference_ty(
+ fn try_fold_binder<T>(
&mut self,
- _var: InferenceVar,
- _kind: TyVariableKind,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Ty> {
- if cfg!(debug_assertions) {
- // we don't want to just panic here, because then the error message
- // won't contain the whole thing, which would not be very helpful
- Err(NoSolution)
- } else {
- Ok(TyKind::Error.intern(Interner))
- }
- }
-
- fn try_fold_free_var_ty(
+ t: crate::next_solver::Binder<'db, T>,
+ ) -> Result<crate::next_solver::Binder<'db, T>, Self::Error>
+ where
+ T: rustc_type_ir::TypeFoldable<DbInterner<'db>>,
+ {
+ self.binder.shift_in(1);
+ let result = t.try_super_fold_with(self);
+ self.binder.shift_out(1);
+ result
+ }
+
+ fn try_fold_ty(
&mut self,
- _bound_var: BoundVar,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Ty> {
- if cfg!(debug_assertions) {
- // we don't want to just panic here, because then the error message
- // won't contain the whole thing, which would not be very helpful
- Err(NoSolution)
- } else {
- Ok(TyKind::Error.intern(Interner))
+ t: crate::next_solver::Ty<'db>,
+ ) -> Result<crate::next_solver::Ty<'db>, Self::Error> {
+ if !t.has_type_flags(
+ rustc_type_ir::TypeFlags::HAS_ERROR
+ | rustc_type_ir::TypeFlags::HAS_TY_INFER
+ | rustc_type_ir::TypeFlags::HAS_CT_INFER
+ | rustc_type_ir::TypeFlags::HAS_RE_INFER,
+ ) {
+ return Ok(t);
}
- }
- fn try_fold_inference_const(
- &mut self,
- ty: Ty,
- _var: InferenceVar,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Const> {
- if cfg!(debug_assertions) { Err(NoSolution) } else { Ok(unknown_const(ty)) }
+ #[cfg(debug_assertions)]
+ let error = || Err(());
+ #[cfg(not(debug_assertions))]
+ let error = || Ok(crate::next_solver::Ty::new_error(self.interner, ErrorGuaranteed));
+
+ match t.kind() {
+ crate::next_solver::TyKind::Error(_) => {
+ let var = rustc_type_ir::BoundVar::from_usize(self.vars.len());
+ self.vars.push(crate::next_solver::CanonicalVarKind::Ty {
+ ui: rustc_type_ir::UniverseIndex::ZERO,
+ sub_root: var,
+ });
+ Ok(crate::next_solver::Ty::new_bound(
+ self.interner,
+ self.binder,
+ crate::next_solver::BoundTy {
+ var,
+ kind: crate::next_solver::BoundTyKind::Anon,
+ },
+ ))
+ }
+ crate::next_solver::TyKind::Infer(_) => error(),
+ crate::next_solver::TyKind::Bound(index, _) if index > self.binder => error(),
+ _ => t.try_super_fold_with(self),
+ }
}
- fn try_fold_free_var_const(
+ fn try_fold_const(
&mut self,
- ty: Ty,
- _bound_var: BoundVar,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Const> {
- if cfg!(debug_assertions) { Err(NoSolution) } else { Ok(unknown_const(ty)) }
- }
+ ct: crate::next_solver::Const<'db>,
+ ) -> Result<crate::next_solver::Const<'db>, Self::Error> {
+ if !ct.has_type_flags(
+ rustc_type_ir::TypeFlags::HAS_ERROR
+ | rustc_type_ir::TypeFlags::HAS_TY_INFER
+ | rustc_type_ir::TypeFlags::HAS_CT_INFER
+ | rustc_type_ir::TypeFlags::HAS_RE_INFER,
+ ) {
+ return Ok(ct);
+ }
- fn try_fold_inference_lifetime(
- &mut self,
- _var: InferenceVar,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Lifetime> {
- if cfg!(debug_assertions) { Err(NoSolution) } else { Ok(error_lifetime()) }
+ #[cfg(debug_assertions)]
+ let error = || Err(());
+ #[cfg(not(debug_assertions))]
+ let error = || Ok(crate::next_solver::Const::error(self.interner));
+
+ match ct.kind() {
+ crate::next_solver::ConstKind::Error(_) => {
+ let var = rustc_type_ir::BoundVar::from_usize(self.vars.len());
+ self.vars.push(crate::next_solver::CanonicalVarKind::Const(
+ rustc_type_ir::UniverseIndex::ZERO,
+ ));
+ Ok(crate::next_solver::Const::new_bound(
+ self.interner,
+ self.binder,
+ crate::next_solver::BoundConst { var },
+ ))
+ }
+ crate::next_solver::ConstKind::Infer(_) => error(),
+ crate::next_solver::ConstKind::Bound(index, _) if index > self.binder => error(),
+ _ => ct.try_super_fold_with(self),
+ }
}
- fn try_fold_free_var_lifetime(
+ fn try_fold_region(
&mut self,
- _bound_var: BoundVar,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Lifetime> {
- if cfg!(debug_assertions) { Err(NoSolution) } else { Ok(error_lifetime()) }
+ region: crate::next_solver::Region<'db>,
+ ) -> Result<crate::next_solver::Region<'db>, Self::Error> {
+ #[cfg(debug_assertions)]
+ let error = || Err(());
+ #[cfg(not(debug_assertions))]
+ let error = || Ok(crate::next_solver::Region::error(self.interner));
+
+ match region.kind() {
+ crate::next_solver::RegionKind::ReError(_) => {
+ let var = rustc_type_ir::BoundVar::from_usize(self.vars.len());
+ self.vars.push(crate::next_solver::CanonicalVarKind::Region(
+ rustc_type_ir::UniverseIndex::ZERO,
+ ));
+ Ok(crate::next_solver::Region::new_bound(
+ self.interner,
+ self.binder,
+ crate::next_solver::BoundRegion {
+ var,
+ kind: crate::next_solver::BoundRegionKind::Anon,
+ },
+ ))
+ }
+ crate::next_solver::RegionKind::ReVar(_) => error(),
+ crate::next_solver::RegionKind::ReBound(index, _) if index > self.binder => error(),
+ _ => Ok(region),
+ }
}
}
- let mut error_replacer = ErrorReplacer { vars: 0 };
- let value = match t.clone().try_fold_with(&mut error_replacer, DebruijnIndex::INNERMOST) {
+
+ let mut error_replacer =
+ ErrorReplacer { vars: Vec::new(), binder: rustc_type_ir::DebruijnIndex::ZERO, interner };
+ let value = match t.clone().try_fold_with(&mut error_replacer) {
Ok(t) => t,
Err(_) => panic!("Encountered unbound or inference vars in {t:?}"),
};
- let kinds = (0..error_replacer.vars).map(|_| {
- chalk_ir::CanonicalVarKind::new(
- chalk_ir::VariableKind::Ty(TyVariableKind::General),
- chalk_ir::UniverseIndex::ROOT,
- )
- });
- Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(Interner, kinds) }
+ crate::next_solver::Canonical {
+ value,
+ max_universe: rustc_type_ir::UniverseIndex::ZERO,
+ variables: crate::next_solver::CanonicalVars::new_from_iter(interner, error_replacer.vars),
+ }
}
pub fn callable_sig_from_fn_trait<'db>(
- self_ty: &Ty,
+ self_ty: crate::next_solver::Ty<'db>,
trait_env: Arc<TraitEnvironment<'db>>,
db: &'db dyn HirDatabase,
-) -> Option<(FnTrait, CallableSig)> {
+) -> Option<(FnTrait, crate::next_solver::PolyFnSig<'db>)> {
let krate = trait_env.krate;
let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?;
let output_assoc_type = fn_once_trait
@@ -942,46 +889,47 @@ pub fn callable_sig_from_fn_trait<'db>(
// - Self: FnOnce<?args_ty>
// - <Self as FnOnce<?args_ty>>::Output == ?ret_ty
let args_ty = table.next_ty_var();
- let args = [self_ty.to_nextsolver(table.interner), args_ty];
- let trait_ref = crate::next_solver::TraitRef::new(table.interner, fn_once_trait.into(), args);
+ let args = [self_ty, args_ty];
+ let trait_ref = crate::next_solver::TraitRef::new(table.interner(), fn_once_trait.into(), args);
let projection = crate::next_solver::Ty::new_alias(
- table.interner,
+ table.interner(),
rustc_type_ir::AliasTyKind::Projection,
- crate::next_solver::AliasTy::new(table.interner, output_assoc_type.into(), args),
+ crate::next_solver::AliasTy::new(table.interner(), output_assoc_type.into(), args),
);
- let pred = crate::next_solver::Predicate::upcast_from(trait_ref, table.interner);
+ let pred = crate::next_solver::Predicate::upcast_from(trait_ref, table.interner());
if !table.try_obligation(pred).no_solution() {
table.register_obligation(pred);
let return_ty = table.normalize_alias_ty(projection);
for fn_x in [FnTrait::Fn, FnTrait::FnMut, FnTrait::FnOnce] {
let fn_x_trait = fn_x.get_id(db, krate)?;
let trait_ref =
- crate::next_solver::TraitRef::new(table.interner, fn_x_trait.into(), args);
+ crate::next_solver::TraitRef::new(table.interner(), fn_x_trait.into(), args);
if !table
.try_obligation(crate::next_solver::Predicate::upcast_from(
trait_ref,
- table.interner,
+ table.interner(),
))
.no_solution()
{
- let ret_ty = table.resolve_completely(return_ty.to_chalk(table.interner));
- let args_ty = table.resolve_completely(args_ty.to_chalk(table.interner));
- let params = args_ty
- .as_tuple()?
- .iter(Interner)
- .map(|it| it.assert_ty_ref(Interner))
- .cloned();
+ let ret_ty = table.resolve_completely(return_ty);
+ let args_ty = table.resolve_completely(args_ty);
+ let crate::next_solver::TyKind::Tuple(params) = args_ty.kind() else {
+ return None;
+ };
+ let inputs_and_output = crate::next_solver::Tys::new_from_iter(
+ table.interner(),
+ params.iter().chain(std::iter::once(ret_ty)),
+ );
return Some((
fn_x,
- CallableSig::from_params_and_return(
- params,
- ret_ty,
- false,
- Safety::Safe,
- FnAbi::RustCall,
- ),
+ crate::next_solver::Binder::dummy(crate::next_solver::FnSig {
+ inputs_and_output,
+ c_variadic: false,
+ safety: crate::next_solver::abi::Safety::Safe,
+ abi: FnAbi::RustCall,
+ }),
));
}
}
@@ -991,74 +939,43 @@ pub fn callable_sig_from_fn_trait<'db>(
}
}
-struct PlaceholderCollector<'db> {
- db: &'db dyn HirDatabase,
- placeholders: FxHashSet<TypeOrConstParamId>,
-}
-
-impl PlaceholderCollector<'_> {
- fn collect(&mut self, idx: PlaceholderIndex) {
- let id = from_placeholder_idx(self.db, idx).0;
- self.placeholders.insert(id);
- }
+struct ParamCollector {
+ params: FxHashSet<TypeOrConstParamId>,
}
-impl TypeVisitor<Interner> for PlaceholderCollector<'_> {
- type BreakTy = ();
-
- fn as_dyn(&mut self) -> &mut dyn TypeVisitor<Interner, BreakTy = Self::BreakTy> {
- self
- }
-
- fn interner(&self) -> Interner {
- Interner
- }
+impl<'db> rustc_type_ir::TypeVisitor<DbInterner<'db>> for ParamCollector {
+ type Result = ();
- fn visit_ty(
- &mut self,
- ty: &Ty,
- outer_binder: DebruijnIndex,
- ) -> std::ops::ControlFlow<Self::BreakTy> {
- let has_placeholder_bits = TypeFlags::HAS_TY_PLACEHOLDER | TypeFlags::HAS_CT_PLACEHOLDER;
- let chalk_ir::TyData { kind, flags } = ty.data(Interner);
-
- if let TyKind::Placeholder(idx) = kind {
- self.collect(*idx);
- } else if flags.intersects(has_placeholder_bits) {
- return ty.super_visit_with(self, outer_binder);
- } else {
- // Fast path: don't visit inner types (e.g. generic arguments) when `flags` indicate
- // that there are no placeholders.
+ fn visit_ty(&mut self, ty: crate::next_solver::Ty<'db>) -> Self::Result {
+ if let crate::next_solver::TyKind::Param(param) = ty.kind() {
+ self.params.insert(param.id.into());
}
- std::ops::ControlFlow::Continue(())
+ ty.super_visit_with(self);
}
- fn visit_const(
- &mut self,
- constant: &chalk_ir::Const<Interner>,
- _outer_binder: DebruijnIndex,
- ) -> std::ops::ControlFlow<Self::BreakTy> {
- if let chalk_ir::ConstValue::Placeholder(idx) = constant.data(Interner).value {
- self.collect(idx);
+ fn visit_const(&mut self, konst: crate::next_solver::Const<'db>) -> Self::Result {
+ if let crate::next_solver::ConstKind::Param(param) = konst.kind() {
+ self.params.insert(param.id.into());
}
- std::ops::ControlFlow::Continue(())
+
+ konst.super_visit_with(self);
}
}
-/// Returns unique placeholders for types and consts contained in `value`.
-pub fn collect_placeholders<T>(value: &T, db: &dyn HirDatabase) -> Vec<TypeOrConstParamId>
+/// Returns unique params for types and consts contained in `value`.
+pub fn collect_params<'db, T>(value: &T) -> Vec<TypeOrConstParamId>
where
- T: ?Sized + TypeVisitable<Interner>,
+ T: ?Sized + rustc_type_ir::TypeVisitable<DbInterner<'db>>,
{
- let mut collector = PlaceholderCollector { db, placeholders: FxHashSet::default() };
- _ = value.visit_with(&mut collector, DebruijnIndex::INNERMOST);
- collector.placeholders.into_iter().collect()
+ let mut collector = ParamCollector { params: FxHashSet::default() };
+ value.visit_with(&mut collector);
+ Vec::from_iter(collector.params)
}
-pub fn known_const_to_ast(
- konst: &Const,
- db: &dyn HirDatabase,
+pub fn known_const_to_ast<'db>(
+ konst: crate::next_solver::Const<'db>,
+ db: &'db dyn HirDatabase,
display_target: DisplayTarget,
) -> Option<ConstArg> {
Some(make::expr_const_value(konst.display(db, display_target).to_string().as_str()))