Merge pull request #20873 from ChayimFriedman2/to-ns2
Rip Chalk out of the codebase 🎉
This commit is contained in:
commit
aae9712904
52 changed files with 2421 additions and 8663 deletions
|
|
@ -258,28 +258,6 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||
|
||||
[[package]]
|
||||
name = "chalk-derive"
|
||||
version = "0.104.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ea9b1e80910f66ae87c772247591432032ef3f6a67367ff17f8343db05beafa"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chalk-ir"
|
||||
version = "0.104.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7047a516de16226cd17344d41a319d0ea1064bf9e60bd612ab341ab4a34bbfa8"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"chalk-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.48"
|
||||
|
|
@ -777,8 +755,6 @@ dependencies = [
|
|||
"arrayvec",
|
||||
"base-db",
|
||||
"bitflags 2.9.4",
|
||||
"chalk-derive",
|
||||
"chalk-ir",
|
||||
"cov-mark",
|
||||
"either",
|
||||
"ena",
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@ debug = 2
|
|||
[patch.'crates-io']
|
||||
# rowan = { path = "../rowan" }
|
||||
|
||||
# chalk-ir = { path = "../chalk/chalk-ir" }
|
||||
# chalk-derive = { path = "../chalk/chalk-derive" }
|
||||
# line-index = { path = "lib/line-index" }
|
||||
# la-arena = { path = "lib/la-arena" }
|
||||
# lsp-server = { path = "lib/lsp-server" }
|
||||
|
|
@ -110,8 +108,6 @@ arrayvec = "0.7.6"
|
|||
bitflags = "2.9.1"
|
||||
cargo_metadata = "0.21.0"
|
||||
camino = "1.1.10"
|
||||
chalk-ir = "0.104.0"
|
||||
chalk-derive = "0.104.0"
|
||||
crossbeam-channel = "0.5.15"
|
||||
dissimilar = "1.0.10"
|
||||
dot = "0.1.4"
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ oorandom = "11.1.5"
|
|||
tracing.workspace = true
|
||||
rustc-hash.workspace = true
|
||||
scoped-tls = "1.0.1"
|
||||
chalk-ir.workspace = true
|
||||
chalk-derive.workspace = true
|
||||
la-arena.workspace = true
|
||||
triomphe.workspace = true
|
||||
typed-arena = "2.0.2"
|
||||
|
|
|
|||
|
|
@ -1,211 +0,0 @@
|
|||
//! `TyBuilder`, a helper for building instances of `Ty` and related types.
|
||||
|
||||
use chalk_ir::{
|
||||
DebruijnIndex,
|
||||
cast::{Cast, Caster},
|
||||
};
|
||||
use hir_def::{GenericDefId, GenericParamId, TraitId};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::{
|
||||
BoundVar, GenericArg, GenericArgData, Interner, Substitution, TraitRef, Ty, TyKind,
|
||||
consteval::unknown_const_as_generic,
|
||||
db::HirDatabase,
|
||||
error_lifetime,
|
||||
generics::generics,
|
||||
infer::unify::InferenceTable,
|
||||
next_solver::{
|
||||
DbInterner, EarlyBinder,
|
||||
mapping::{ChalkToNextSolver, NextSolverToChalk},
|
||||
},
|
||||
to_chalk_trait_id,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub(crate) enum ParamKind {
|
||||
Type,
|
||||
Lifetime,
|
||||
Const(Ty),
|
||||
}
|
||||
|
||||
/// This is a builder for `Ty` or anything that needs a `Substitution`.
|
||||
pub(crate) struct TyBuilder<D> {
|
||||
/// The `data` field is used to keep track of what we're building (e.g. an
|
||||
/// ADT, a `TraitRef`, ...).
|
||||
data: D,
|
||||
vec: SmallVec<[GenericArg; 2]>,
|
||||
param_kinds: SmallVec<[ParamKind; 2]>,
|
||||
parent_subst: Substitution,
|
||||
}
|
||||
|
||||
impl<A> TyBuilder<A> {
|
||||
fn with_data<B>(self, data: B) -> TyBuilder<B> {
|
||||
TyBuilder {
|
||||
data,
|
||||
vec: self.vec,
|
||||
param_kinds: self.param_kinds,
|
||||
parent_subst: self.parent_subst,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<D> TyBuilder<D> {
|
||||
fn new(
|
||||
data: D,
|
||||
param_kinds: SmallVec<[ParamKind; 2]>,
|
||||
parent_subst: Option<Substitution>,
|
||||
) -> Self {
|
||||
let parent_subst = parent_subst.unwrap_or_else(|| Substitution::empty(Interner));
|
||||
Self { data, vec: SmallVec::with_capacity(param_kinds.len()), param_kinds, parent_subst }
|
||||
}
|
||||
|
||||
fn build_internal(self) -> (D, Substitution) {
|
||||
assert_eq!(
|
||||
self.vec.len(),
|
||||
self.param_kinds.len(),
|
||||
"{} args received, {} expected ({:?})",
|
||||
self.vec.len(),
|
||||
self.param_kinds.len(),
|
||||
&self.param_kinds
|
||||
);
|
||||
for (a, e) in self.vec.iter().zip(self.param_kinds.iter()) {
|
||||
self.assert_match_kind(a, e);
|
||||
}
|
||||
let subst = Substitution::from_iter(
|
||||
Interner,
|
||||
self.parent_subst.iter(Interner).cloned().chain(self.vec),
|
||||
);
|
||||
(self.data, subst)
|
||||
}
|
||||
|
||||
pub(crate) fn remaining(&self) -> usize {
|
||||
self.param_kinds.len() - self.vec.len()
|
||||
}
|
||||
|
||||
pub(crate) fn fill_with_bound_vars(
|
||||
self,
|
||||
debruijn: DebruijnIndex,
|
||||
starting_from: usize,
|
||||
) -> Self {
|
||||
// self.fill is inlined to make borrow checker happy
|
||||
let mut this = self;
|
||||
let other = &this.param_kinds[this.vec.len()..];
|
||||
let filler = (starting_from..).zip(other).map(|(idx, kind)| match kind {
|
||||
ParamKind::Type => BoundVar::new(debruijn, idx).to_ty(Interner).cast(Interner),
|
||||
ParamKind::Const(ty) => {
|
||||
BoundVar::new(debruijn, idx).to_const(Interner, ty.clone()).cast(Interner)
|
||||
}
|
||||
ParamKind::Lifetime => {
|
||||
BoundVar::new(debruijn, idx).to_lifetime(Interner).cast(Interner)
|
||||
}
|
||||
});
|
||||
this.vec.extend(filler.take(this.remaining()).casted(Interner));
|
||||
assert_eq!(this.remaining(), 0);
|
||||
this
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) fn fill_with_inference_vars(self, table: &mut InferenceTable<'_>) -> Self {
|
||||
self.fill(|x| {
|
||||
match x {
|
||||
ParamKind::Type => crate::next_solver::GenericArg::Ty(table.next_ty_var()),
|
||||
ParamKind::Const(_) => table.next_const_var().into(),
|
||||
ParamKind::Lifetime => table.next_region_var().into(),
|
||||
}
|
||||
.to_chalk(table.interner())
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn fill(mut self, filler: impl FnMut(&ParamKind) -> GenericArg) -> Self {
|
||||
self.vec.extend(self.param_kinds[self.vec.len()..].iter().map(filler));
|
||||
assert_eq!(self.remaining(), 0);
|
||||
self
|
||||
}
|
||||
|
||||
fn assert_match_kind(&self, a: &chalk_ir::GenericArg<Interner>, e: &ParamKind) {
|
||||
match (a.data(Interner), e) {
|
||||
(GenericArgData::Ty(_), ParamKind::Type)
|
||||
| (GenericArgData::Const(_), ParamKind::Const(_))
|
||||
| (GenericArgData::Lifetime(_), ParamKind::Lifetime) => (),
|
||||
_ => panic!("Mismatched kinds: {a:?}, {:?}, {:?}", self.vec, self.param_kinds),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TyBuilder<()> {
|
||||
pub(crate) fn usize() -> Ty {
|
||||
TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::Usize)).intern(Interner)
|
||||
}
|
||||
|
||||
pub(crate) fn unknown_subst(
|
||||
db: &dyn HirDatabase,
|
||||
def: impl Into<GenericDefId>,
|
||||
) -> Substitution {
|
||||
let interner = DbInterner::conjure();
|
||||
let params = generics(db, def.into());
|
||||
Substitution::from_iter(
|
||||
Interner,
|
||||
params.iter_id().map(|id| match id {
|
||||
GenericParamId::TypeParamId(_) => TyKind::Error.intern(Interner).cast(Interner),
|
||||
GenericParamId::ConstParamId(id) => {
|
||||
unknown_const_as_generic(db.const_param_ty_ns(id))
|
||||
.to_chalk(interner)
|
||||
.cast(Interner)
|
||||
}
|
||||
GenericParamId::LifetimeParamId(_) => error_lifetime().cast(Interner),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) fn subst_for_def(
|
||||
db: &dyn HirDatabase,
|
||||
def: impl Into<GenericDefId>,
|
||||
parent_subst: Option<Substitution>,
|
||||
) -> TyBuilder<()> {
|
||||
let generics = generics(db, def.into());
|
||||
assert!(generics.parent_generics().is_some() == parent_subst.is_some());
|
||||
let params = generics
|
||||
.iter_self()
|
||||
.map(|(id, _data)| match id {
|
||||
GenericParamId::TypeParamId(_) => ParamKind::Type,
|
||||
GenericParamId::ConstParamId(id) => ParamKind::Const(db.const_param_ty(id)),
|
||||
GenericParamId::LifetimeParamId(_) => ParamKind::Lifetime,
|
||||
})
|
||||
.collect();
|
||||
TyBuilder::new((), params, parent_subst)
|
||||
}
|
||||
|
||||
pub(crate) fn build(self) -> Substitution {
|
||||
let ((), subst) = self.build_internal();
|
||||
subst
|
||||
}
|
||||
}
|
||||
|
||||
impl TyBuilder<TraitId> {
|
||||
pub(crate) fn trait_ref(db: &dyn HirDatabase, def: TraitId) -> TyBuilder<TraitId> {
|
||||
TyBuilder::subst_for_def(db, def, None).with_data(def)
|
||||
}
|
||||
|
||||
pub(crate) fn build(self) -> TraitRef {
|
||||
let (trait_id, substitution) = self.build_internal();
|
||||
TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'db, T: rustc_type_ir::TypeFoldable<DbInterner<'db>>> TyBuilder<EarlyBinder<'db, T>> {
|
||||
pub(crate) fn build(self, interner: DbInterner<'db>) -> T {
|
||||
let (b, subst) = self.build_internal();
|
||||
let args: crate::next_solver::GenericArgs<'db> = subst.to_nextsolver(interner);
|
||||
b.instantiate(interner, args)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'db> TyBuilder<EarlyBinder<'db, crate::next_solver::Ty<'db>>> {
|
||||
pub(crate) fn impl_self_ty(
|
||||
db: &'db dyn HirDatabase,
|
||||
def: hir_def::ImplId,
|
||||
) -> TyBuilder<EarlyBinder<'db, crate::next_solver::Ty<'db>>> {
|
||||
TyBuilder::subst_for_def(db, def, None).with_data(db.impl_self_ty(def))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
//! The implementation of `RustIrDatabase` for Chalk, which provides information
|
||||
//! about the code that Chalk needs.
|
||||
|
||||
use crate::Interner;
|
||||
|
||||
pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
|
||||
pub(crate) type TraitId = chalk_ir::TraitId<Interner>;
|
||||
pub(crate) type AdtId = chalk_ir::AdtId<Interner>;
|
||||
pub(crate) type ImplId = chalk_ir::ImplId<Interner>;
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
//! Various extensions traits for Chalk types.
|
||||
|
||||
use hir_def::{ItemContainerId, Lookup, TraitId};
|
||||
|
||||
use crate::{
|
||||
Interner, ProjectionTy, Substitution, TraitRef, Ty, db::HirDatabase, from_assoc_type_id,
|
||||
from_chalk_trait_id, generics::generics, to_chalk_trait_id,
|
||||
};
|
||||
|
||||
pub(crate) trait ProjectionTyExt {
|
||||
fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef;
|
||||
fn trait_(&self, db: &dyn HirDatabase) -> TraitId;
|
||||
fn self_type_parameter(&self, db: &dyn HirDatabase) -> Ty;
|
||||
}
|
||||
|
||||
impl ProjectionTyExt for ProjectionTy {
|
||||
fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
|
||||
// FIXME: something like `Split` trait from chalk-solve might be nice.
|
||||
let generics = generics(db, from_assoc_type_id(self.associated_ty_id).into());
|
||||
let parent_len = generics.parent_generics().map_or(0, |g| g.len_self());
|
||||
let substitution =
|
||||
Substitution::from_iter(Interner, self.substitution.iter(Interner).take(parent_len));
|
||||
TraitRef { trait_id: to_chalk_trait_id(self.trait_(db)), substitution }
|
||||
}
|
||||
|
||||
fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
|
||||
match from_assoc_type_id(self.associated_ty_id).lookup(db).container {
|
||||
ItemContainerId::TraitId(it) => it,
|
||||
_ => panic!("projection ty without parent trait"),
|
||||
}
|
||||
}
|
||||
|
||||
fn self_type_parameter(&self, db: &dyn HirDatabase) -> Ty {
|
||||
self.trait_ref(db).self_type_parameter(Interner)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait TraitRefExt {
|
||||
fn hir_trait_id(&self) -> TraitId;
|
||||
}
|
||||
|
||||
impl TraitRefExt for TraitRef {
|
||||
fn hir_trait_id(&self) -> TraitId {
|
||||
from_chalk_trait_id(self.trait_id)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
//! Constant evaluation details
|
||||
|
||||
use base_db::Crate;
|
||||
use chalk_ir::{BoundVar, DebruijnIndex, cast::Cast};
|
||||
use hir_def::{
|
||||
expr_store::{HygieneId, path::Path},
|
||||
resolver::{Resolver, ValueNs},
|
||||
type_ref::LiteralConstRef,
|
||||
};
|
||||
use stdx::never;
|
||||
|
||||
use crate::{
|
||||
Const, ConstData, ConstScalar, ConstValue, GenericArg, Interner, MemoryMap, Substitution,
|
||||
TraitEnvironment, Ty,
|
||||
db::HirDatabase,
|
||||
generics::Generics,
|
||||
lower::ParamLoweringMode,
|
||||
next_solver::{DbInterner, mapping::ChalkToNextSolver},
|
||||
to_placeholder_idx,
|
||||
};
|
||||
|
||||
pub(crate) fn path_to_const<'g>(
|
||||
db: &dyn HirDatabase,
|
||||
resolver: &Resolver<'_>,
|
||||
path: &Path,
|
||||
mode: ParamLoweringMode,
|
||||
args: impl FnOnce() -> &'g Generics,
|
||||
debruijn: DebruijnIndex,
|
||||
expected_ty: Ty,
|
||||
) -> Option<Const> {
|
||||
match resolver.resolve_path_in_value_ns_fully(db, path, HygieneId::ROOT) {
|
||||
Some(ValueNs::GenericParam(p)) => {
|
||||
let ty = db.const_param_ty(p);
|
||||
let args = args();
|
||||
let value = match mode {
|
||||
ParamLoweringMode::Placeholder => {
|
||||
let idx = args.type_or_const_param_idx(p.into()).unwrap();
|
||||
ConstValue::Placeholder(to_placeholder_idx(db, p.into(), idx as u32))
|
||||
}
|
||||
ParamLoweringMode::Variable => match args.type_or_const_param_idx(p.into()) {
|
||||
Some(it) => ConstValue::BoundVar(BoundVar::new(debruijn, it)),
|
||||
None => {
|
||||
never!(
|
||||
"Generic list doesn't contain this param: {:?}, {:?}, {:?}",
|
||||
args,
|
||||
path,
|
||||
p
|
||||
);
|
||||
return None;
|
||||
}
|
||||
},
|
||||
};
|
||||
Some(ConstData { ty, value }.intern(Interner))
|
||||
}
|
||||
Some(ValueNs::ConstId(c)) => Some(intern_const_scalar(
|
||||
ConstScalar::UnevaluatedConst(c.into(), Substitution::empty(Interner)),
|
||||
expected_ty,
|
||||
)),
|
||||
// FIXME: With feature(adt_const_params), we also need to consider other things here, e.g. struct constructors.
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn unknown_const(ty: Ty) -> Const {
|
||||
ConstData {
|
||||
ty,
|
||||
value: ConstValue::Concrete(chalk_ir::ConcreteConst { interned: ConstScalar::Unknown }),
|
||||
}
|
||||
.intern(Interner)
|
||||
}
|
||||
|
||||
pub(crate) fn unknown_const_as_generic(ty: Ty) -> GenericArg {
|
||||
unknown_const(ty).cast(Interner)
|
||||
}
|
||||
|
||||
/// Interns a constant scalar with the given type
|
||||
pub(crate) fn intern_const_scalar(value: ConstScalar, ty: Ty) -> Const {
|
||||
ConstData { ty, value: ConstValue::Concrete(chalk_ir::ConcreteConst { interned: value }) }
|
||||
.intern(Interner)
|
||||
}
|
||||
|
||||
/// Interns a constant scalar with the given type
|
||||
pub(crate) fn intern_const_ref(
|
||||
db: &dyn HirDatabase,
|
||||
value: &LiteralConstRef,
|
||||
ty: Ty,
|
||||
krate: Crate,
|
||||
) -> Const {
|
||||
let interner = DbInterner::new_with(db, Some(krate), None);
|
||||
let layout = || db.layout_of_ty(ty.to_nextsolver(interner), TraitEnvironment::empty(krate));
|
||||
let bytes = match value {
|
||||
LiteralConstRef::Int(i) => {
|
||||
// FIXME: We should handle failure of layout better.
|
||||
let size = layout().map(|it| it.size.bytes_usize()).unwrap_or(16);
|
||||
ConstScalar::Bytes(i.to_le_bytes()[0..size].into(), MemoryMap::default())
|
||||
}
|
||||
LiteralConstRef::UInt(i) => {
|
||||
let size = layout().map(|it| it.size.bytes_usize()).unwrap_or(16);
|
||||
ConstScalar::Bytes(i.to_le_bytes()[0..size].into(), MemoryMap::default())
|
||||
}
|
||||
LiteralConstRef::Bool(b) => ConstScalar::Bytes(Box::new([*b as u8]), MemoryMap::default()),
|
||||
LiteralConstRef::Char(c) => {
|
||||
ConstScalar::Bytes((*c as u32).to_le_bytes().into(), MemoryMap::default())
|
||||
}
|
||||
LiteralConstRef::Unknown => ConstScalar::Unknown,
|
||||
};
|
||||
intern_const_scalar(bytes, ty)
|
||||
}
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
//! The home of `HirDatabase`, which is the Salsa database containing all the
|
||||
//! type inference-related queries.
|
||||
|
||||
use base_db::Crate;
|
||||
use base_db::target::TargetLoadError;
|
||||
use base_db::{Crate, target::TargetLoadError};
|
||||
use hir_def::{
|
||||
AdtId, BlockId, CallableDefId, ConstParamId, DefWithBodyId, EnumVariantId, FunctionId,
|
||||
GeneralConstId, GenericDefId, ImplId, LifetimeParamId, LocalFieldId, StaticId, TraitId,
|
||||
|
|
@ -16,13 +15,14 @@ use smallvec::SmallVec;
|
|||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
Binders, ImplTraitId, ImplTraits, InferenceResult, TraitEnvironment, Ty, TyDefId, ValueTyDefId,
|
||||
ImplTraitId, InferenceResult, TraitEnvironment, TyDefId, ValueTyDefId,
|
||||
consteval::ConstEvalError,
|
||||
dyn_compatibility::DynCompatibilityViolation,
|
||||
layout::{Layout, LayoutError},
|
||||
lower::{Diagnostics, GenericDefaults, GenericPredicates},
|
||||
lower::{Diagnostics, GenericDefaults, GenericPredicates, ImplTraits},
|
||||
method_resolution::{InherentImpls, TraitImpls, TyFingerprint},
|
||||
mir::{BorrowckResult, MirBody, MirLowerError},
|
||||
next_solver::{Const, EarlyBinder, GenericArgs, PolyFnSig, TraitRef, Ty, VariancesOf},
|
||||
};
|
||||
|
||||
#[query_group::query_group]
|
||||
|
|
@ -51,7 +51,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
|||
fn monomorphized_mir_body<'db>(
|
||||
&'db self,
|
||||
def: DefWithBodyId,
|
||||
subst: crate::next_solver::GenericArgs<'db>,
|
||||
subst: GenericArgs<'db>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>>;
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
|||
fn monomorphized_mir_body_for_closure<'db>(
|
||||
&'db self,
|
||||
def: InternedClosureId,
|
||||
subst: crate::next_solver::GenericArgs<'db>,
|
||||
subst: GenericArgs<'db>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
) -> Result<Arc<MirBody<'db>>, MirLowerError<'db>>;
|
||||
|
||||
|
|
@ -75,16 +75,13 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
|||
fn const_eval<'db>(
|
||||
&'db self,
|
||||
def: GeneralConstId,
|
||||
subst: crate::next_solver::GenericArgs<'db>,
|
||||
subst: GenericArgs<'db>,
|
||||
trait_env: Option<Arc<TraitEnvironment<'db>>>,
|
||||
) -> Result<crate::next_solver::Const<'db>, ConstEvalError<'db>>;
|
||||
) -> Result<Const<'db>, ConstEvalError<'db>>;
|
||||
|
||||
#[salsa::invoke(crate::consteval::const_eval_static_query)]
|
||||
#[salsa::cycle(cycle_result = crate::consteval::const_eval_static_cycle_result)]
|
||||
fn const_eval_static<'db>(
|
||||
&'db self,
|
||||
def: StaticId,
|
||||
) -> Result<crate::next_solver::Const<'db>, ConstEvalError<'db>>;
|
||||
fn const_eval_static<'db>(&'db self, def: StaticId) -> Result<Const<'db>, ConstEvalError<'db>>;
|
||||
|
||||
#[salsa::invoke(crate::consteval::const_eval_discriminant_variant)]
|
||||
#[salsa::cycle(cycle_result = crate::consteval::const_eval_discriminant_cycle_result)]
|
||||
|
|
@ -99,8 +96,8 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
|||
&'db self,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
func: FunctionId,
|
||||
fn_subst: crate::next_solver::GenericArgs<'db>,
|
||||
) -> (FunctionId, crate::next_solver::GenericArgs<'db>);
|
||||
fn_subst: GenericArgs<'db>,
|
||||
) -> (FunctionId, GenericArgs<'db>);
|
||||
|
||||
// endregion:mir
|
||||
|
||||
|
|
@ -109,7 +106,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
|||
fn layout_of_adt<'db>(
|
||||
&'db self,
|
||||
def: AdtId,
|
||||
args: crate::next_solver::GenericArgs<'db>,
|
||||
args: GenericArgs<'db>,
|
||||
trait_env: Arc<TraitEnvironment<'db>>,
|
||||
) -> Result<Arc<Layout>, LayoutError>;
|
||||
|
||||
|
|
@ -117,7 +114,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
|||
#[salsa::cycle(cycle_result = crate::layout::layout_of_ty_cycle_result)]
|
||||
fn layout_of_ty<'db>(
|
||||
&'db self,
|
||||
ty: crate::next_solver::Ty<'db>,
|
||||
ty: Ty<'db>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
) -> Result<Arc<Layout>, LayoutError>;
|
||||
|
||||
|
|
@ -127,149 +124,130 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
|||
#[salsa::invoke(crate::dyn_compatibility::dyn_compatibility_of_trait_query)]
|
||||
fn dyn_compatibility_of_trait(&self, trait_: TraitId) -> Option<DynCompatibilityViolation>;
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::ty_query)]
|
||||
#[salsa::invoke(crate::lower::ty_query)]
|
||||
#[salsa::transparent]
|
||||
fn ty<'db>(
|
||||
&'db self,
|
||||
def: TyDefId,
|
||||
) -> crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>;
|
||||
fn ty<'db>(&'db self, def: TyDefId) -> EarlyBinder<'db, Ty<'db>>;
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::type_for_type_alias_with_diagnostics_query)]
|
||||
#[salsa::cycle(cycle_result = crate::lower_nextsolver::type_for_type_alias_with_diagnostics_cycle_result)]
|
||||
#[salsa::invoke(crate::lower::type_for_type_alias_with_diagnostics_query)]
|
||||
#[salsa::cycle(cycle_result = crate::lower::type_for_type_alias_with_diagnostics_cycle_result)]
|
||||
fn type_for_type_alias_with_diagnostics<'db>(
|
||||
&'db self,
|
||||
def: TypeAliasId,
|
||||
) -> (crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>, Diagnostics);
|
||||
) -> (EarlyBinder<'db, Ty<'db>>, Diagnostics);
|
||||
|
||||
/// Returns the type of the value of the given constant, or `None` if the `ValueTyDefId` is
|
||||
/// a `StructId` or `EnumVariantId` with a record constructor.
|
||||
#[salsa::invoke(crate::lower_nextsolver::value_ty_query)]
|
||||
fn value_ty<'db>(
|
||||
&'db self,
|
||||
def: ValueTyDefId,
|
||||
) -> Option<crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>>;
|
||||
#[salsa::invoke(crate::lower::value_ty_query)]
|
||||
fn value_ty<'db>(&'db self, def: ValueTyDefId) -> Option<EarlyBinder<'db, Ty<'db>>>;
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::impl_self_ty_with_diagnostics_query)]
|
||||
#[salsa::cycle(cycle_result = crate::lower_nextsolver::impl_self_ty_with_diagnostics_cycle_result)]
|
||||
#[salsa::invoke(crate::lower::impl_self_ty_with_diagnostics_query)]
|
||||
#[salsa::cycle(cycle_result = crate::lower::impl_self_ty_with_diagnostics_cycle_result)]
|
||||
fn impl_self_ty_with_diagnostics<'db>(
|
||||
&'db self,
|
||||
def: ImplId,
|
||||
) -> (crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>, Diagnostics);
|
||||
) -> (EarlyBinder<'db, Ty<'db>>, Diagnostics);
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::impl_self_ty_query)]
|
||||
#[salsa::invoke(crate::lower::impl_self_ty_query)]
|
||||
#[salsa::transparent]
|
||||
fn impl_self_ty<'db>(
|
||||
&'db self,
|
||||
def: ImplId,
|
||||
) -> crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>;
|
||||
fn impl_self_ty<'db>(&'db self, def: ImplId) -> EarlyBinder<'db, Ty<'db>>;
|
||||
|
||||
// FIXME: Make this a non-interned query.
|
||||
#[salsa::invoke_interned(crate::lower_nextsolver::const_param_ty_with_diagnostics_query)]
|
||||
#[salsa::cycle(cycle_result = crate::lower_nextsolver::const_param_ty_with_diagnostics_cycle_result)]
|
||||
fn const_param_ty_with_diagnostics<'db>(
|
||||
&'db self,
|
||||
def: ConstParamId,
|
||||
) -> (crate::next_solver::Ty<'db>, Diagnostics);
|
||||
#[salsa::invoke_interned(crate::lower::const_param_ty_with_diagnostics_query)]
|
||||
#[salsa::cycle(cycle_result = crate::lower::const_param_ty_with_diagnostics_cycle_result)]
|
||||
fn const_param_ty_with_diagnostics<'db>(&'db self, def: ConstParamId)
|
||||
-> (Ty<'db>, Diagnostics);
|
||||
|
||||
// FIXME: Make this a non-interned query.
|
||||
#[salsa::invoke_interned(crate::lower::const_param_ty_query)]
|
||||
#[salsa::cycle(cycle_result = crate::lower::const_param_ty_cycle_result)]
|
||||
fn const_param_ty(&self, def: ConstParamId) -> Ty;
|
||||
#[salsa::invoke(crate::lower::const_param_ty_query)]
|
||||
#[salsa::transparent]
|
||||
fn const_param_ty_ns<'db>(&'db self, def: ConstParamId) -> Ty<'db>;
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::impl_trait_with_diagnostics_query)]
|
||||
#[salsa::invoke(crate::lower::impl_trait_with_diagnostics_query)]
|
||||
fn impl_trait_with_diagnostics<'db>(
|
||||
&'db self,
|
||||
def: ImplId,
|
||||
) -> Option<(
|
||||
crate::next_solver::EarlyBinder<'db, crate::next_solver::TraitRef<'db>>,
|
||||
Diagnostics,
|
||||
)>;
|
||||
) -> Option<(EarlyBinder<'db, TraitRef<'db>>, Diagnostics)>;
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::impl_trait_query)]
|
||||
#[salsa::invoke(crate::lower::impl_trait_query)]
|
||||
#[salsa::transparent]
|
||||
fn impl_trait<'db>(
|
||||
&'db self,
|
||||
def: ImplId,
|
||||
) -> Option<crate::next_solver::EarlyBinder<'db, crate::next_solver::TraitRef<'db>>>;
|
||||
fn impl_trait<'db>(&'db self, def: ImplId) -> Option<EarlyBinder<'db, TraitRef<'db>>>;
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::field_types_with_diagnostics_query)]
|
||||
#[salsa::invoke(crate::lower::field_types_with_diagnostics_query)]
|
||||
fn field_types_with_diagnostics<'db>(
|
||||
&'db self,
|
||||
var: VariantId,
|
||||
) -> (
|
||||
Arc<
|
||||
ArenaMap<
|
||||
LocalFieldId,
|
||||
crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>,
|
||||
>,
|
||||
>,
|
||||
Diagnostics,
|
||||
);
|
||||
) -> (Arc<ArenaMap<LocalFieldId, EarlyBinder<'db, Ty<'db>>>>, Diagnostics);
|
||||
|
||||
#[salsa::invoke(crate::lower::field_types_query)]
|
||||
#[salsa::transparent]
|
||||
fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>>;
|
||||
fn field_types<'db>(
|
||||
&'db self,
|
||||
var: VariantId,
|
||||
) -> Arc<ArenaMap<LocalFieldId, EarlyBinder<'db, Ty<'db>>>>;
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::callable_item_signature_query)]
|
||||
#[salsa::invoke(crate::lower::callable_item_signature_query)]
|
||||
fn callable_item_signature<'db>(
|
||||
&'db self,
|
||||
def: CallableDefId,
|
||||
) -> crate::next_solver::EarlyBinder<'db, crate::next_solver::PolyFnSig<'db>>;
|
||||
) -> EarlyBinder<'db, PolyFnSig<'db>>;
|
||||
|
||||
#[salsa::invoke(crate::lower::return_type_impl_traits)]
|
||||
fn return_type_impl_traits(&self, def: FunctionId) -> Option<Arc<Binders<ImplTraits>>>;
|
||||
fn return_type_impl_traits<'db>(
|
||||
&'db self,
|
||||
def: FunctionId,
|
||||
) -> Option<Arc<EarlyBinder<'db, ImplTraits<'db>>>>;
|
||||
|
||||
#[salsa::invoke(crate::lower::type_alias_impl_traits)]
|
||||
fn type_alias_impl_traits(&self, def: TypeAliasId) -> Option<Arc<Binders<ImplTraits>>>;
|
||||
fn type_alias_impl_traits<'db>(
|
||||
&'db self,
|
||||
def: TypeAliasId,
|
||||
) -> Option<Arc<EarlyBinder<'db, ImplTraits<'db>>>>;
|
||||
|
||||
#[salsa::invoke(crate::lower::generic_predicates_for_param_query)]
|
||||
#[salsa::cycle(cycle_result = crate::lower::generic_predicates_for_param_cycle_result)]
|
||||
fn generic_predicates_for_param(
|
||||
&self,
|
||||
def: GenericDefId,
|
||||
param_id: TypeOrConstParamId,
|
||||
assoc_name: Option<Name>,
|
||||
) -> GenericPredicates;
|
||||
|
||||
#[salsa::invoke(crate::lower::generic_predicates_query)]
|
||||
fn generic_predicates(&self, def: GenericDefId) -> GenericPredicates;
|
||||
|
||||
#[salsa::invoke(
|
||||
crate::lower_nextsolver::generic_predicates_without_parent_with_diagnostics_query
|
||||
)]
|
||||
#[salsa::invoke(crate::lower::generic_predicates_without_parent_with_diagnostics_query)]
|
||||
fn generic_predicates_without_parent_with_diagnostics<'db>(
|
||||
&'db self,
|
||||
def: GenericDefId,
|
||||
) -> (crate::lower_nextsolver::GenericPredicates<'db>, Diagnostics);
|
||||
) -> (GenericPredicates<'db>, Diagnostics);
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::generic_predicates_without_parent_query)]
|
||||
#[salsa::invoke(crate::lower::generic_predicates_without_parent_query)]
|
||||
#[salsa::transparent]
|
||||
fn generic_predicates_without_parent<'db>(
|
||||
&'db self,
|
||||
def: GenericDefId,
|
||||
) -> crate::lower_nextsolver::GenericPredicates<'db>;
|
||||
) -> GenericPredicates<'db>;
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::trait_environment_for_body_query)]
|
||||
#[salsa::invoke(crate::lower::generic_predicates_for_param_query)]
|
||||
#[salsa::cycle(cycle_result = crate::lower::generic_predicates_for_param_cycle_result)]
|
||||
fn generic_predicates_for_param<'db>(
|
||||
&'db self,
|
||||
def: GenericDefId,
|
||||
param_id: TypeOrConstParamId,
|
||||
assoc_name: Option<Name>,
|
||||
) -> GenericPredicates<'db>;
|
||||
|
||||
#[salsa::invoke(crate::lower::generic_predicates_query)]
|
||||
fn generic_predicates<'db>(&'db self, def: GenericDefId) -> GenericPredicates<'db>;
|
||||
|
||||
#[salsa::invoke(crate::lower::trait_environment_for_body_query)]
|
||||
#[salsa::transparent]
|
||||
fn trait_environment_for_body<'db>(&'db self, def: DefWithBodyId)
|
||||
-> Arc<TraitEnvironment<'db>>;
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::trait_environment_query)]
|
||||
#[salsa::invoke(crate::lower::trait_environment_query)]
|
||||
fn trait_environment<'db>(&'db self, def: GenericDefId) -> Arc<TraitEnvironment<'db>>;
|
||||
|
||||
#[salsa::invoke(crate::lower::generic_defaults_with_diagnostics_query)]
|
||||
#[salsa::cycle(cycle_result = crate::lower::generic_defaults_with_diagnostics_cycle_result)]
|
||||
fn generic_defaults_with_diagnostics(
|
||||
&self,
|
||||
fn generic_defaults_with_diagnostics<'db>(
|
||||
&'db self,
|
||||
def: GenericDefId,
|
||||
) -> (GenericDefaults, Diagnostics);
|
||||
) -> (GenericDefaults<'db>, Diagnostics);
|
||||
|
||||
/// This returns an empty list if no parameter has default.
|
||||
///
|
||||
/// The binders of the returned defaults are only up to (not including) this parameter.
|
||||
#[salsa::invoke(crate::lower::generic_defaults_query)]
|
||||
#[salsa::transparent]
|
||||
fn generic_defaults(&self, def: GenericDefId) -> GenericDefaults;
|
||||
fn generic_defaults<'db>(&'db self, def: GenericDefId) -> GenericDefaults<'db>;
|
||||
|
||||
#[salsa::invoke(InherentImpls::inherent_impls_in_crate_query)]
|
||||
fn inherent_impls_in_crate(&self, krate: Crate) -> Arc<InherentImpls>;
|
||||
|
|
@ -297,7 +275,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
|||
#[salsa::invoke(TraitImpls::trait_impls_in_deps_query)]
|
||||
fn trait_impls_in_deps(&self, krate: Crate) -> Arc<[Arc<TraitImpls>]>;
|
||||
|
||||
// Interned IDs for Chalk integration
|
||||
// Interned IDs for solver integration
|
||||
#[salsa::interned]
|
||||
fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId;
|
||||
|
||||
|
|
@ -313,66 +291,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
|
|||
// cycle_initial = crate::variance::variances_of_cycle_initial,
|
||||
cycle_result = crate::variance::variances_of_cycle_initial,
|
||||
)]
|
||||
fn variances_of(&self, def: GenericDefId) -> crate::next_solver::VariancesOf<'_>;
|
||||
|
||||
// next trait solver
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::const_param_ty_query)]
|
||||
#[salsa::transparent]
|
||||
fn const_param_ty_ns<'db>(&'db self, def: ConstParamId) -> crate::next_solver::Ty<'db>;
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::field_types_query)]
|
||||
#[salsa::transparent]
|
||||
fn field_types_ns<'db>(
|
||||
&'db self,
|
||||
var: VariantId,
|
||||
) -> Arc<
|
||||
ArenaMap<LocalFieldId, crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>>,
|
||||
>;
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::return_type_impl_traits)]
|
||||
fn return_type_impl_traits_ns<'db>(
|
||||
&'db self,
|
||||
def: FunctionId,
|
||||
) -> Option<Arc<crate::next_solver::EarlyBinder<'db, crate::lower_nextsolver::ImplTraits<'db>>>>;
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::type_alias_impl_traits)]
|
||||
fn type_alias_impl_traits_ns<'db>(
|
||||
&'db self,
|
||||
def: TypeAliasId,
|
||||
) -> Option<Arc<crate::next_solver::EarlyBinder<'db, crate::lower_nextsolver::ImplTraits<'db>>>>;
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::generic_predicates_for_param_query)]
|
||||
#[salsa::cycle(cycle_result = crate::lower_nextsolver::generic_predicates_for_param_cycle_result)]
|
||||
fn generic_predicates_for_param_ns<'db>(
|
||||
&'db self,
|
||||
def: GenericDefId,
|
||||
param_id: TypeOrConstParamId,
|
||||
assoc_name: Option<Name>,
|
||||
) -> crate::lower_nextsolver::GenericPredicates<'db>;
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::generic_predicates_query)]
|
||||
fn generic_predicates_ns<'db>(
|
||||
&'db self,
|
||||
def: GenericDefId,
|
||||
) -> crate::lower_nextsolver::GenericPredicates<'db>;
|
||||
|
||||
#[salsa::invoke(crate::lower_nextsolver::generic_defaults_with_diagnostics_query)]
|
||||
#[salsa::cycle(cycle_result = crate::lower_nextsolver::generic_defaults_with_diagnostics_cycle_result)]
|
||||
fn generic_defaults_ns_with_diagnostics<'db>(
|
||||
&'db self,
|
||||
def: GenericDefId,
|
||||
) -> (crate::lower_nextsolver::GenericDefaults<'db>, Diagnostics);
|
||||
|
||||
/// This returns an empty list if no parameter has default.
|
||||
///
|
||||
/// The binders of the returned defaults are only up to (not including) this parameter.
|
||||
#[salsa::invoke(crate::lower_nextsolver::generic_defaults_query)]
|
||||
#[salsa::transparent]
|
||||
fn generic_defaults_ns<'db>(
|
||||
&'db self,
|
||||
def: GenericDefId,
|
||||
) -> crate::lower_nextsolver::GenericDefaults<'db>;
|
||||
fn variances_of(&self, def: GenericDefId) -> VariancesOf<'_>;
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ impl<'a, 'db> MatchCheckCtx<'a, 'db> {
|
|||
) -> impl Iterator<Item = (LocalFieldId, Ty<'db>)> {
|
||||
let (_, substs) = ty.as_adt().unwrap();
|
||||
|
||||
let field_tys = self.db.field_types_ns(variant);
|
||||
let field_tys = self.db.field_types(variant);
|
||||
let fields_len = variant.fields(self.db).fields().len() as u32;
|
||||
|
||||
(0..fields_len).map(|idx| LocalFieldId::from_raw(idx.into())).map(move |fid| {
|
||||
|
|
|
|||
|
|
@ -626,7 +626,7 @@ fn write_projection<'db>(
|
|||
// FIXME: We shouldn't use `param.id`, it should be removed. We should know the
|
||||
// `GenericDefId` from the formatted type (store it inside the `HirFormatter`).
|
||||
let bounds =
|
||||
f.db.generic_predicates_ns(param.id.parent())
|
||||
f.db.generic_predicates(param.id.parent())
|
||||
.instantiate_identity()
|
||||
.into_iter()
|
||||
.flatten()
|
||||
|
|
@ -902,7 +902,7 @@ fn render_const_scalar_inner<'db>(
|
|||
hir_def::AdtId::StructId(s) => {
|
||||
let data = f.db.struct_signature(s);
|
||||
write!(f, "{}", data.name.display(f.db, f.edition()))?;
|
||||
let field_types = f.db.field_types_ns(s.into());
|
||||
let field_types = f.db.field_types(s.into());
|
||||
render_variant_after_name(
|
||||
s.fields(f.db),
|
||||
f,
|
||||
|
|
@ -934,7 +934,7 @@ fn render_const_scalar_inner<'db>(
|
|||
.1
|
||||
.display(f.db, f.edition())
|
||||
)?;
|
||||
let field_types = f.db.field_types_ns(var_id.into());
|
||||
let field_types = f.db.field_types(var_id.into());
|
||||
render_variant_after_name(
|
||||
var_id.fields(f.db),
|
||||
f,
|
||||
|
|
@ -1121,7 +1121,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
|
|||
let impl_trait_id = db.lookup_intern_impl_trait_id(opaque_ty_id);
|
||||
if let ImplTraitId::ReturnTypeImplTrait(func, idx) = impl_trait_id {
|
||||
let datas = db
|
||||
.return_type_impl_traits_ns(func)
|
||||
.return_type_impl_traits(func)
|
||||
.expect("impl trait id without data");
|
||||
let data = (*datas).as_ref().map_bound(|rpit| {
|
||||
&rpit.impl_traits[idx.to_nextsolver(interner)].predicates
|
||||
|
|
@ -1353,9 +1353,8 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
|
|||
let impl_trait_id = db.lookup_intern_impl_trait_id(opaque_ty_id);
|
||||
match impl_trait_id {
|
||||
ImplTraitId::ReturnTypeImplTrait(func, idx) => {
|
||||
let datas = db
|
||||
.return_type_impl_traits_ns(func)
|
||||
.expect("impl trait id without data");
|
||||
let datas =
|
||||
db.return_type_impl_traits(func).expect("impl trait id without data");
|
||||
let data = (*datas).as_ref().map_bound(|rpit| {
|
||||
&rpit.impl_traits[idx.to_nextsolver(interner)].predicates
|
||||
});
|
||||
|
|
@ -1373,9 +1372,8 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
|
|||
// FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
|
||||
}
|
||||
ImplTraitId::TypeAliasImplTrait(alias, idx) => {
|
||||
let datas = db
|
||||
.type_alias_impl_traits_ns(alias)
|
||||
.expect("impl trait id without data");
|
||||
let datas =
|
||||
db.type_alias_impl_traits(alias).expect("impl trait id without data");
|
||||
let data = (*datas).as_ref().map_bound(|rpit| {
|
||||
&rpit.impl_traits[idx.to_nextsolver(interner)].predicates
|
||||
});
|
||||
|
|
@ -1501,7 +1499,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
|
|||
}
|
||||
TypeParamProvenance::ArgumentImplTrait => {
|
||||
let bounds = db
|
||||
.generic_predicates_ns(param.id.parent())
|
||||
.generic_predicates(param.id.parent())
|
||||
.instantiate_identity()
|
||||
.into_iter()
|
||||
.flatten()
|
||||
|
|
@ -1621,7 +1619,7 @@ fn generic_args_sans_defaults<'ga, 'db>(
|
|||
parameters: &'ga [GenericArg<'db>],
|
||||
) -> &'ga [GenericArg<'db>] {
|
||||
if f.display_kind.is_source_code() || f.omit_verbose_types() {
|
||||
match generic_def.map(|generic_def_id| f.db.generic_defaults_ns(generic_def_id)) {
|
||||
match generic_def.map(|generic_def_id| f.db.generic_defaults(generic_def_id)) {
|
||||
None => parameters,
|
||||
Some(default_parameters) => {
|
||||
let should_show = |arg: GenericArg<'db>, i: usize| match default_parameters.get(i) {
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ fn has_drop_glue_impl<'db>(
|
|||
{
|
||||
return DropGlue::None;
|
||||
}
|
||||
db.field_types_ns(id.into())
|
||||
db.field_types(id.into())
|
||||
.iter()
|
||||
.map(|(_, field_ty)| {
|
||||
has_drop_glue_impl(
|
||||
|
|
@ -105,7 +105,7 @@ fn has_drop_glue_impl<'db>(
|
|||
.variants
|
||||
.iter()
|
||||
.map(|&(variant, _, _)| {
|
||||
db.field_types_ns(variant.into())
|
||||
db.field_types(variant.into())
|
||||
.iter()
|
||||
.map(|(_, field_ty)| {
|
||||
has_drop_glue_impl(
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ use smallvec::SmallVec;
|
|||
use crate::{
|
||||
ImplTraitId,
|
||||
db::{HirDatabase, InternedOpaqueTyId},
|
||||
lower_nextsolver::associated_ty_item_bounds,
|
||||
lower::associated_ty_item_bounds,
|
||||
next_solver::{
|
||||
Clause, Clauses, DbInterner, GenericArgs, ParamEnv, SolverDefId, TraitPredicate, TraitRef,
|
||||
TypingMode, infer::DbInternerInferExt, mk_param,
|
||||
Binder, Clause, Clauses, DbInterner, EarlyBinder, GenericArgs, Goal, ParamEnv, ParamTy,
|
||||
SolverDefId, TraitPredicate, TraitRef, Ty, TypingMode, infer::DbInternerInferExt, mk_param,
|
||||
},
|
||||
traits::next_trait_solve_in_ctxt,
|
||||
};
|
||||
|
|
@ -136,7 +136,7 @@ pub fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> b
|
|||
};
|
||||
|
||||
let interner = DbInterner::new_with(db, Some(krate), None);
|
||||
let predicates = db.generic_predicates_ns(def);
|
||||
let predicates = db.generic_predicates(def);
|
||||
// FIXME: We should use `explicit_predicates_of` here, which hasn't been implemented to
|
||||
// rust-analyzer yet
|
||||
// https://github.com/rust-lang/rust/blob/ddaf12390d3ffb7d5ba74491a48f3cd528e5d777/compiler/rustc_hir_analysis/src/collect/predicates_of.rs#L490
|
||||
|
|
@ -162,7 +162,7 @@ pub fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> b
|
|||
// but we don't have good way to render such locations.
|
||||
// So, just return single boolean value for existence of such `Self` reference
|
||||
fn predicates_reference_self(db: &dyn HirDatabase, trait_: TraitId) -> bool {
|
||||
db.generic_predicates_ns(trait_.into())
|
||||
db.generic_predicates(trait_.into())
|
||||
.iter()
|
||||
.any(|pred| predicate_references_self(db, trait_, pred, AllowSelfProjection::No))
|
||||
}
|
||||
|
|
@ -378,7 +378,7 @@ where
|
|||
}) = pred
|
||||
&& let trait_data = db.trait_signature(pred_trait_ref.def_id.0)
|
||||
&& trait_data.flags.contains(TraitFlags::AUTO)
|
||||
&& let rustc_type_ir::TyKind::Param(crate::next_solver::ParamTy { index: 0, .. }) =
|
||||
&& let rustc_type_ir::TyKind::Param(ParamTy { index: 0, .. }) =
|
||||
pred_trait_ref.self_ty().kind()
|
||||
{
|
||||
continue;
|
||||
|
|
@ -397,10 +397,7 @@ fn receiver_is_dispatchable<'db>(
|
|||
db: &dyn HirDatabase,
|
||||
trait_: TraitId,
|
||||
func: FunctionId,
|
||||
sig: &crate::next_solver::EarlyBinder<
|
||||
'db,
|
||||
crate::next_solver::Binder<'db, rustc_type_ir::FnSig<DbInterner<'db>>>,
|
||||
>,
|
||||
sig: &EarlyBinder<'db, Binder<'db, rustc_type_ir::FnSig<DbInterner<'db>>>>,
|
||||
) -> bool {
|
||||
let sig = sig.instantiate_identity();
|
||||
|
||||
|
|
@ -409,10 +406,8 @@ fn receiver_is_dispatchable<'db>(
|
|||
parent: trait_.into(),
|
||||
local_id: LocalTypeOrConstParamId::from_raw(la_arena::RawIdx::from_u32(0)),
|
||||
});
|
||||
let self_param_ty = crate::next_solver::Ty::new(
|
||||
interner,
|
||||
rustc_type_ir::TyKind::Param(crate::next_solver::ParamTy { index: 0, id: self_param_id }),
|
||||
);
|
||||
let self_param_ty =
|
||||
Ty::new(interner, rustc_type_ir::TyKind::Param(ParamTy { index: 0, id: self_param_id }));
|
||||
|
||||
// `self: Self` can't be dispatched on, but this is already considered dyn-compatible
|
||||
// See rustc's comment on https://github.com/rust-lang/rust/blob/3f121b9461cce02a703a0e7e450568849dfaa074/compiler/rustc_trait_selection/src/traits/object_safety.rs#L433-L437
|
||||
|
|
@ -440,12 +435,12 @@ fn receiver_is_dispatchable<'db>(
|
|||
|
||||
// Type `U`
|
||||
// FIXME: That seems problematic to fake a generic param like that?
|
||||
let unsized_self_ty = crate::next_solver::Ty::new_param(interner, self_param_id, u32::MAX);
|
||||
let unsized_self_ty = Ty::new_param(interner, self_param_id, u32::MAX);
|
||||
// `Receiver[Self => U]`
|
||||
let unsized_receiver_ty = receiver_for_self_ty(interner, func, receiver_ty, unsized_self_ty);
|
||||
|
||||
let param_env = {
|
||||
let generic_predicates = &*db.generic_predicates_ns(func.into());
|
||||
let generic_predicates = &*db.generic_predicates(func.into());
|
||||
|
||||
// Self: Unsize<U>
|
||||
let unsize_predicate =
|
||||
|
|
@ -475,7 +470,7 @@ fn receiver_is_dispatchable<'db>(
|
|||
// Receiver: DispatchFromDyn<Receiver[Self => U]>
|
||||
let predicate =
|
||||
TraitRef::new(interner, dispatch_from_dyn_did.into(), [receiver_ty, unsized_receiver_ty]);
|
||||
let goal = crate::next_solver::Goal::new(interner, param_env, predicate);
|
||||
let goal = Goal::new(interner, param_env, predicate);
|
||||
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
// the receiver is dispatchable iff the obligation holds
|
||||
|
|
@ -486,26 +481,19 @@ fn receiver_is_dispatchable<'db>(
|
|||
fn receiver_for_self_ty<'db>(
|
||||
interner: DbInterner<'db>,
|
||||
func: FunctionId,
|
||||
receiver_ty: crate::next_solver::Ty<'db>,
|
||||
self_ty: crate::next_solver::Ty<'db>,
|
||||
) -> crate::next_solver::Ty<'db> {
|
||||
let args = crate::next_solver::GenericArgs::for_item(
|
||||
interner,
|
||||
SolverDefId::FunctionId(func),
|
||||
|index, kind, _| {
|
||||
if index == 0 { self_ty.into() } else { mk_param(interner, index, kind) }
|
||||
},
|
||||
);
|
||||
receiver_ty: Ty<'db>,
|
||||
self_ty: Ty<'db>,
|
||||
) -> Ty<'db> {
|
||||
let args = GenericArgs::for_item(interner, SolverDefId::FunctionId(func), |index, kind, _| {
|
||||
if index == 0 { self_ty.into() } else { mk_param(interner, index, kind) }
|
||||
});
|
||||
|
||||
crate::next_solver::EarlyBinder::bind(receiver_ty).instantiate(interner, args)
|
||||
EarlyBinder::bind(receiver_ty).instantiate(interner, args)
|
||||
}
|
||||
|
||||
fn contains_illegal_impl_trait_in_trait<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
sig: &crate::next_solver::EarlyBinder<
|
||||
'db,
|
||||
crate::next_solver::Binder<'db, rustc_type_ir::FnSig<DbInterner<'db>>>,
|
||||
>,
|
||||
sig: &EarlyBinder<'db, Binder<'db, rustc_type_ir::FnSig<DbInterner<'db>>>>,
|
||||
) -> Option<MethodViolationCode> {
|
||||
struct OpaqueTypeCollector(FxHashSet<InternedOpaqueTyId>);
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
//! where parent follows the same scheme.
|
||||
use std::ops;
|
||||
|
||||
use chalk_ir::{BoundVar, DebruijnIndex, cast::Cast as _};
|
||||
use hir_def::{
|
||||
ConstParamId, GenericDefId, GenericParamId, ItemContainerId, LifetimeParamId, Lookup,
|
||||
TypeOrConstParamId, TypeParamId,
|
||||
|
|
@ -23,8 +22,6 @@ use hir_def::{
|
|||
use itertools::chain;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{Interner, Substitution, db::HirDatabase, lt_to_placeholder_idx, to_placeholder_idx};
|
||||
|
||||
pub fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics {
|
||||
let parent_generics = parent_generic_def(db, def).map(|def| Box::new(generics(db, def)));
|
||||
let (params, store) = db.generic_params_and_store(def);
|
||||
|
|
@ -230,50 +227,6 @@ impl Generics {
|
|||
pub(crate) fn parent_generics(&self) -> Option<&Generics> {
|
||||
self.parent_generics.as_deref()
|
||||
}
|
||||
|
||||
pub(crate) fn parent_or_self(&self) -> &Generics {
|
||||
self.parent_generics.as_deref().unwrap_or(self)
|
||||
}
|
||||
|
||||
/// Returns a Substitution that replaces each parameter by a bound variable.
|
||||
pub(crate) fn bound_vars_subst(
|
||||
&self,
|
||||
db: &dyn HirDatabase,
|
||||
debruijn: DebruijnIndex,
|
||||
) -> Substitution {
|
||||
Substitution::from_iter(
|
||||
Interner,
|
||||
self.iter_id().enumerate().map(|(idx, id)| match id {
|
||||
GenericParamId::ConstParamId(id) => BoundVar::new(debruijn, idx)
|
||||
.to_const(Interner, db.const_param_ty(id))
|
||||
.cast(Interner),
|
||||
GenericParamId::TypeParamId(_) => {
|
||||
BoundVar::new(debruijn, idx).to_ty(Interner).cast(Interner)
|
||||
}
|
||||
GenericParamId::LifetimeParamId(_) => {
|
||||
BoundVar::new(debruijn, idx).to_lifetime(Interner).cast(Interner)
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns a Substitution that replaces each parameter by itself (i.e. `Ty::Param`).
|
||||
pub(crate) fn placeholder_subst(&self, db: &dyn HirDatabase) -> Substitution {
|
||||
Substitution::from_iter(
|
||||
Interner,
|
||||
self.iter_id().enumerate().map(|(index, id)| match id {
|
||||
GenericParamId::TypeParamId(id) => {
|
||||
to_placeholder_idx(db, id.into(), index as u32).to_ty(Interner).cast(Interner)
|
||||
}
|
||||
GenericParamId::ConstParamId(id) => to_placeholder_idx(db, id.into(), index as u32)
|
||||
.to_const(Interner, db.const_param_ty(id))
|
||||
.cast(Interner),
|
||||
GenericParamId::LifetimeParamId(id) => {
|
||||
lt_to_placeholder_idx(db, id, index as u32).to_lifetime(Interner).cast(Interner)
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn trait_self_param_idx(db: &dyn DefDatabase, def: GenericDefId) -> Option<usize> {
|
||||
|
|
|
|||
|
|
@ -63,8 +63,9 @@ use crate::{
|
|||
expr::ExprIsRead,
|
||||
unify::InferenceTable,
|
||||
},
|
||||
lower::diagnostics::TyLoweringDiagnostic,
|
||||
lower_nextsolver::{ImplTraitIdx, ImplTraitLoweringMode, LifetimeElisionKind},
|
||||
lower::{
|
||||
ImplTraitIdx, ImplTraitLoweringMode, LifetimeElisionKind, diagnostics::TyLoweringDiagnostic,
|
||||
},
|
||||
mir::MirSpan,
|
||||
next_solver::{
|
||||
AliasTy, Const, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, Region, Ty, TyKind,
|
||||
|
|
@ -1159,7 +1160,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
|
|||
},
|
||||
);
|
||||
let return_ty = self.insert_type_vars(return_ty);
|
||||
if let Some(rpits) = self.db.return_type_impl_traits_ns(func) {
|
||||
if let Some(rpits) = self.db.return_type_impl_traits(func) {
|
||||
let mut mode = ImplTraitReplacingMode::ReturnPosition(FxHashSet::default());
|
||||
let result = self.insert_inference_vars_for_impl_trait(return_ty, &mut mode);
|
||||
if let ImplTraitReplacingMode::ReturnPosition(taits) = mode {
|
||||
|
|
@ -1234,7 +1235,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
|
|||
}
|
||||
return ty;
|
||||
}
|
||||
(self.db.return_type_impl_traits_ns(def), idx)
|
||||
(self.db.return_type_impl_traits(def), idx)
|
||||
}
|
||||
ImplTraitId::TypeAliasImplTrait(def, idx) => {
|
||||
if let ImplTraitReplacingMode::ReturnPosition(taits) = mode {
|
||||
|
|
@ -1243,7 +1244,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
|
|||
taits.insert(ty);
|
||||
return ty;
|
||||
}
|
||||
(self.db.type_alias_impl_traits_ns(def), idx)
|
||||
(self.db.type_alias_impl_traits(def), idx)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
|
@ -1604,8 +1605,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
|
|||
match ty.kind() {
|
||||
TyKind::Adt(adt_def, substs) => match adt_def.def_id().0 {
|
||||
AdtId::StructId(struct_id) => {
|
||||
match self.db.field_types_ns(struct_id.into()).values().next_back().copied()
|
||||
{
|
||||
match self.db.field_types(struct_id.into()).values().next_back().copied() {
|
||||
Some(field) => {
|
||||
ty = field.instantiate(self.interner(), substs);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -394,7 +394,7 @@ fn pointer_kind<'db>(
|
|||
let struct_data = id.fields(ctx.db);
|
||||
if let Some((last_field, _)) = struct_data.fields().iter().last() {
|
||||
let last_field_ty =
|
||||
ctx.db.field_types_ns(id.into())[last_field].instantiate(ctx.interner(), subst);
|
||||
ctx.db.field_types(id.into())[last_field].instantiate(ctx.interner(), subst);
|
||||
pointer_kind(last_field_ty, ctx)
|
||||
} else {
|
||||
Ok(Some(PointerKind::Thin))
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ use la_arena::{Idx, RawIdx};
|
|||
use crate::{
|
||||
InferenceDiagnostic, InferenceTyDiagnosticSource, TyLoweringDiagnostic,
|
||||
db::HirDatabase,
|
||||
lower_nextsolver::path::{PathDiagnosticCallback, PathLoweringContext},
|
||||
lower_nextsolver::{LifetimeElisionKind, TyLoweringContext},
|
||||
lower::path::{PathDiagnosticCallback, PathLoweringContext},
|
||||
lower::{LifetimeElisionKind, TyLoweringContext},
|
||||
};
|
||||
|
||||
// Unfortunately, this struct needs to use interior mutability (but we encapsulate it)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ use crate::{
|
|||
pat::contains_explicit_ref_binding,
|
||||
},
|
||||
lang_items::lang_items_for_bin_op,
|
||||
lower_nextsolver::{
|
||||
lower::{
|
||||
LifetimeElisionKind, lower_mutability,
|
||||
path::{GenericArgsLowerer, TypeLikeConst, substs_from_args_and_bindings},
|
||||
},
|
||||
|
|
@ -564,7 +564,7 @@ impl<'db> InferenceContext<'_, 'db> {
|
|||
match def_id {
|
||||
_ if fields.is_empty() => {}
|
||||
Some(def) => {
|
||||
let field_types = self.db.field_types_ns(def);
|
||||
let field_types = self.db.field_types(def);
|
||||
let variant_data = def.fields(self.db);
|
||||
let visibilities = self.db.field_visibilities(def);
|
||||
for field in fields.iter() {
|
||||
|
|
@ -1622,7 +1622,7 @@ impl<'db> InferenceContext<'_, 'db> {
|
|||
}
|
||||
return None;
|
||||
}
|
||||
let ty = self.db.field_types_ns(field_id.parent)[field_id.local_id]
|
||||
let ty = self.db.field_types(field_id.parent)[field_id.local_id]
|
||||
.instantiate(interner, parameters);
|
||||
Some((Either::Left(field_id), ty))
|
||||
});
|
||||
|
|
@ -1637,7 +1637,7 @@ impl<'db> InferenceContext<'_, 'db> {
|
|||
None => {
|
||||
let (field_id, subst) = private_field?;
|
||||
let adjustments = autoderef.adjust_steps();
|
||||
let ty = self.db.field_types_ns(field_id.parent)[field_id.local_id]
|
||||
let ty = self.db.field_types(field_id.parent)[field_id.local_id]
|
||||
.instantiate(self.interner(), subst);
|
||||
let ty = self.process_remote_user_written_ty(ty);
|
||||
|
||||
|
|
@ -2320,7 +2320,7 @@ impl<'db> InferenceContext<'_, 'db> {
|
|||
let callable_ty = self.table.try_structurally_resolve_type(callable_ty);
|
||||
if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind() {
|
||||
let generic_predicates =
|
||||
self.db.generic_predicates_ns(GenericDefId::from_callable(self.db, fn_def.0));
|
||||
self.db.generic_predicates(GenericDefId::from_callable(self.db, fn_def.0));
|
||||
if let Some(predicates) = generic_predicates.instantiate(self.interner(), parameters) {
|
||||
let interner = self.interner();
|
||||
let param_env = self.table.trait_env.env;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ use crate::next_solver::{GenericArgs, TraitRef};
|
|||
use crate::{
|
||||
Adjust, Adjustment, AutoBorrow, OverloadedDeref,
|
||||
infer::{Expectation, InferenceContext, expr::ExprIsRead},
|
||||
lower_nextsolver::lower_mutability,
|
||||
lower::lower_mutability,
|
||||
next_solver::TyKind,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use crate::{
|
|||
AllowTwoPhase, BindingMode, Expectation, InferenceContext, TypeMismatch,
|
||||
coerce::CoerceNever, expr::ExprIsRead,
|
||||
},
|
||||
lower_nextsolver::lower_mutability,
|
||||
lower::lower_mutability,
|
||||
next_solver::{GenericArgs, Ty, TyKind},
|
||||
};
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ impl<'db> InferenceContext<'_, 'db> {
|
|||
match def {
|
||||
_ if subs.is_empty() => {}
|
||||
Some(def) => {
|
||||
let field_types = self.db.field_types_ns(def);
|
||||
let field_types = self.db.field_types(def);
|
||||
let variant_data = def.fields(self.db);
|
||||
let visibilities = self.db.field_visibilities(def);
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ impl<'db> InferenceContext<'_, 'db> {
|
|||
match def {
|
||||
_ if subs.len() == 0 => {}
|
||||
Some(def) => {
|
||||
let field_types = self.db.field_types_ns(def);
|
||||
let field_types = self.db.field_types(def);
|
||||
let variant_data = def.fields(self.db);
|
||||
let visibilities = self.db.field_visibilities(def);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use crate::{
|
|||
InferenceDiagnostic, ValueTyDefId,
|
||||
generics::generics,
|
||||
infer::diagnostics::InferenceTyLoweringContext as TyLoweringContext,
|
||||
lower_nextsolver::LifetimeElisionKind,
|
||||
lower::LifetimeElisionKind,
|
||||
method_resolution::{self, VisibleFromModule},
|
||||
next_solver::{
|
||||
GenericArg, GenericArgs, TraitRef, Ty,
|
||||
|
|
@ -221,7 +221,7 @@ impl<'db> InferenceContext<'_, 'db> {
|
|||
def: GenericDefId,
|
||||
subst: GenericArgs<'db>,
|
||||
) {
|
||||
let predicates = self.db.generic_predicates_ns(def);
|
||||
let predicates = self.db.generic_predicates(def);
|
||||
let interner = self.interner();
|
||||
let param_env = self.table.trait_env.env;
|
||||
if let Some(predicates) = predicates.instantiate(self.interner(), subst) {
|
||||
|
|
|
|||
|
|
@ -800,7 +800,7 @@ impl<'db> InferenceTable<'db> {
|
|||
while let Some((AdtId::StructId(id), subst)) = ty.as_adt() {
|
||||
let struct_data = id.fields(self.db);
|
||||
if let Some((last_field, _)) = struct_data.fields().iter().next_back() {
|
||||
let last_field_ty = self.db.field_types_ns(id.into())[last_field]
|
||||
let last_field_ty = self.db.field_types(id.into())[last_field]
|
||||
.instantiate(self.interner(), subst);
|
||||
if structs.contains(&ty) {
|
||||
// A struct recursively contains itself as a tail field somewhere.
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ impl<'a, 'db> UninhabitedFrom<'a, 'db> {
|
|||
}
|
||||
|
||||
let is_enum = matches!(variant, VariantId::EnumVariantId(..));
|
||||
let field_tys = self.db().field_types_ns(variant);
|
||||
let field_tys = self.db().field_types(variant);
|
||||
let field_vis = if is_enum { None } else { Some(self.db().field_visibilities(variant)) };
|
||||
|
||||
for (fid, _) in fields.iter() {
|
||||
|
|
|
|||
|
|
@ -1,403 +0,0 @@
|
|||
//! Implementation of the Chalk `Interner` trait, which allows customizing the
|
||||
//! representation of the various objects Chalk deals with (types, goals etc.).
|
||||
|
||||
use crate::{
|
||||
AliasTy, CanonicalVarKind, CanonicalVarKinds, ClosureId, Const, ConstData, ConstScalar, FnAbi,
|
||||
FnDefId, GenericArg, GenericArgData, Goal, GoalData, InEnvironment, Lifetime, LifetimeData,
|
||||
OpaqueTy, OpaqueTyId, ProgramClause, ProjectionTy, QuantifiedWhereClause,
|
||||
QuantifiedWhereClauses, Substitution, Ty, TyKind, VariableKind, chalk_db, tls,
|
||||
};
|
||||
use chalk_ir::{ProgramClauseImplication, SeparatorTraitRef, Variance};
|
||||
use hir_def::TypeAliasId;
|
||||
use intern::{Interned, impl_internable};
|
||||
use smallvec::SmallVec;
|
||||
use std::fmt;
|
||||
use triomphe::Arc;
|
||||
|
||||
type TyData = chalk_ir::TyData<Interner>;
|
||||
type VariableKinds = chalk_ir::VariableKinds<Interner>;
|
||||
type Goals = chalk_ir::Goals<Interner>;
|
||||
type ProgramClauseData = chalk_ir::ProgramClauseData<Interner>;
|
||||
type Constraint = chalk_ir::Constraint<Interner>;
|
||||
type Constraints = chalk_ir::Constraints<Interner>;
|
||||
type ProgramClauses = chalk_ir::ProgramClauses<Interner>;
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
|
||||
pub struct Interner;
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Clone)]
|
||||
pub struct InternedWrapper<T>(pub(crate) T);
|
||||
|
||||
impl<T: fmt::Debug> fmt::Debug for InternedWrapper<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Debug::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Clone)]
|
||||
pub struct InternedWrapperNoDebug<T>(pub(crate) T);
|
||||
|
||||
impl<T> std::ops::Deref for InternedWrapper<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl_internable!(
|
||||
InternedWrapper<Vec<VariableKind>>,
|
||||
InternedWrapper<SmallVec<[GenericArg; 2]>>,
|
||||
InternedWrapper<TyData>,
|
||||
InternedWrapper<LifetimeData>,
|
||||
InternedWrapper<ConstData>,
|
||||
InternedWrapper<ConstScalar>,
|
||||
InternedWrapper<Vec<CanonicalVarKind>>,
|
||||
InternedWrapper<Box<[ProgramClause]>>,
|
||||
InternedWrapper<Vec<QuantifiedWhereClause>>,
|
||||
InternedWrapper<SmallVec<[Variance; 16]>>,
|
||||
);
|
||||
|
||||
impl chalk_ir::interner::Interner for Interner {
|
||||
type InternedType = Interned<InternedWrapper<TyData>>;
|
||||
type InternedLifetime = Interned<InternedWrapper<LifetimeData>>;
|
||||
type InternedConst = Interned<InternedWrapper<ConstData>>;
|
||||
type InternedConcreteConst = ConstScalar;
|
||||
type InternedGenericArg = GenericArgData;
|
||||
// We could do the following, but that saves "only" 20mb on self while increasing inference
|
||||
// time by ~2.5%
|
||||
// type InternedGoal = Interned<InternedWrapper<GoalData>>;
|
||||
type InternedGoal = Arc<GoalData>;
|
||||
type InternedGoals = Vec<Goal>;
|
||||
type InternedSubstitution = Interned<InternedWrapper<SmallVec<[GenericArg; 2]>>>;
|
||||
type InternedProgramClauses = Interned<InternedWrapper<Box<[ProgramClause]>>>;
|
||||
type InternedProgramClause = ProgramClauseData;
|
||||
type InternedQuantifiedWhereClauses = Interned<InternedWrapper<Vec<QuantifiedWhereClause>>>;
|
||||
type InternedVariableKinds = Interned<InternedWrapper<Vec<VariableKind>>>;
|
||||
type InternedCanonicalVarKinds = Interned<InternedWrapper<Vec<CanonicalVarKind>>>;
|
||||
type InternedConstraints = Vec<InEnvironment<Constraint>>;
|
||||
type InternedVariances = SmallVec<[Variance; 16]>;
|
||||
type DefId = salsa::Id;
|
||||
type InternedAdtId = hir_def::AdtId;
|
||||
type Identifier = TypeAliasId;
|
||||
type FnAbi = FnAbi;
|
||||
|
||||
fn debug_adt_id(
|
||||
type_kind_id: chalk_db::AdtId,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt)))
|
||||
}
|
||||
|
||||
fn debug_trait_id(
|
||||
type_kind_id: chalk_db::TraitId,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
tls::with_current_program(|prog| Some(prog?.debug_trait_id(type_kind_id, fmt)))
|
||||
}
|
||||
|
||||
fn debug_assoc_type_id(
|
||||
id: chalk_db::AssocTypeId,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt)))
|
||||
}
|
||||
|
||||
fn debug_opaque_ty_id(
|
||||
opaque_ty_id: OpaqueTyId,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
Some(write!(fmt, "OpaqueTy#{:?}", opaque_ty_id.0))
|
||||
}
|
||||
|
||||
fn debug_fn_def_id(fn_def_id: FnDefId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
|
||||
tls::with_current_program(|prog| Some(prog?.debug_fn_def_id(fn_def_id, fmt)))
|
||||
}
|
||||
|
||||
fn debug_closure_id(
|
||||
_fn_def_id: ClosureId,
|
||||
_fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
None
|
||||
}
|
||||
|
||||
fn debug_alias(alias: &AliasTy, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
|
||||
use std::fmt::Debug;
|
||||
match alias {
|
||||
AliasTy::Projection(projection_ty) => Interner::debug_projection_ty(projection_ty, fmt),
|
||||
AliasTy::Opaque(opaque_ty) => Some(opaque_ty.fmt(fmt)),
|
||||
}
|
||||
}
|
||||
|
||||
fn debug_projection_ty(
|
||||
proj: &ProjectionTy,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
tls::with_current_program(|prog| Some(prog?.debug_projection_ty(proj, fmt)))
|
||||
.or_else(|| Some(fmt.write_str("ProjectionTy")))
|
||||
}
|
||||
|
||||
fn debug_opaque_ty(opaque_ty: &OpaqueTy, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
|
||||
Some(write!(fmt, "{:?}", opaque_ty.opaque_ty_id))
|
||||
}
|
||||
|
||||
fn debug_ty(ty: &Ty, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
|
||||
Some(write!(fmt, "{:?}", ty.data(Interner)))
|
||||
}
|
||||
|
||||
fn debug_lifetime(lifetime: &Lifetime, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
|
||||
Some(write!(fmt, "{:?}", lifetime.data(Interner)))
|
||||
}
|
||||
|
||||
fn debug_const(constant: &Const, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
|
||||
Some(write!(fmt, "{:?}", constant.data(Interner)))
|
||||
}
|
||||
|
||||
fn debug_generic_arg(
|
||||
parameter: &GenericArg,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
Some(write!(fmt, "{:?}", parameter.data(Interner).inner_debug()))
|
||||
}
|
||||
|
||||
fn debug_variable_kinds(
|
||||
variable_kinds: &VariableKinds,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
Some(write!(fmt, "{:?}", variable_kinds.as_slice(Interner)))
|
||||
}
|
||||
|
||||
fn debug_variable_kinds_with_angles(
|
||||
variable_kinds: &VariableKinds,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
Some(write!(fmt, "{:?}", variable_kinds.inner_debug(Interner)))
|
||||
}
|
||||
|
||||
fn debug_canonical_var_kinds(
|
||||
canonical_var_kinds: &CanonicalVarKinds,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
Some(write!(fmt, "{:?}", canonical_var_kinds.as_slice(Interner)))
|
||||
}
|
||||
fn debug_goal(goal: &Goal, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
|
||||
let goal_data = goal.data(Interner);
|
||||
Some(write!(fmt, "{goal_data:?}"))
|
||||
}
|
||||
fn debug_goals(goals: &Goals, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
|
||||
Some(write!(fmt, "{:?}", goals.debug(Interner)))
|
||||
}
|
||||
fn debug_program_clause_implication(
|
||||
pci: &ProgramClauseImplication<Self>,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
Some(write!(fmt, "{:?}", pci.debug(Interner)))
|
||||
}
|
||||
fn debug_program_clause(
|
||||
clause: &ProgramClause,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
Some(write!(fmt, "{:?}", clause.data(Interner)))
|
||||
}
|
||||
fn debug_program_clauses(
|
||||
clauses: &ProgramClauses,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
Some(write!(fmt, "{:?}", clauses.as_slice(Interner)))
|
||||
}
|
||||
fn debug_substitution(
|
||||
substitution: &Substitution,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
Some(write!(fmt, "{:?}", substitution.debug(Interner)))
|
||||
}
|
||||
fn debug_separator_trait_ref(
|
||||
separator_trait_ref: &SeparatorTraitRef<'_, Interner>,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
Some(write!(fmt, "{:?}", separator_trait_ref.debug(Interner)))
|
||||
}
|
||||
|
||||
fn debug_quantified_where_clauses(
|
||||
clauses: &QuantifiedWhereClauses,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
Some(write!(fmt, "{:?}", clauses.as_slice(Interner)))
|
||||
}
|
||||
|
||||
fn debug_constraints(
|
||||
_clauses: &Constraints,
|
||||
_fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Option<fmt::Result> {
|
||||
None
|
||||
}
|
||||
|
||||
fn intern_ty(self, kind: TyKind) -> Self::InternedType {
|
||||
let flags = kind.compute_flags(self);
|
||||
Interned::new(InternedWrapper(TyData { kind, flags }))
|
||||
}
|
||||
|
||||
fn ty_data(self, ty: &Self::InternedType) -> &TyData {
|
||||
&ty.0
|
||||
}
|
||||
|
||||
fn intern_lifetime(self, lifetime: LifetimeData) -> Self::InternedLifetime {
|
||||
Interned::new(InternedWrapper(lifetime))
|
||||
}
|
||||
|
||||
fn lifetime_data(self, lifetime: &Self::InternedLifetime) -> &LifetimeData {
|
||||
&lifetime.0
|
||||
}
|
||||
|
||||
fn intern_const(self, constant: ConstData) -> Self::InternedConst {
|
||||
Interned::new(InternedWrapper(constant))
|
||||
}
|
||||
|
||||
fn const_data(self, constant: &Self::InternedConst) -> &ConstData {
|
||||
&constant.0
|
||||
}
|
||||
|
||||
fn const_eq(
|
||||
self,
|
||||
_ty: &Self::InternedType,
|
||||
c1: &Self::InternedConcreteConst,
|
||||
c2: &Self::InternedConcreteConst,
|
||||
) -> bool {
|
||||
!matches!(c1, ConstScalar::Bytes(..)) || !matches!(c2, ConstScalar::Bytes(..)) || (c1 == c2)
|
||||
}
|
||||
|
||||
fn intern_generic_arg(self, parameter: GenericArgData) -> Self::InternedGenericArg {
|
||||
parameter
|
||||
}
|
||||
|
||||
fn generic_arg_data(self, parameter: &Self::InternedGenericArg) -> &GenericArgData {
|
||||
parameter
|
||||
}
|
||||
|
||||
fn intern_goal(self, goal: GoalData) -> Self::InternedGoal {
|
||||
Arc::new(goal)
|
||||
}
|
||||
|
||||
fn goal_data(self, goal: &Self::InternedGoal) -> &GoalData {
|
||||
goal
|
||||
}
|
||||
|
||||
fn intern_goals<E>(
|
||||
self,
|
||||
data: impl IntoIterator<Item = Result<Goal, E>>,
|
||||
) -> Result<Self::InternedGoals, E> {
|
||||
// let hash =
|
||||
// std::hash::BuildHasher::hash_one(&BuildHasherDefault::<FxHasher>::default(), &goal);
|
||||
// Interned::new(InternedWrapper(PreHashedWrapper(goal, hash)))
|
||||
data.into_iter().collect()
|
||||
}
|
||||
|
||||
fn goals_data(self, goals: &Self::InternedGoals) -> &[Goal] {
|
||||
goals
|
||||
}
|
||||
|
||||
fn intern_substitution<E>(
|
||||
self,
|
||||
data: impl IntoIterator<Item = Result<GenericArg, E>>,
|
||||
) -> Result<Self::InternedSubstitution, E> {
|
||||
Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
|
||||
}
|
||||
|
||||
fn substitution_data(self, substitution: &Self::InternedSubstitution) -> &[GenericArg] {
|
||||
&substitution.as_ref().0
|
||||
}
|
||||
|
||||
fn intern_program_clause(self, data: ProgramClauseData) -> Self::InternedProgramClause {
|
||||
data
|
||||
}
|
||||
|
||||
fn program_clause_data(self, clause: &Self::InternedProgramClause) -> &ProgramClauseData {
|
||||
clause
|
||||
}
|
||||
|
||||
fn intern_program_clauses<E>(
|
||||
self,
|
||||
data: impl IntoIterator<Item = Result<ProgramClause, E>>,
|
||||
) -> Result<Self::InternedProgramClauses, E> {
|
||||
Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
|
||||
}
|
||||
|
||||
fn program_clauses_data(self, clauses: &Self::InternedProgramClauses) -> &[ProgramClause] {
|
||||
clauses
|
||||
}
|
||||
|
||||
fn intern_quantified_where_clauses<E>(
|
||||
self,
|
||||
data: impl IntoIterator<Item = Result<QuantifiedWhereClause, E>>,
|
||||
) -> Result<Self::InternedQuantifiedWhereClauses, E> {
|
||||
Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
|
||||
}
|
||||
|
||||
fn quantified_where_clauses_data(
|
||||
self,
|
||||
clauses: &Self::InternedQuantifiedWhereClauses,
|
||||
) -> &[QuantifiedWhereClause] {
|
||||
clauses
|
||||
}
|
||||
|
||||
fn intern_generic_arg_kinds<E>(
|
||||
self,
|
||||
data: impl IntoIterator<Item = Result<VariableKind, E>>,
|
||||
) -> Result<Self::InternedVariableKinds, E> {
|
||||
Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
|
||||
}
|
||||
|
||||
fn variable_kinds_data(self, parameter_kinds: &Self::InternedVariableKinds) -> &[VariableKind] {
|
||||
¶meter_kinds.as_ref().0
|
||||
}
|
||||
|
||||
fn intern_canonical_var_kinds<E>(
|
||||
self,
|
||||
data: impl IntoIterator<Item = Result<CanonicalVarKind, E>>,
|
||||
) -> Result<Self::InternedCanonicalVarKinds, E> {
|
||||
Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
|
||||
}
|
||||
|
||||
fn canonical_var_kinds_data(
|
||||
self,
|
||||
canonical_var_kinds: &Self::InternedCanonicalVarKinds,
|
||||
) -> &[CanonicalVarKind] {
|
||||
canonical_var_kinds
|
||||
}
|
||||
fn intern_constraints<E>(
|
||||
self,
|
||||
data: impl IntoIterator<Item = Result<InEnvironment<Constraint>, E>>,
|
||||
) -> Result<Self::InternedConstraints, E> {
|
||||
data.into_iter().collect()
|
||||
}
|
||||
fn constraints_data(
|
||||
self,
|
||||
constraints: &Self::InternedConstraints,
|
||||
) -> &[InEnvironment<Constraint>] {
|
||||
constraints
|
||||
}
|
||||
|
||||
fn intern_variances<E>(
|
||||
self,
|
||||
data: impl IntoIterator<Item = Result<Variance, E>>,
|
||||
) -> Result<Self::InternedVariances, E> {
|
||||
data.into_iter().collect::<Result<_, _>>()
|
||||
}
|
||||
|
||||
fn variances_data(self, variances: &Self::InternedVariances) -> &[Variance] {
|
||||
variances
|
||||
}
|
||||
}
|
||||
|
||||
impl chalk_ir::interner::HasInterner for Interner {
|
||||
type Interner = Self;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! has_interner {
|
||||
($t:ty) => {
|
||||
impl HasInterner for $t {
|
||||
type Interner = $crate::Interner;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -138,7 +138,7 @@ fn layout_of_simd_ty<'db>(
|
|||
// * #[repr(simd)] struct S([T; 4])
|
||||
//
|
||||
// where T is a primitive scalar (integer/float/pointer).
|
||||
let fields = db.field_types_ns(id.into());
|
||||
let fields = db.field_types(id.into());
|
||||
let mut fields = fields.iter();
|
||||
let Some(TyKind::Array(e_ty, e_len)) = fields
|
||||
.next()
|
||||
|
|
@ -401,7 +401,7 @@ fn field_ty<'a>(
|
|||
fd: LocalFieldId,
|
||||
args: &GenericArgs<'a>,
|
||||
) -> Ty<'a> {
|
||||
db.field_types_ns(def)[fd].instantiate(DbInterner::new_with(db, None, None), args)
|
||||
db.field_types(def)[fd].instantiate(DbInterner::new_with(db, None, None), args)
|
||||
}
|
||||
|
||||
fn scalar_unit(dl: &TargetDataLayout, value: Primitive) -> Scalar {
|
||||
|
|
|
|||
|
|
@ -23,23 +23,15 @@ 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 infer;
|
||||
mod inhabitedness;
|
||||
mod interner;
|
||||
mod lower;
|
||||
mod lower_nextsolver;
|
||||
mod mapping;
|
||||
pub mod next_solver;
|
||||
mod target_feature;
|
||||
mod tls;
|
||||
mod utils;
|
||||
|
||||
pub mod autoderef;
|
||||
pub mod consteval;
|
||||
mod consteval_chalk;
|
||||
pub mod db;
|
||||
pub mod diagnostics;
|
||||
pub mod display;
|
||||
|
|
@ -61,16 +53,11 @@ mod variance;
|
|||
|
||||
use std::hash::Hash;
|
||||
|
||||
use chalk_ir::{
|
||||
VariableKinds,
|
||||
fold::{Shift, TypeFoldable},
|
||||
interner::HasInterner,
|
||||
};
|
||||
use hir_def::{CallableDefId, GeneralConstId, TypeOrConstParamId, hir::ExprId, type_ref::Rawness};
|
||||
use hir_def::{CallableDefId, TypeOrConstParamId, hir::ExprId, type_ref::Rawness};
|
||||
use hir_expand::name::Name;
|
||||
use indexmap::{IndexMap, map::Entry};
|
||||
use intern::{Symbol, sym};
|
||||
use la_arena::{Arena, Idx};
|
||||
use la_arena::Idx;
|
||||
use mir::{MirEvalError, VTableMap};
|
||||
use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet};
|
||||
use rustc_type_ir::{
|
||||
|
|
@ -82,13 +69,14 @@ use traits::FnTrait;
|
|||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
builder::TyBuilder,
|
||||
chalk_ext::*,
|
||||
db::HirDatabase,
|
||||
display::{DisplayTarget, HirDisplay},
|
||||
generics::Generics,
|
||||
infer::unify::InferenceTable,
|
||||
next_solver::DbInterner,
|
||||
next_solver::{
|
||||
AliasTy, Binder, BoundConst, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, Canonical,
|
||||
CanonicalVarKind, CanonicalVars, Const, ConstKind, DbInterner, FnSig, PolyFnSig, Predicate,
|
||||
Region, RegionKind, TraitRef, Ty, TyKind, Tys, abi,
|
||||
},
|
||||
};
|
||||
|
||||
pub use autoderef::autoderef;
|
||||
|
|
@ -99,15 +87,9 @@ pub use infer::{
|
|||
closure::analysis::{CaptureKind, CapturedItem},
|
||||
could_coerce, could_unify, could_unify_deeply,
|
||||
};
|
||||
pub use interner::Interner;
|
||||
pub use lower::{ImplTraitLoweringMode, ParamLoweringMode, TyDefId, ValueTyDefId, diagnostics::*};
|
||||
pub use lower_nextsolver::{
|
||||
LifetimeElisionKind, TyLoweringContext, 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 lower::{
|
||||
LifetimeElisionKind, TyDefId, TyLoweringContext, ValueTyDefId,
|
||||
associated_type_shorthand_candidates, diagnostics::*,
|
||||
};
|
||||
pub use method_resolution::check_orphan_rules;
|
||||
pub use next_solver::interner::{attach_db, attach_db_allow_change, with_attached_db};
|
||||
|
|
@ -118,76 +100,6 @@ pub use utils::{
|
|||
is_fn_unsafe_to_call, target_feature_is_safe_in_target,
|
||||
};
|
||||
|
||||
use chalk_ir::{BoundVar, DebruijnIndex, Safety, Scalar};
|
||||
|
||||
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(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
|
||||
/// also contain the generic parameters for its parent. See chalk's documentation for details.
|
||||
///
|
||||
/// One thing to keep in mind when working with `Binders` (and `Substitution`s, which represent
|
||||
/// generic arguments) in rust-analyzer is that the ordering within *is* significant - the generic
|
||||
/// 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(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(crate) type Substitution = chalk_ir::Substitution<Interner>;
|
||||
pub(crate) type GenericArg = chalk_ir::GenericArg<Interner>;
|
||||
pub(crate) type GenericArgData = chalk_ir::GenericArgData<Interner>;
|
||||
|
||||
pub(crate) type Ty = chalk_ir::Ty<Interner>;
|
||||
pub type TyKind = chalk_ir::TyKind<Interner>;
|
||||
pub(crate) type DynTy = chalk_ir::DynTy<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(crate) type ProjectionTy = chalk_ir::ProjectionTy<Interner>;
|
||||
pub(crate) type OpaqueTy = chalk_ir::OpaqueTy<Interner>;
|
||||
|
||||
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(crate) type ConstValue = chalk_ir::ConstValue<Interner>;
|
||||
|
||||
pub(crate) type Const = chalk_ir::Const<Interner>;
|
||||
pub(crate) type ConstData = chalk_ir::ConstData<Interner>;
|
||||
|
||||
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(crate) type InEnvironment<T> = chalk_ir::InEnvironment<T>;
|
||||
pub type AliasEq = chalk_ir::AliasEq<Interner>;
|
||||
pub type WhereClause = chalk_ir::WhereClause<Interner>;
|
||||
|
||||
pub(crate) type DomainGoal = chalk_ir::DomainGoal<Interner>;
|
||||
pub(crate) type Goal = chalk_ir::Goal<Interner>;
|
||||
|
||||
pub(crate) type CanonicalVarKind = chalk_ir::CanonicalVarKind<Interner>;
|
||||
pub(crate) type GoalData = chalk_ir::GoalData<Interner>;
|
||||
pub(crate) type ProgramClause = chalk_ir::ProgramClause<Interner>;
|
||||
|
||||
/// A constant can have reference to other things. Memory map job is holding
|
||||
/// the necessary bits of memory of the const eval session to keep the constant
|
||||
/// meaningful.
|
||||
|
|
@ -221,7 +133,7 @@ impl ComplexMemoryMap<'_> {
|
|||
}
|
||||
|
||||
impl<'db> MemoryMap<'db> {
|
||||
pub fn vtable_ty(&self, id: usize) -> Result<crate::next_solver::Ty<'db>, MirEvalError<'db>> {
|
||||
pub fn vtable_ty(&self, id: usize) -> Result<Ty<'db>, MirEvalError<'db>> {
|
||||
match self {
|
||||
MemoryMap::Empty | MemoryMap::Simple(_) => Err(MirEvalError::InvalidVTableId(id)),
|
||||
MemoryMap::Complex(cm) => cm.vtable.ty(id),
|
||||
|
|
@ -271,118 +183,11 @@ impl<'db> MemoryMap<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME(next-solver): add a lifetime to this
|
||||
/// A concrete constant value
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ConstScalar {
|
||||
Bytes(Box<[u8]>, MemoryMap<'static>),
|
||||
// FIXME: this is a hack to get around chalk not being able to represent unevaluatable
|
||||
// constants
|
||||
UnevaluatedConst(GeneralConstId, Substitution),
|
||||
/// Case of an unknown value that rustc might know but we don't
|
||||
// FIXME: this is a hack to get around chalk not being able to represent unevaluatable
|
||||
// constants
|
||||
// https://github.com/rust-lang/rust-analyzer/pull/8813#issuecomment-840679177
|
||||
// https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/Handling.20non.20evaluatable.20constants'.20equality/near/238386348
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl Hash for ConstScalar {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
core::mem::discriminant(self).hash(state);
|
||||
if let ConstScalar::Bytes(b, _) = self {
|
||||
b.hash(state)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A concrete constant value
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ConstScalarNs<'db> {
|
||||
Bytes(Box<[u8]>, MemoryMap<'db>),
|
||||
// FIXME: this is a hack to get around chalk not being able to represent unevaluatable
|
||||
// constants
|
||||
UnevaluatedConst(GeneralConstId, Substitution),
|
||||
/// Case of an unknown value that rustc might know but we don't
|
||||
// FIXME: this is a hack to get around chalk not being able to represent unevaluatable
|
||||
// constants
|
||||
// https://github.com/rust-lang/rust-analyzer/pull/8813#issuecomment-840679177
|
||||
// https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/Handling.20non.20evaluatable.20constants'.20equality/near/238386348
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl Hash for ConstScalarNs<'_> {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
core::mem::discriminant(self).hash(state);
|
||||
if let ConstScalarNs::Bytes(b, _) = self {
|
||||
b.hash(state)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return an index of a parameter in the generic type parameter list by it's id.
|
||||
pub fn param_idx(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Option<usize> {
|
||||
generics::generics(db, id.parent).type_or_const_param_idx(id)
|
||||
}
|
||||
|
||||
pub(crate) fn wrap_empty_binders<T>(value: T) -> Binders<T>
|
||||
where
|
||||
T: TypeFoldable<Interner> + HasInterner<Interner = Interner>,
|
||||
{
|
||||
Binders::empty(Interner, value.shifted_in_from(Interner, DebruijnIndex::ONE))
|
||||
}
|
||||
|
||||
pub(crate) fn make_single_type_binders<T: HasInterner<Interner = Interner>>(
|
||||
value: T,
|
||||
) -> Binders<T> {
|
||||
Binders::new(
|
||||
chalk_ir::VariableKinds::from_iter(
|
||||
Interner,
|
||||
std::iter::once(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)),
|
||||
),
|
||||
value,
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn make_binders<T: HasInterner<Interner = Interner>>(
|
||||
db: &dyn HirDatabase,
|
||||
generics: &Generics,
|
||||
value: T,
|
||||
) -> Binders<T> {
|
||||
Binders::new(variable_kinds_from_iter(db, generics.iter_id()), value)
|
||||
}
|
||||
|
||||
pub(crate) fn variable_kinds_from_iter(
|
||||
db: &dyn HirDatabase,
|
||||
iter: impl Iterator<Item = hir_def::GenericParamId>,
|
||||
) -> VariableKinds<Interner> {
|
||||
VariableKinds::from_iter(
|
||||
Interner,
|
||||
iter.map(|x| match x {
|
||||
hir_def::GenericParamId::ConstParamId(id) => {
|
||||
chalk_ir::VariableKind::Const(db.const_param_ty(id))
|
||||
}
|
||||
hir_def::GenericParamId::TypeParamId(_) => {
|
||||
chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)
|
||||
}
|
||||
hir_def::GenericParamId::LifetimeParamId(_) => chalk_ir::VariableKind::Lifetime,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
// FIXME: get rid of this, just replace it by FnPointer
|
||||
/// A function signature as seen by type inference: Several parameter types and
|
||||
/// one return type.
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub(crate) struct CallableSig {
|
||||
params_and_return: Arc<[Ty]>,
|
||||
is_varargs: bool,
|
||||
safety: Safety,
|
||||
abi: FnAbi,
|
||||
}
|
||||
|
||||
has_interner!(CallableSig);
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq)]
|
||||
pub enum FnAbi {
|
||||
Aapcs,
|
||||
|
|
@ -534,81 +339,21 @@ pub enum ImplTraitId {
|
|||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Hash)]
|
||||
pub struct ImplTraits {
|
||||
pub(crate) impl_traits: Arena<ImplTrait>,
|
||||
}
|
||||
|
||||
has_interner!(ImplTraits);
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Hash)]
|
||||
pub struct ImplTrait {
|
||||
pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>,
|
||||
}
|
||||
pub struct ImplTrait {}
|
||||
|
||||
pub type ImplTraitIdx = Idx<ImplTrait>;
|
||||
|
||||
pub fn static_lifetime() -> Lifetime {
|
||||
LifetimeData::Static.intern(Interner)
|
||||
}
|
||||
|
||||
pub fn error_lifetime() -> Lifetime {
|
||||
LifetimeData::Error.intern(Interner)
|
||||
}
|
||||
|
||||
pub(crate) fn fold_free_vars<T: HasInterner<Interner = Interner> + TypeFoldable<Interner>>(
|
||||
t: T,
|
||||
for_ty: impl FnMut(BoundVar, DebruijnIndex) -> Ty,
|
||||
for_const: impl FnMut(Ty, BoundVar, DebruijnIndex) -> Const,
|
||||
) -> T {
|
||||
use chalk_ir::fold::TypeFolder;
|
||||
|
||||
#[derive(chalk_derive::FallibleTypeFolder)]
|
||||
#[has_interner(Interner)]
|
||||
struct FreeVarFolder<
|
||||
F1: FnMut(BoundVar, DebruijnIndex) -> Ty,
|
||||
F2: FnMut(Ty, BoundVar, DebruijnIndex) -> Const,
|
||||
>(F1, F2);
|
||||
impl<F1: FnMut(BoundVar, DebruijnIndex) -> Ty, F2: FnMut(Ty, BoundVar, DebruijnIndex) -> Const>
|
||||
TypeFolder<Interner> for FreeVarFolder<F1, F2>
|
||||
{
|
||||
fn as_dyn(&mut self) -> &mut dyn TypeFolder<Interner> {
|
||||
self
|
||||
}
|
||||
|
||||
fn interner(&self) -> Interner {
|
||||
Interner
|
||||
}
|
||||
|
||||
fn fold_free_var_ty(&mut self, bound_var: BoundVar, outer_binder: DebruijnIndex) -> Ty {
|
||||
self.0(bound_var, outer_binder)
|
||||
}
|
||||
|
||||
fn fold_free_var_const(
|
||||
&mut self,
|
||||
ty: Ty,
|
||||
bound_var: BoundVar,
|
||||
outer_binder: DebruijnIndex,
|
||||
) -> Const {
|
||||
self.1(ty, bound_var, outer_binder)
|
||||
}
|
||||
}
|
||||
t.fold_with(&mut FreeVarFolder(for_ty, for_const), DebruijnIndex::INNERMOST)
|
||||
}
|
||||
|
||||
/// '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<'db, T>(
|
||||
interner: DbInterner<'db>,
|
||||
t: &T,
|
||||
) -> crate::next_solver::Canonical<'db, T>
|
||||
pub fn replace_errors_with_variables<'db, T>(interner: DbInterner<'db>, t: &T) -> Canonical<'db, T>
|
||||
where
|
||||
T: rustc_type_ir::TypeFoldable<DbInterner<'db>> + Clone,
|
||||
{
|
||||
use rustc_type_ir::{FallibleTypeFolder, TypeSuperFoldable};
|
||||
struct ErrorReplacer<'db> {
|
||||
interner: DbInterner<'db>,
|
||||
vars: Vec<crate::next_solver::CanonicalVarKind<'db>>,
|
||||
vars: Vec<CanonicalVarKind<'db>>,
|
||||
binder: rustc_type_ir::DebruijnIndex,
|
||||
}
|
||||
impl<'db> FallibleTypeFolder<DbInterner<'db>> for ErrorReplacer<'db> {
|
||||
|
|
@ -621,10 +366,7 @@ where
|
|||
self.interner
|
||||
}
|
||||
|
||||
fn try_fold_binder<T>(
|
||||
&mut self,
|
||||
t: crate::next_solver::Binder<'db, T>,
|
||||
) -> Result<crate::next_solver::Binder<'db, T>, Self::Error>
|
||||
fn try_fold_binder<T>(&mut self, t: Binder<'db, T>) -> Result<Binder<'db, T>, Self::Error>
|
||||
where
|
||||
T: rustc_type_ir::TypeFoldable<DbInterner<'db>>,
|
||||
{
|
||||
|
|
@ -634,10 +376,7 @@ where
|
|||
result
|
||||
}
|
||||
|
||||
fn try_fold_ty(
|
||||
&mut self,
|
||||
t: crate::next_solver::Ty<'db>,
|
||||
) -> Result<crate::next_solver::Ty<'db>, Self::Error> {
|
||||
fn try_fold_ty(&mut self, t: Ty<'db>) -> Result<Ty<'db>, Self::Error> {
|
||||
if !t.has_type_flags(
|
||||
rustc_type_ir::TypeFlags::HAS_ERROR
|
||||
| rustc_type_ir::TypeFlags::HAS_TY_INFER
|
||||
|
|
@ -650,39 +389,28 @@ where
|
|||
#[cfg(debug_assertions)]
|
||||
let error = || Err(());
|
||||
#[cfg(not(debug_assertions))]
|
||||
let error = || {
|
||||
Ok(crate::next_solver::Ty::new_error(
|
||||
self.interner,
|
||||
crate::next_solver::ErrorGuaranteed,
|
||||
))
|
||||
};
|
||||
let error = || Ok(Ty::new_error(self.interner, crate::next_solver::ErrorGuaranteed));
|
||||
|
||||
match t.kind() {
|
||||
crate::next_solver::TyKind::Error(_) => {
|
||||
TyKind::Error(_) => {
|
||||
let var = rustc_type_ir::BoundVar::from_usize(self.vars.len());
|
||||
self.vars.push(crate::next_solver::CanonicalVarKind::Ty {
|
||||
self.vars.push(CanonicalVarKind::Ty {
|
||||
ui: rustc_type_ir::UniverseIndex::ZERO,
|
||||
sub_root: var,
|
||||
});
|
||||
Ok(crate::next_solver::Ty::new_bound(
|
||||
Ok(Ty::new_bound(
|
||||
self.interner,
|
||||
self.binder,
|
||||
crate::next_solver::BoundTy {
|
||||
var,
|
||||
kind: crate::next_solver::BoundTyKind::Anon,
|
||||
},
|
||||
BoundTy { var, kind: BoundTyKind::Anon },
|
||||
))
|
||||
}
|
||||
crate::next_solver::TyKind::Infer(_) => error(),
|
||||
crate::next_solver::TyKind::Bound(index, _) if index > self.binder => error(),
|
||||
TyKind::Infer(_) => error(),
|
||||
TyKind::Bound(index, _) if index > self.binder => error(),
|
||||
_ => t.try_super_fold_with(self),
|
||||
}
|
||||
}
|
||||
|
||||
fn try_fold_const(
|
||||
&mut self,
|
||||
ct: crate::next_solver::Const<'db>,
|
||||
) -> Result<crate::next_solver::Const<'db>, Self::Error> {
|
||||
fn try_fold_const(&mut self, ct: Const<'db>) -> Result<Const<'db>, Self::Error> {
|
||||
if !ct.has_type_flags(
|
||||
rustc_type_ir::TypeFlags::HAS_ERROR
|
||||
| rustc_type_ir::TypeFlags::HAS_TY_INFER
|
||||
|
|
@ -695,52 +423,38 @@ where
|
|||
#[cfg(debug_assertions)]
|
||||
let error = || Err(());
|
||||
#[cfg(not(debug_assertions))]
|
||||
let error = || Ok(crate::next_solver::Const::error(self.interner));
|
||||
let error = || Ok(Const::error(self.interner));
|
||||
|
||||
match ct.kind() {
|
||||
crate::next_solver::ConstKind::Error(_) => {
|
||||
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 },
|
||||
))
|
||||
self.vars.push(CanonicalVarKind::Const(rustc_type_ir::UniverseIndex::ZERO));
|
||||
Ok(Const::new_bound(self.interner, self.binder, BoundConst { var }))
|
||||
}
|
||||
crate::next_solver::ConstKind::Infer(_) => error(),
|
||||
crate::next_solver::ConstKind::Bound(index, _) if index > self.binder => error(),
|
||||
ConstKind::Infer(_) => error(),
|
||||
ConstKind::Bound(index, _) if index > self.binder => error(),
|
||||
_ => ct.try_super_fold_with(self),
|
||||
}
|
||||
}
|
||||
|
||||
fn try_fold_region(
|
||||
&mut self,
|
||||
region: crate::next_solver::Region<'db>,
|
||||
) -> Result<crate::next_solver::Region<'db>, Self::Error> {
|
||||
fn try_fold_region(&mut self, region: Region<'db>) -> Result<Region<'db>, Self::Error> {
|
||||
#[cfg(debug_assertions)]
|
||||
let error = || Err(());
|
||||
#[cfg(not(debug_assertions))]
|
||||
let error = || Ok(crate::next_solver::Region::error(self.interner));
|
||||
let error = || Ok(Region::error(self.interner));
|
||||
|
||||
match region.kind() {
|
||||
crate::next_solver::RegionKind::ReError(_) => {
|
||||
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.vars.push(CanonicalVarKind::Region(rustc_type_ir::UniverseIndex::ZERO));
|
||||
Ok(Region::new_bound(
|
||||
self.interner,
|
||||
self.binder,
|
||||
crate::next_solver::BoundRegion {
|
||||
var,
|
||||
kind: crate::next_solver::BoundRegionKind::Anon,
|
||||
},
|
||||
BoundRegion { var, kind: BoundRegionKind::Anon },
|
||||
))
|
||||
}
|
||||
crate::next_solver::RegionKind::ReVar(_) => error(),
|
||||
crate::next_solver::RegionKind::ReBound(index, _) if index > self.binder => error(),
|
||||
RegionKind::ReVar(_) => error(),
|
||||
RegionKind::ReBound(index, _) if index > self.binder => error(),
|
||||
_ => Ok(region),
|
||||
}
|
||||
}
|
||||
|
|
@ -752,18 +466,18 @@ where
|
|||
Ok(t) => t,
|
||||
Err(_) => panic!("Encountered unbound or inference vars in {t:?}"),
|
||||
};
|
||||
crate::next_solver::Canonical {
|
||||
Canonical {
|
||||
value,
|
||||
max_universe: rustc_type_ir::UniverseIndex::ZERO,
|
||||
variables: crate::next_solver::CanonicalVars::new_from_iter(interner, error_replacer.vars),
|
||||
variables: CanonicalVars::new_from_iter(interner, error_replacer.vars),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn callable_sig_from_fn_trait<'db>(
|
||||
self_ty: crate::next_solver::Ty<'db>,
|
||||
self_ty: Ty<'db>,
|
||||
trait_env: Arc<TraitEnvironment<'db>>,
|
||||
db: &'db dyn HirDatabase,
|
||||
) -> Option<(FnTrait, crate::next_solver::PolyFnSig<'db>)> {
|
||||
) -> Option<(FnTrait, PolyFnSig<'db>)> {
|
||||
let krate = trait_env.krate;
|
||||
let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?;
|
||||
let output_assoc_type = fn_once_trait
|
||||
|
|
@ -771,54 +485,46 @@ pub fn callable_sig_from_fn_trait<'db>(
|
|||
.associated_type_by_name(&Name::new_symbol_root(sym::Output))?;
|
||||
|
||||
let mut table = InferenceTable::new(db, trait_env.clone());
|
||||
let b = TyBuilder::trait_ref(db, fn_once_trait);
|
||||
if b.remaining() != 2 {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Register two obligations:
|
||||
// - Self: FnOnce<?args_ty>
|
||||
// - <Self as FnOnce<?args_ty>>::Output == ?ret_ty
|
||||
let args_ty = table.next_ty_var();
|
||||
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(
|
||||
let trait_ref = TraitRef::new(table.interner(), fn_once_trait.into(), args);
|
||||
let projection = Ty::new_alias(
|
||||
table.interner(),
|
||||
rustc_type_ir::AliasTyKind::Projection,
|
||||
crate::next_solver::AliasTy::new(table.interner(), output_assoc_type.into(), args),
|
||||
AliasTy::new(table.interner(), output_assoc_type.into(), args),
|
||||
);
|
||||
|
||||
let pred = crate::next_solver::Predicate::upcast_from(trait_ref, table.interner());
|
||||
let pred = 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);
|
||||
let trait_ref = TraitRef::new(table.interner(), fn_x_trait.into(), args);
|
||||
if !table
|
||||
.try_obligation(crate::next_solver::Predicate::upcast_from(
|
||||
trait_ref,
|
||||
table.interner(),
|
||||
))
|
||||
.try_obligation(Predicate::upcast_from(trait_ref, table.interner()))
|
||||
.no_solution()
|
||||
{
|
||||
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 {
|
||||
let TyKind::Tuple(params) = args_ty.kind() else {
|
||||
return None;
|
||||
};
|
||||
let inputs_and_output = crate::next_solver::Tys::new_from_iter(
|
||||
let inputs_and_output = Tys::new_from_iter(
|
||||
table.interner(),
|
||||
params.iter().chain(std::iter::once(ret_ty)),
|
||||
);
|
||||
|
||||
return Some((
|
||||
fn_x,
|
||||
crate::next_solver::Binder::dummy(crate::next_solver::FnSig {
|
||||
Binder::dummy(FnSig {
|
||||
inputs_and_output,
|
||||
c_variadic: false,
|
||||
safety: crate::next_solver::abi::Safety::Safe,
|
||||
safety: abi::Safety::Safe,
|
||||
abi: FnAbi::RustCall,
|
||||
}),
|
||||
));
|
||||
|
|
@ -837,16 +543,16 @@ struct ParamCollector {
|
|||
impl<'db> rustc_type_ir::TypeVisitor<DbInterner<'db>> for ParamCollector {
|
||||
type Result = ();
|
||||
|
||||
fn visit_ty(&mut self, ty: crate::next_solver::Ty<'db>) -> Self::Result {
|
||||
if let crate::next_solver::TyKind::Param(param) = ty.kind() {
|
||||
fn visit_ty(&mut self, ty: Ty<'db>) -> Self::Result {
|
||||
if let TyKind::Param(param) = ty.kind() {
|
||||
self.params.insert(param.id.into());
|
||||
}
|
||||
|
||||
ty.super_visit_with(self);
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, konst: crate::next_solver::Const<'db>) -> Self::Result {
|
||||
if let crate::next_solver::ConstKind::Param(param) = konst.kind() {
|
||||
fn visit_const(&mut self, konst: Const<'db>) -> Self::Result {
|
||||
if let ConstKind::Param(param) = konst.kind() {
|
||||
self.params.insert(param.id.into());
|
||||
}
|
||||
|
||||
|
|
@ -865,7 +571,7 @@ where
|
|||
}
|
||||
|
||||
pub fn known_const_to_ast<'db>(
|
||||
konst: crate::next_solver::Const<'db>,
|
||||
konst: Const<'db>,
|
||||
db: &'db dyn HirDatabase,
|
||||
display_target: DisplayTarget,
|
||||
) -> Option<ConstArg> {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,169 +0,0 @@
|
|||
//! This module contains the implementations of the `ToChalk` trait, which
|
||||
//! handles conversion between our data types and their corresponding types in
|
||||
//! Chalk (in both directions); plus some helper functions for more specialized
|
||||
//! conversions.
|
||||
|
||||
use hir_def::{LifetimeParamId, TraitId, TypeAliasId, TypeOrConstParamId};
|
||||
use salsa::{
|
||||
Id,
|
||||
plumbing::{AsId, FromId},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
AssocTypeId, CallableDefId, ChalkTraitId, FnDefId, ForeignDefId, Interner, OpaqueTyId,
|
||||
PlaceholderIndex, chalk_db,
|
||||
db::{HirDatabase, InternedLifetimeParamId, InternedTypeOrConstParamId},
|
||||
};
|
||||
|
||||
pub trait ToChalk {
|
||||
type Chalk;
|
||||
fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk;
|
||||
fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self;
|
||||
}
|
||||
|
||||
pub(crate) fn from_chalk<T, ChalkT>(db: &dyn HirDatabase, chalk: ChalkT) -> T
|
||||
where
|
||||
T: ToChalk<Chalk = ChalkT>,
|
||||
{
|
||||
T::from_chalk(db, chalk)
|
||||
}
|
||||
|
||||
impl ToChalk for hir_def::ImplId {
|
||||
type Chalk = chalk_db::ImplId;
|
||||
|
||||
fn to_chalk(self, _db: &dyn HirDatabase) -> chalk_db::ImplId {
|
||||
chalk_ir::ImplId(self.as_id())
|
||||
}
|
||||
|
||||
fn from_chalk(_db: &dyn HirDatabase, impl_id: chalk_db::ImplId) -> hir_def::ImplId {
|
||||
FromId::from_id(impl_id.0.as_id())
|
||||
}
|
||||
}
|
||||
|
||||
impl ToChalk for CallableDefId {
|
||||
type Chalk = FnDefId;
|
||||
|
||||
fn to_chalk(self, _db: &dyn HirDatabase) -> FnDefId {
|
||||
chalk_ir::FnDefId(salsa::plumbing::AsId::as_id(&self))
|
||||
}
|
||||
|
||||
fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDefId {
|
||||
salsa::plumbing::FromIdWithDb::from_id(fn_def_id.0, db.zalsa())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId {
|
||||
fn from(id: OpaqueTyId) -> Self {
|
||||
FromId::from_id(id.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId {
|
||||
fn from(id: crate::db::InternedOpaqueTyId) -> Self {
|
||||
chalk_ir::OpaqueTyId(id.as_id())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<chalk_ir::ClosureId<Interner>> for crate::db::InternedClosureId {
|
||||
fn from(id: chalk_ir::ClosureId<Interner>) -> Self {
|
||||
FromId::from_id(id.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> {
|
||||
fn from(id: crate::db::InternedClosureId) -> Self {
|
||||
chalk_ir::ClosureId(id.as_id())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<chalk_ir::CoroutineId<Interner>> for crate::db::InternedCoroutineId {
|
||||
fn from(id: chalk_ir::CoroutineId<Interner>) -> Self {
|
||||
Self::from_id(id.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<crate::db::InternedCoroutineId> for chalk_ir::CoroutineId<Interner> {
|
||||
fn from(id: crate::db::InternedCoroutineId) -> Self {
|
||||
chalk_ir::CoroutineId(id.as_id())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId {
|
||||
chalk_ir::ForeignDefId(id.as_id())
|
||||
}
|
||||
|
||||
pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId {
|
||||
FromId::from_id(id.0)
|
||||
}
|
||||
|
||||
pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId {
|
||||
chalk_ir::AssocTypeId(id.as_id())
|
||||
}
|
||||
|
||||
pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId {
|
||||
FromId::from_id(id.0)
|
||||
}
|
||||
|
||||
pub fn from_placeholder_idx(
|
||||
db: &dyn HirDatabase,
|
||||
idx: PlaceholderIndex,
|
||||
) -> (TypeOrConstParamId, u32) {
|
||||
assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT);
|
||||
// SAFETY: We cannot really encapsulate this unfortunately, so just hope this is sound.
|
||||
let interned_id =
|
||||
InternedTypeOrConstParamId::from_id(unsafe { Id::from_index(idx.idx.try_into().unwrap()) });
|
||||
interned_id.loc(db)
|
||||
}
|
||||
|
||||
pub fn to_placeholder_idx(
|
||||
db: &dyn HirDatabase,
|
||||
id: TypeOrConstParamId,
|
||||
idx: u32,
|
||||
) -> PlaceholderIndex {
|
||||
let interned_id = InternedTypeOrConstParamId::new(db, (id, idx));
|
||||
PlaceholderIndex {
|
||||
ui: chalk_ir::UniverseIndex::ROOT,
|
||||
idx: interned_id.as_id().index() as usize,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_placeholder_idx_no_index(
|
||||
db: &dyn HirDatabase,
|
||||
id: TypeOrConstParamId,
|
||||
) -> PlaceholderIndex {
|
||||
let index = crate::generics::generics(db, id.parent)
|
||||
.type_or_const_param_idx(id)
|
||||
.expect("param not found");
|
||||
to_placeholder_idx(db, id, index as u32)
|
||||
}
|
||||
|
||||
pub fn lt_from_placeholder_idx(
|
||||
db: &dyn HirDatabase,
|
||||
idx: PlaceholderIndex,
|
||||
) -> (LifetimeParamId, u32) {
|
||||
assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT);
|
||||
// SAFETY: We cannot really encapsulate this unfortunately, so just hope this is sound.
|
||||
let interned_id =
|
||||
InternedLifetimeParamId::from_id(unsafe { Id::from_index(idx.idx.try_into().unwrap()) });
|
||||
interned_id.loc(db)
|
||||
}
|
||||
|
||||
pub fn lt_to_placeholder_idx(
|
||||
db: &dyn HirDatabase,
|
||||
id: LifetimeParamId,
|
||||
idx: u32,
|
||||
) -> PlaceholderIndex {
|
||||
let interned_id = InternedLifetimeParamId::new(db, (id, idx));
|
||||
PlaceholderIndex {
|
||||
ui: chalk_ir::UniverseIndex::ROOT,
|
||||
idx: interned_id.as_id().index() as usize,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId {
|
||||
chalk_ir::TraitId(id.as_id())
|
||||
}
|
||||
|
||||
pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId {
|
||||
FromId::from_id(id.0)
|
||||
}
|
||||
|
|
@ -25,10 +25,8 @@ use smallvec::{SmallVec, smallvec};
|
|||
use stdx::never;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::next_solver::infer::InferCtxt;
|
||||
use crate::next_solver::infer::select::ImplSource;
|
||||
use crate::{
|
||||
TraitEnvironment, TyBuilder,
|
||||
TraitEnvironment,
|
||||
autoderef::{self, AutoderefKind},
|
||||
db::HirDatabase,
|
||||
infer::{Adjust, Adjustment, OverloadedDeref, PointerCast, unify::InferenceTable},
|
||||
|
|
@ -37,7 +35,8 @@ use crate::{
|
|||
Canonical, DbInterner, ErrorGuaranteed, GenericArgs, Goal, Predicate, Region, SolverDefId,
|
||||
TraitRef, Ty, TyKind, TypingMode,
|
||||
infer::{
|
||||
DbInternerInferExt,
|
||||
DbInternerInferExt, InferCtxt,
|
||||
select::ImplSource,
|
||||
traits::{Obligation, ObligationCause, PredicateObligation},
|
||||
},
|
||||
obligation_ctxt::ObligationCtxt,
|
||||
|
|
@ -1597,9 +1596,9 @@ fn is_valid_impl_method_candidate<'db>(
|
|||
return IsValidCandidate::NotVisible;
|
||||
}
|
||||
let self_ty_matches = table.run_in_snapshot(|table| {
|
||||
let expected_self_ty = TyBuilder::impl_self_ty(db, impl_id)
|
||||
.fill_with_inference_vars(table)
|
||||
.build(table.interner());
|
||||
let impl_args = table.fresh_args_for_item(impl_id.into());
|
||||
let expected_self_ty =
|
||||
db.impl_self_ty(impl_id).instantiate(table.interner(), impl_args);
|
||||
table.unify(expected_self_ty, self_ty)
|
||||
});
|
||||
if !self_ty_matches {
|
||||
|
|
@ -1727,7 +1726,7 @@ fn is_valid_impl_fn_candidate<'db>(
|
|||
|
||||
// We need to consider the bounds on the impl to distinguish functions of the same name
|
||||
// for a type.
|
||||
let predicates = db.generic_predicates_ns(impl_id.into());
|
||||
let predicates = db.generic_predicates(impl_id.into());
|
||||
let Some(predicates) = predicates.instantiate(table.interner(), impl_subst) else {
|
||||
return IsValidCandidate::Yes;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ impl<V, T> ProjectionElem<V, T> {
|
|||
},
|
||||
ProjectionElem::Field(Either::Left(f)) => match base.kind() {
|
||||
TyKind::Adt(_, subst) => {
|
||||
db.field_types_ns(f.parent)[f.local_id].instantiate(interner, subst)
|
||||
db.field_types(f.parent)[f.local_id].instantiate(interner, subst)
|
||||
}
|
||||
ty => {
|
||||
never!("Only adt has field, found {:?}", ty);
|
||||
|
|
|
|||
|
|
@ -1696,7 +1696,7 @@ impl<'db> Evaluator<'db> {
|
|||
if let TyKind::Adt(adt_ef, subst) = kind
|
||||
&& let AdtId::StructId(struct_id) = adt_ef.def_id().0
|
||||
{
|
||||
let field_types = self.db.field_types_ns(struct_id.into());
|
||||
let field_types = self.db.field_types(struct_id.into());
|
||||
if let Some(ty) =
|
||||
field_types.iter().last().map(|it| it.1.instantiate(self.interner(), subst))
|
||||
{
|
||||
|
|
@ -1775,9 +1775,9 @@ impl<'db> Evaluator<'db> {
|
|||
else {
|
||||
not_supported!("unsizing struct without field");
|
||||
};
|
||||
let target_last_field = self.db.field_types_ns(id.into())[last_field]
|
||||
let target_last_field = self.db.field_types(id.into())[last_field]
|
||||
.instantiate(self.interner(), target_subst);
|
||||
let current_last_field = self.db.field_types_ns(id.into())[last_field]
|
||||
let current_last_field = self.db.field_types(id.into())[last_field]
|
||||
.instantiate(self.interner(), current_subst);
|
||||
return self.unsizing_ptr_from_addr(
|
||||
target_last_field,
|
||||
|
|
@ -2268,7 +2268,7 @@ impl<'db> Evaluator<'db> {
|
|||
AdtId::StructId(s) => {
|
||||
let data = s.fields(this.db);
|
||||
let layout = this.layout(ty)?;
|
||||
let field_types = this.db.field_types_ns(s.into());
|
||||
let field_types = this.db.field_types(s.into());
|
||||
for (f, _) in data.fields().iter() {
|
||||
let offset = layout
|
||||
.fields
|
||||
|
|
@ -2296,7 +2296,7 @@ impl<'db> Evaluator<'db> {
|
|||
e,
|
||||
) {
|
||||
let data = v.fields(this.db);
|
||||
let field_types = this.db.field_types_ns(v.into());
|
||||
let field_types = this.db.field_types(v.into());
|
||||
for (f, _) in data.fields().iter() {
|
||||
let offset =
|
||||
l.fields.offset(u32::from(f.into_raw()) as usize).bytes_usize();
|
||||
|
|
@ -2373,7 +2373,7 @@ impl<'db> Evaluator<'db> {
|
|||
}
|
||||
TyKind::Adt(id, args) => match id.def_id().0 {
|
||||
AdtId::StructId(s) => {
|
||||
for (i, (_, ty)) in self.db.field_types_ns(s.into()).iter().enumerate() {
|
||||
for (i, (_, ty)) in self.db.field_types(s.into()).iter().enumerate() {
|
||||
let offset = layout.fields.offset(i).bytes_usize();
|
||||
let ty = ty.instantiate(self.interner(), args);
|
||||
self.patch_addresses(
|
||||
|
|
@ -2394,7 +2394,7 @@ impl<'db> Evaluator<'db> {
|
|||
self.read_memory(addr, layout.size.bytes_usize())?,
|
||||
e,
|
||||
) {
|
||||
for (i, (_, ty)) in self.db.field_types_ns(ev.into()).iter().enumerate() {
|
||||
for (i, (_, ty)) in self.db.field_types(ev.into()).iter().enumerate() {
|
||||
let offset = layout.fields.offset(i).bytes_usize();
|
||||
let ty = ty.instantiate(self.interner(), args);
|
||||
self.patch_addresses(
|
||||
|
|
@ -2895,7 +2895,7 @@ impl<'db> Evaluator<'db> {
|
|||
let variant_fields = s.fields(self.db);
|
||||
match variant_fields.shape {
|
||||
FieldsShape::Record | FieldsShape::Tuple => {
|
||||
let field_types = self.db.field_types_ns(s.into());
|
||||
let field_types = self.db.field_types(s.into());
|
||||
for (field, _) in variant_fields.fields().iter() {
|
||||
let offset = layout
|
||||
.fields
|
||||
|
|
|
|||
|
|
@ -1383,7 +1383,7 @@ impl<'db> Evaluator<'db> {
|
|||
AdtId::StructId(s) => s,
|
||||
_ => not_supported!("unsized enum or union"),
|
||||
};
|
||||
let field_types = self.db.field_types_ns(id.into());
|
||||
let field_types = self.db.field_types(id.into());
|
||||
let last_field_ty =
|
||||
field_types.iter().next_back().unwrap().1.instantiate(self.interner(), subst);
|
||||
let sized_part_size =
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ impl<'db> Evaluator<'db> {
|
|||
let Some((first_field, _)) = fields.iter().next() else {
|
||||
not_supported!("simd type with no field");
|
||||
};
|
||||
let field_ty = self.db.field_types_ns(id.into())[first_field]
|
||||
let field_ty = self.db.field_types(id.into())[first_field]
|
||||
.instantiate(self.interner(), subst);
|
||||
return Ok((fields.len(), field_ty));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ pub use region::*;
|
|||
pub use solver::*;
|
||||
pub use ty::*;
|
||||
|
||||
pub use crate::lower_nextsolver::ImplTraitIdx;
|
||||
pub use crate::lower::ImplTraitIdx;
|
||||
pub use rustc_ast_ir::Mutability;
|
||||
|
||||
pub type Binder<'db, T> = rustc_type_ir::Binder<DbInterner<'db>, T>;
|
||||
|
|
|
|||
|
|
@ -14,8 +14,7 @@ use rustc_type_ir::{
|
|||
|
||||
use crate::{
|
||||
MemoryMap,
|
||||
interner::InternedWrapperNoDebug,
|
||||
next_solver::{ClauseKind, ParamEnv},
|
||||
next_solver::{ClauseKind, ParamEnv, interner::InternedWrapperNoDebug},
|
||||
};
|
||||
|
||||
use super::{BoundVarKind, DbInterner, ErrorGuaranteed, GenericArgs, Placeholder, Ty};
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ impl<'db> GenericArgs<'db> {
|
|||
where
|
||||
F: FnMut(u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
|
||||
{
|
||||
let defaults = interner.db.generic_defaults_ns(def_id);
|
||||
let defaults = interner.db.generic_defaults(def_id);
|
||||
Self::for_item(interner, def_id.into(), |idx, id, prev| match defaults.get(idx as usize) {
|
||||
Some(default) => default.instantiate(interner, prev),
|
||||
None => fallback(idx, id, prev),
|
||||
|
|
@ -240,7 +240,7 @@ impl<'db> GenericArgs<'db> {
|
|||
where
|
||||
F: FnMut(u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
|
||||
{
|
||||
let defaults = interner.db.generic_defaults_ns(def_id);
|
||||
let defaults = interner.db.generic_defaults(def_id);
|
||||
Self::fill_rest(interner, def_id.into(), first, |idx, id, prev| {
|
||||
defaults
|
||||
.get(idx as usize)
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ use crate::{
|
|||
method_resolution::{ALL_FLOAT_FPS, ALL_INT_FPS, TyFingerprint},
|
||||
next_solver::{
|
||||
AdtIdWrapper, BoundConst, CallableIdWrapper, CanonicalVarKind, ClosureIdWrapper,
|
||||
CoroutineIdWrapper, Ctor, FnSig, FxIndexMap, ImplIdWrapper, InternedWrapperNoDebug,
|
||||
RegionAssumptions, SolverContext, SolverDefIds, TraitIdWrapper, TypeAliasIdWrapper,
|
||||
CoroutineIdWrapper, Ctor, FnSig, FxIndexMap, ImplIdWrapper, RegionAssumptions,
|
||||
SolverContext, SolverDefIds, TraitIdWrapper, TypeAliasIdWrapper,
|
||||
util::{ContainsTypeErrors, explicit_item_bounds, for_trait_impls},
|
||||
},
|
||||
};
|
||||
|
|
@ -53,6 +53,9 @@ use super::{
|
|||
util::sizedness_constraint_for_ty,
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Clone)]
|
||||
pub struct InternedWrapperNoDebug<T>(pub(crate) T);
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! _interned_vec_nolifetime_salsa {
|
||||
|
|
@ -611,7 +614,7 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
|
|||
return None;
|
||||
};
|
||||
let id: VariantId = struct_id.into();
|
||||
let field_types = interner.db().field_types_ns(id);
|
||||
let field_types = interner.db().field_types(id);
|
||||
|
||||
field_types.iter().last().map(|f| *f.1)
|
||||
}
|
||||
|
|
@ -623,7 +626,7 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
|
|||
let db = interner.db();
|
||||
// FIXME: this is disabled just to match the behavior with chalk right now
|
||||
let _field_tys = |id: VariantId| {
|
||||
db.field_types_ns(id).iter().map(|(_, ty)| ty.skip_binder()).collect::<Vec<_>>()
|
||||
db.field_types(id).iter().map(|(_, ty)| ty.skip_binder()).collect::<Vec<_>>()
|
||||
};
|
||||
let field_tys = |_id: VariantId| vec![];
|
||||
let tys: Vec<_> = match self.inner().id {
|
||||
|
|
@ -1284,7 +1287,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
|
|||
self,
|
||||
def_id: Self::DefId,
|
||||
) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
|
||||
let predicates = self.db().generic_predicates_ns(def_id.try_into().unwrap());
|
||||
let predicates = self.db().generic_predicates(def_id.try_into().unwrap());
|
||||
let predicates: Vec<_> = predicates.iter().cloned().collect();
|
||||
EarlyBinder::bind(predicates.into_iter())
|
||||
}
|
||||
|
|
@ -1311,7 +1314,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
|
|||
|
||||
let predicates: Vec<(Clause<'db>, Span)> = self
|
||||
.db()
|
||||
.generic_predicates_ns(def_id.0.into())
|
||||
.generic_predicates(def_id.0.into())
|
||||
.iter()
|
||||
.filter(|p| match p.kind().skip_binder() {
|
||||
// rustc has the following assertion:
|
||||
|
|
@ -1345,7 +1348,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
|
|||
|
||||
let predicates: Vec<(Clause<'db>, Span)> = self
|
||||
.db()
|
||||
.generic_predicates_ns(def_id.try_into().unwrap())
|
||||
.generic_predicates(def_id.try_into().unwrap())
|
||||
.iter()
|
||||
.filter(|p| match p.kind().skip_binder() {
|
||||
rustc_type_ir::ClauseKind::Trait(it) => is_self_or_assoc(it.self_ty()),
|
||||
|
|
@ -1765,7 +1768,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
|
|||
return UnsizingParams(DenseBitSet::new_empty(num_params));
|
||||
};
|
||||
|
||||
let field_types = self.db().field_types_ns(variant.id());
|
||||
let field_types = self.db().field_types(variant.id());
|
||||
let mut unsizing_params = DenseBitSet::new_empty(num_params);
|
||||
let ty = field_types[tail_field.0];
|
||||
for arg in ty.instantiate_identity().walk() {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -13,7 +13,7 @@ use rustc_type_ir::{
|
|||
};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::next_solver::TraitIdWrapper;
|
||||
use crate::next_solver::{InternedWrapperNoDebug, TraitIdWrapper};
|
||||
|
||||
use super::{Binder, BoundVarKinds, DbInterner, Region, Ty, interned_vec_db};
|
||||
|
||||
|
|
@ -171,9 +171,6 @@ impl<'db> rustc_type_ir::relate::Relate<DbInterner<'db>> for BoundExistentialPre
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Clone)]
|
||||
pub struct InternedWrapperNoDebug<T>(pub(crate) T);
|
||||
|
||||
#[salsa::interned(constructor = new_)]
|
||||
pub struct Predicate<'db> {
|
||||
#[returns(ref)]
|
||||
|
|
|
|||
|
|
@ -26,11 +26,11 @@ use rustc_type_ir::{
|
|||
use crate::{
|
||||
ImplTraitId,
|
||||
db::HirDatabase,
|
||||
interner::InternedWrapperNoDebug,
|
||||
next_solver::{
|
||||
AdtDef, Binder, CallableIdWrapper, Clause, ClauseKind, ClosureIdWrapper, Const,
|
||||
CoroutineIdWrapper, FnSig, GenericArg, PolyFnSig, Region, TraitRef, TypeAliasIdWrapper,
|
||||
abi::Safety,
|
||||
interner::InternedWrapperNoDebug,
|
||||
mapping::ChalkToNextSolver,
|
||||
util::{CoroutineArgsExt, IntegerTypeExt},
|
||||
},
|
||||
|
|
@ -531,7 +531,7 @@ impl<'db> Ty<'db> {
|
|||
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_ns(func).map(|it| {
|
||||
db.return_type_impl_traits(func).map(|it| {
|
||||
let data = (*it).as_ref().map_bound(|rpit| {
|
||||
&rpit.impl_traits[idx.to_nextsolver(interner)].predicates
|
||||
});
|
||||
|
|
@ -540,7 +540,7 @@ impl<'db> Ty<'db> {
|
|||
})
|
||||
}
|
||||
ImplTraitId::TypeAliasImplTrait(alias, idx) => {
|
||||
db.type_alias_impl_traits_ns(alias).map(|it| {
|
||||
db.type_alias_impl_traits(alias).map(|it| {
|
||||
let data = (*it).as_ref().map_bound(|rpit| {
|
||||
&rpit.impl_traits[idx.to_nextsolver(interner)].predicates
|
||||
});
|
||||
|
|
@ -575,7 +575,7 @@ impl<'db> Ty<'db> {
|
|||
TypeOrConstParamData::TypeParamData(p) => match p.provenance {
|
||||
TypeParamProvenance::ArgumentImplTrait => {
|
||||
let predicates = db
|
||||
.generic_predicates_ns(param.id.parent())
|
||||
.generic_predicates(param.id.parent())
|
||||
.instantiate_identity()
|
||||
.into_iter()
|
||||
.flatten()
|
||||
|
|
|
|||
|
|
@ -1,46 +1,42 @@
|
|||
//! Various utilities for the next-trait-solver.
|
||||
|
||||
use std::iter;
|
||||
use std::ops::{self, ControlFlow};
|
||||
use std::{
|
||||
iter,
|
||||
ops::{self, ControlFlow},
|
||||
};
|
||||
|
||||
use base_db::Crate;
|
||||
use hir_def::lang_item::LangItem;
|
||||
use hir_def::{BlockId, HasModule};
|
||||
use hir_def::{BlockId, HasModule, lang_item::LangItem};
|
||||
use intern::sym;
|
||||
use la_arena::Idx;
|
||||
use rustc_abi::{Float, HasDataLayout, Integer, IntegerType, Primitive, ReprOptions};
|
||||
use rustc_type_ir::data_structures::IndexMap;
|
||||
use rustc_type_ir::inherent::{
|
||||
AdtDef, GenericArg as _, GenericArgs as _, ParamEnv as _, SliceLike, Ty as _,
|
||||
};
|
||||
use rustc_type_ir::lang_items::SolverTraitLangItem;
|
||||
use rustc_type_ir::solve::SizedTraitKind;
|
||||
use rustc_type_ir::{
|
||||
BoundVar, Canonical, DebruijnIndex, GenericArgKind, INNERMOST, Interner, PredicatePolarity,
|
||||
TypeVisitableExt,
|
||||
ConstKind, CoroutineArgs, DebruijnIndex, FloatTy, GenericArgKind, INNERMOST, IntTy, Interner,
|
||||
PredicatePolarity, RegionKind, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable,
|
||||
TypeVisitableExt, TypeVisitor, UintTy, UniverseIndex,
|
||||
inherent::{
|
||||
AdtDef, GenericArg as _, GenericArgs as _, IntoKind, ParamEnv as _, SliceLike, Ty as _,
|
||||
},
|
||||
lang_items::SolverTraitLangItem,
|
||||
solve::SizedTraitKind,
|
||||
};
|
||||
use rustc_type_ir::{
|
||||
ConstKind, CoroutineArgs, FloatTy, IntTy, RegionKind, TypeFolder, TypeSuperFoldable,
|
||||
TypeSuperVisitable, TypeVisitor, UintTy, UniverseIndex, inherent::IntoKind,
|
||||
};
|
||||
use rustc_type_ir::{InferCtxtLike, TypeFoldable};
|
||||
|
||||
use crate::lower_nextsolver::{LifetimeElisionKind, TyLoweringContext};
|
||||
use crate::next_solver::infer::InferCtxt;
|
||||
use crate::next_solver::{
|
||||
BoundConst, FxIndexMap, ParamEnv, Placeholder, PlaceholderConst, PlaceholderRegion,
|
||||
};
|
||||
use crate::{
|
||||
db::HirDatabase,
|
||||
lower::{LifetimeElisionKind, TyLoweringContext},
|
||||
method_resolution::{TraitImpls, TyFingerprint},
|
||||
next_solver::{
|
||||
BoundConst, FxIndexMap, ParamEnv, Placeholder, PlaceholderConst, PlaceholderRegion,
|
||||
infer::InferCtxt,
|
||||
},
|
||||
};
|
||||
|
||||
use super::fold::{BoundVarReplacer, FnMutDelegate};
|
||||
use super::{
|
||||
AliasTerm, AliasTy, Binder, BoundRegion, BoundTy, BoundTyKind, BoundVarKind, BoundVarKinds,
|
||||
CanonicalVars, Clause, ClauseKind, Clauses, Const, DbInterner, EarlyBinder, GenericArg,
|
||||
GenericArgs, Predicate, PredicateKind, ProjectionPredicate, Region, SolverContext, SolverDefId,
|
||||
Term, TraitPredicate, TraitRef, Ty, TyKind,
|
||||
Clause, ClauseKind, Clauses, Const, DbInterner, EarlyBinder, GenericArgs, Predicate,
|
||||
PredicateKind, ProjectionPredicate, Region, SolverDefId, Term, TraitPredicate, TraitRef, Ty,
|
||||
TyKind,
|
||||
fold::{BoundVarReplacer, FnMutDelegate},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
@ -510,151 +506,6 @@ pub fn apply_args_to_binder<'db, T: TypeFoldable<DbInterner<'db>>>(
|
|||
b.skip_binder().fold_with(&mut instantiate)
|
||||
}
|
||||
|
||||
pub(crate) fn mini_canonicalize<'db, T: TypeFoldable<DbInterner<'db>>>(
|
||||
mut context: SolverContext<'db>,
|
||||
val: T,
|
||||
) -> Canonical<DbInterner<'db>, T> {
|
||||
let mut canon = MiniCanonicalizer {
|
||||
context: &mut context,
|
||||
db: DebruijnIndex::ZERO,
|
||||
vars: IndexMap::default(),
|
||||
};
|
||||
let canon_val = val.fold_with(&mut canon);
|
||||
let vars = canon.vars;
|
||||
Canonical {
|
||||
value: canon_val,
|
||||
max_universe: UniverseIndex::from_u32(1),
|
||||
variables: CanonicalVars::new_from_iter(
|
||||
context.cx(),
|
||||
vars.iter().enumerate().map(|(idx, (k, _v))| match (*k).kind() {
|
||||
GenericArgKind::Type(ty) => match ty.kind() {
|
||||
TyKind::Int(..) | TyKind::Uint(..) => rustc_type_ir::CanonicalVarKind::Int,
|
||||
TyKind::Float(..) => rustc_type_ir::CanonicalVarKind::Float,
|
||||
_ => rustc_type_ir::CanonicalVarKind::Ty {
|
||||
ui: UniverseIndex::ZERO,
|
||||
sub_root: BoundVar::from_usize(idx),
|
||||
},
|
||||
},
|
||||
GenericArgKind::Lifetime(_) => {
|
||||
rustc_type_ir::CanonicalVarKind::Region(UniverseIndex::ZERO)
|
||||
}
|
||||
GenericArgKind::Const(_) => {
|
||||
rustc_type_ir::CanonicalVarKind::Const(UniverseIndex::ZERO)
|
||||
}
|
||||
}),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
struct MiniCanonicalizer<'a, 'db> {
|
||||
context: &'a mut SolverContext<'db>,
|
||||
db: DebruijnIndex,
|
||||
vars: IndexMap<GenericArg<'db>, usize>,
|
||||
}
|
||||
|
||||
impl<'db> TypeFolder<DbInterner<'db>> for MiniCanonicalizer<'_, 'db> {
|
||||
fn cx(&self) -> DbInterner<'db> {
|
||||
self.context.cx()
|
||||
}
|
||||
|
||||
fn fold_binder<T: TypeFoldable<DbInterner<'db>>>(
|
||||
&mut self,
|
||||
t: rustc_type_ir::Binder<DbInterner<'db>, T>,
|
||||
) -> rustc_type_ir::Binder<DbInterner<'db>, T> {
|
||||
self.db.shift_in(1);
|
||||
let res = t.map_bound(|t| t.fold_with(self));
|
||||
self.db.shift_out(1);
|
||||
res
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'db>) -> Ty<'db> {
|
||||
match t.kind() {
|
||||
rustc_type_ir::TyKind::Bound(db, _) => {
|
||||
if db >= self.db {
|
||||
panic!("Unexpected bound var");
|
||||
}
|
||||
t
|
||||
}
|
||||
rustc_type_ir::TyKind::Infer(infer) => {
|
||||
let t = match infer {
|
||||
rustc_type_ir::InferTy::TyVar(vid) => {
|
||||
self.context.opportunistic_resolve_ty_var(vid)
|
||||
}
|
||||
rustc_type_ir::InferTy::IntVar(vid) => {
|
||||
self.context.opportunistic_resolve_int_var(vid)
|
||||
}
|
||||
rustc_type_ir::InferTy::FloatVar(vid) => {
|
||||
self.context.opportunistic_resolve_float_var(vid)
|
||||
}
|
||||
_ => t,
|
||||
};
|
||||
let len = self.vars.len();
|
||||
let var = *self.vars.entry(t.into()).or_insert(len);
|
||||
Ty::new(
|
||||
self.cx(),
|
||||
TyKind::Bound(
|
||||
self.db,
|
||||
BoundTy { kind: super::BoundTyKind::Anon, var: BoundVar::from_usize(var) },
|
||||
),
|
||||
)
|
||||
}
|
||||
_ => t.super_fold_with(self),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_region(
|
||||
&mut self,
|
||||
r: <DbInterner<'db> as rustc_type_ir::Interner>::Region,
|
||||
) -> <DbInterner<'db> as rustc_type_ir::Interner>::Region {
|
||||
match r.kind() {
|
||||
RegionKind::ReBound(db, _) => {
|
||||
if db >= self.db {
|
||||
panic!("Unexpected bound var");
|
||||
}
|
||||
r
|
||||
}
|
||||
RegionKind::ReVar(_vid) => {
|
||||
let len = self.vars.len();
|
||||
let var = *self.vars.entry(r.into()).or_insert(len);
|
||||
Region::new(
|
||||
self.cx(),
|
||||
RegionKind::ReBound(
|
||||
self.db,
|
||||
BoundRegion {
|
||||
kind: super::BoundRegionKind::Anon,
|
||||
var: BoundVar::from_usize(var),
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
_ => r,
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
c: <DbInterner<'db> as rustc_type_ir::Interner>::Const,
|
||||
) -> <DbInterner<'db> as rustc_type_ir::Interner>::Const {
|
||||
match c.kind() {
|
||||
ConstKind::Bound(db, _) => {
|
||||
if db >= self.db {
|
||||
panic!("Unexpected bound var");
|
||||
}
|
||||
c
|
||||
}
|
||||
ConstKind::Infer(_infer) => {
|
||||
let len = self.vars.len();
|
||||
let var = *self.vars.entry(c.into()).or_insert(len);
|
||||
Const::new(
|
||||
self.cx(),
|
||||
ConstKind::Bound(self.db, BoundConst { var: BoundVar::from_usize(var) }),
|
||||
)
|
||||
}
|
||||
_ => c.super_fold_with(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn explicit_item_bounds<'db>(
|
||||
interner: DbInterner<'db>,
|
||||
def_id: SolverDefId,
|
||||
|
|
@ -713,7 +564,7 @@ pub fn explicit_item_bounds<'db>(
|
|||
match full_id {
|
||||
crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => {
|
||||
let datas = db
|
||||
.return_type_impl_traits_ns(func)
|
||||
.return_type_impl_traits(func)
|
||||
.expect("impl trait id without impl traits");
|
||||
let datas = (*datas).as_ref().skip_binder();
|
||||
let data = &datas.impl_traits[Idx::from_raw(idx.into_raw())];
|
||||
|
|
@ -721,7 +572,7 @@ pub fn explicit_item_bounds<'db>(
|
|||
}
|
||||
crate::ImplTraitId::TypeAliasImplTrait(alias, idx) => {
|
||||
let datas = db
|
||||
.type_alias_impl_traits_ns(alias)
|
||||
.type_alias_impl_traits(alias)
|
||||
.expect("impl trait id without impl traits");
|
||||
let datas = (*datas).as_ref().skip_binder();
|
||||
let data = &datas.impl_traits[Idx::from_raw(idx.into_raw())];
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ fn foo() -> i32 {
|
|||
"body_shim",
|
||||
"body_with_source_map_shim",
|
||||
"trait_environment_shim",
|
||||
"return_type_impl_traits_ns_shim",
|
||||
"return_type_impl_traits_shim",
|
||||
"expr_scopes_shim",
|
||||
"lang_item",
|
||||
"crate_lang_items",
|
||||
|
|
@ -131,7 +131,7 @@ fn baz() -> i32 {
|
|||
"body_shim",
|
||||
"body_with_source_map_shim",
|
||||
"trait_environment_shim",
|
||||
"return_type_impl_traits_ns_shim",
|
||||
"return_type_impl_traits_shim",
|
||||
"expr_scopes_shim",
|
||||
"lang_item",
|
||||
"crate_lang_items",
|
||||
|
|
@ -143,7 +143,7 @@ fn baz() -> i32 {
|
|||
"body_shim",
|
||||
"body_with_source_map_shim",
|
||||
"trait_environment_shim",
|
||||
"return_type_impl_traits_ns_shim",
|
||||
"return_type_impl_traits_shim",
|
||||
"expr_scopes_shim",
|
||||
"infer_shim",
|
||||
"function_signature_shim",
|
||||
|
|
@ -151,7 +151,7 @@ fn baz() -> i32 {
|
|||
"body_shim",
|
||||
"body_with_source_map_shim",
|
||||
"trait_environment_shim",
|
||||
"return_type_impl_traits_ns_shim",
|
||||
"return_type_impl_traits_shim",
|
||||
"expr_scopes_shim",
|
||||
]
|
||||
"#]],
|
||||
|
|
@ -585,8 +585,8 @@ fn main() {
|
|||
"crate_lang_items",
|
||||
"attrs_shim",
|
||||
"attrs_shim",
|
||||
"generic_predicates_ns_shim",
|
||||
"return_type_impl_traits_ns_shim",
|
||||
"generic_predicates_shim",
|
||||
"return_type_impl_traits_shim",
|
||||
"infer_shim",
|
||||
"function_signature_shim",
|
||||
"function_signature_with_source_map_shim",
|
||||
|
|
@ -594,7 +594,7 @@ fn main() {
|
|||
"expr_scopes_shim",
|
||||
"struct_signature_shim",
|
||||
"struct_signature_with_source_map_shim",
|
||||
"generic_predicates_ns_shim",
|
||||
"generic_predicates_shim",
|
||||
"value_ty_shim",
|
||||
"VariantFields::firewall_",
|
||||
"VariantFields::query_",
|
||||
|
|
@ -608,9 +608,9 @@ fn main() {
|
|||
"trait_impls_in_crate_shim",
|
||||
"impl_trait_with_diagnostics_shim",
|
||||
"impl_self_ty_with_diagnostics_shim",
|
||||
"generic_predicates_ns_shim",
|
||||
"generic_predicates_shim",
|
||||
"value_ty_shim",
|
||||
"generic_predicates_ns_shim",
|
||||
"generic_predicates_shim",
|
||||
]
|
||||
"#]],
|
||||
);
|
||||
|
|
@ -682,13 +682,13 @@ fn main() {
|
|||
"attrs_shim",
|
||||
"attrs_shim",
|
||||
"attrs_shim",
|
||||
"generic_predicates_ns_shim",
|
||||
"return_type_impl_traits_ns_shim",
|
||||
"generic_predicates_shim",
|
||||
"return_type_impl_traits_shim",
|
||||
"infer_shim",
|
||||
"function_signature_with_source_map_shim",
|
||||
"expr_scopes_shim",
|
||||
"struct_signature_with_source_map_shim",
|
||||
"generic_predicates_ns_shim",
|
||||
"generic_predicates_shim",
|
||||
"VariantFields::query_",
|
||||
"inherent_impls_in_crate_shim",
|
||||
"impl_signature_with_source_map_shim",
|
||||
|
|
@ -697,8 +697,8 @@ fn main() {
|
|||
"trait_impls_in_crate_shim",
|
||||
"impl_trait_with_diagnostics_shim",
|
||||
"impl_self_ty_with_diagnostics_shim",
|
||||
"generic_predicates_ns_shim",
|
||||
"generic_predicates_ns_shim",
|
||||
"generic_predicates_shim",
|
||||
"generic_predicates_shim",
|
||||
]
|
||||
"#]],
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,155 +0,0 @@
|
|||
//! Implementation of Chalk debug helper functions using TLS.
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
use itertools::Itertools;
|
||||
use span::Edition;
|
||||
|
||||
use crate::{
|
||||
CallableDefId, Interner, ProjectionTyExt, chalk_db, db::HirDatabase, from_assoc_type_id,
|
||||
from_chalk_trait_id, mapping::from_chalk,
|
||||
};
|
||||
use hir_def::{AdtId, ItemContainerId, Lookup, TypeAliasId};
|
||||
|
||||
#[allow(unused)]
|
||||
pub(crate) use unsafe_tls::{set_current_program, with_current_program};
|
||||
|
||||
pub(crate) struct DebugContext<'a>(&'a dyn HirDatabase);
|
||||
|
||||
impl DebugContext<'_> {
|
||||
pub(crate) fn debug_struct_id(
|
||||
&self,
|
||||
id: chalk_db::AdtId,
|
||||
f: &mut fmt::Formatter<'_>,
|
||||
) -> Result<(), fmt::Error> {
|
||||
let name = match id.0 {
|
||||
AdtId::StructId(it) => self.0.struct_signature(it).name.clone(),
|
||||
AdtId::UnionId(it) => self.0.union_signature(it).name.clone(),
|
||||
AdtId::EnumId(it) => self.0.enum_signature(it).name.clone(),
|
||||
};
|
||||
name.display(self.0, Edition::LATEST).fmt(f)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn debug_trait_id(
|
||||
&self,
|
||||
id: chalk_db::TraitId,
|
||||
f: &mut fmt::Formatter<'_>,
|
||||
) -> Result<(), fmt::Error> {
|
||||
let trait_: hir_def::TraitId = from_chalk_trait_id(id);
|
||||
let trait_data = self.0.trait_signature(trait_);
|
||||
trait_data.name.display(self.0, Edition::LATEST).fmt(f)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn debug_assoc_type_id(
|
||||
&self,
|
||||
id: chalk_db::AssocTypeId,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Result<(), fmt::Error> {
|
||||
let type_alias: TypeAliasId = from_assoc_type_id(id);
|
||||
let type_alias_data = self.0.type_alias_signature(type_alias);
|
||||
let trait_ = match type_alias.lookup(self.0).container {
|
||||
ItemContainerId::TraitId(t) => t,
|
||||
_ => panic!("associated type not in trait"),
|
||||
};
|
||||
let trait_data = self.0.trait_signature(trait_);
|
||||
write!(
|
||||
fmt,
|
||||
"{}::{}",
|
||||
trait_data.name.display(self.0, Edition::LATEST),
|
||||
type_alias_data.name.display(self.0, Edition::LATEST)
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn debug_projection_ty(
|
||||
&self,
|
||||
projection_ty: &chalk_ir::ProjectionTy<Interner>,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Result<(), fmt::Error> {
|
||||
let type_alias = from_assoc_type_id(projection_ty.associated_ty_id);
|
||||
let type_alias_data = self.0.type_alias_signature(type_alias);
|
||||
let trait_ = match type_alias.lookup(self.0).container {
|
||||
ItemContainerId::TraitId(t) => t,
|
||||
_ => panic!("associated type not in trait"),
|
||||
};
|
||||
let trait_name = &self.0.trait_signature(trait_).name;
|
||||
let trait_ref = projection_ty.trait_ref(self.0);
|
||||
let trait_params = trait_ref.substitution.as_slice(Interner);
|
||||
let self_ty = trait_ref.self_type_parameter(Interner);
|
||||
write!(fmt, "<{self_ty:?} as {}", trait_name.display(self.0, Edition::LATEST))?;
|
||||
if trait_params.len() > 1 {
|
||||
write!(
|
||||
fmt,
|
||||
"<{}>",
|
||||
trait_params[1..].iter().format_with(", ", |x, f| f(&format_args!("{x:?}"))),
|
||||
)?;
|
||||
}
|
||||
write!(fmt, ">::{}", type_alias_data.name.display(self.0, Edition::LATEST))?;
|
||||
|
||||
let proj_params = &projection_ty.substitution.as_slice(Interner)[trait_params.len()..];
|
||||
if !proj_params.is_empty() {
|
||||
write!(
|
||||
fmt,
|
||||
"<{}>",
|
||||
proj_params.iter().format_with(", ", |x, f| f(&format_args!("{x:?}"))),
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn debug_fn_def_id(
|
||||
&self,
|
||||
fn_def_id: chalk_ir::FnDefId<Interner>,
|
||||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Result<(), fmt::Error> {
|
||||
let def: CallableDefId = from_chalk(self.0, fn_def_id);
|
||||
let name = match def {
|
||||
CallableDefId::FunctionId(ff) => self.0.function_signature(ff).name.clone(),
|
||||
CallableDefId::StructId(s) => self.0.struct_signature(s).name.clone(),
|
||||
CallableDefId::EnumVariantId(e) => {
|
||||
let loc = e.lookup(self.0);
|
||||
loc.parent.enum_variants(self.0).variants[loc.index as usize].1.clone()
|
||||
}
|
||||
};
|
||||
match def {
|
||||
CallableDefId::FunctionId(_) => {
|
||||
write!(fmt, "{{fn {}}}", name.display(self.0, Edition::LATEST))
|
||||
}
|
||||
CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {
|
||||
write!(fmt, "{{ctor {}}}", name.display(self.0, Edition::LATEST))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod unsafe_tls {
|
||||
use super::DebugContext;
|
||||
use crate::db::HirDatabase;
|
||||
use scoped_tls::scoped_thread_local;
|
||||
|
||||
scoped_thread_local!(static PROGRAM: DebugContext<'_>);
|
||||
|
||||
pub(crate) fn with_current_program<R>(
|
||||
op: impl for<'a> FnOnce(Option<&'a DebugContext<'a>>) -> R,
|
||||
) -> R {
|
||||
if PROGRAM.is_set() { PROGRAM.with(|prog| op(Some(prog))) } else { op(None) }
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn set_current_program<OP, R>(p: &dyn HirDatabase, op: OP) -> R
|
||||
where
|
||||
OP: FnOnce() -> R,
|
||||
{
|
||||
let ctx = DebugContext(p);
|
||||
// we're transmuting the lifetime in the DebugContext to static. This is
|
||||
// fine because we only keep the reference for the lifetime of this
|
||||
// function, *and* the only way to access the context is through
|
||||
// `with_current_program`, which hides the lifetime through the `for`
|
||||
// type.
|
||||
let static_p: &DebugContext<'static> =
|
||||
unsafe { std::mem::transmute::<&DebugContext<'_>, &DebugContext<'static>>(&ctx) };
|
||||
PROGRAM.set(static_p, op)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,33 +3,26 @@
|
|||
use core::fmt;
|
||||
use std::hash::Hash;
|
||||
|
||||
use chalk_ir::{DebruijnIndex, GoalData, fold::TypeFoldable};
|
||||
|
||||
use base_db::Crate;
|
||||
use hir_def::{BlockId, TraitId, lang_item::LangItem};
|
||||
use hir_expand::name::Name;
|
||||
use intern::sym;
|
||||
use rustc_next_trait_solver::solve::{HasChanged, SolverDelegateEvalExt};
|
||||
use rustc_type_ir::{
|
||||
InferCtxtLike, TypingMode,
|
||||
inherent::{IntoKind, SliceLike, Span as _},
|
||||
TypingMode,
|
||||
inherent::{IntoKind, Span as _},
|
||||
solve::Certainty,
|
||||
};
|
||||
use span::Edition;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
AliasEq, AliasTy, Canonical, DomainGoal, Goal, InEnvironment, Interner, ProjectionTyExt,
|
||||
TraitRefExt, TyKind, WhereClause,
|
||||
db::HirDatabase,
|
||||
next_solver::{
|
||||
DbInterner, GenericArg, ParamEnv, Predicate, SolverContext, Span,
|
||||
Canonical, DbInterner, GenericArgs, Goal, ParamEnv, Predicate, SolverContext, Span, Ty,
|
||||
TyKind,
|
||||
infer::{DbInternerInferExt, InferCtxt, traits::ObligationCause},
|
||||
mapping::{ChalkToNextSolver, convert_canonical_args_for_result},
|
||||
obligation_ctxt::ObligationCtxt,
|
||||
util::mini_canonicalize,
|
||||
},
|
||||
utils::UnevaluatedConstEvaluatorFolder,
|
||||
};
|
||||
|
||||
/// A set of clauses that we assume to be true. E.g. if we are inside this function:
|
||||
|
|
@ -42,7 +35,7 @@ pub struct TraitEnvironment<'db> {
|
|||
pub krate: Crate,
|
||||
pub block: Option<BlockId>,
|
||||
// FIXME make this a BTreeMap
|
||||
traits_from_clauses: Box<[(crate::next_solver::Ty<'db>, TraitId)]>,
|
||||
traits_from_clauses: Box<[(Ty<'db>, TraitId)]>,
|
||||
pub env: ParamEnv<'db>,
|
||||
}
|
||||
|
||||
|
|
@ -59,7 +52,7 @@ impl<'db> TraitEnvironment<'db> {
|
|||
pub fn new(
|
||||
krate: Crate,
|
||||
block: Option<BlockId>,
|
||||
traits_from_clauses: Box<[(crate::next_solver::Ty<'db>, TraitId)]>,
|
||||
traits_from_clauses: Box<[(Ty<'db>, TraitId)]>,
|
||||
env: ParamEnv<'db>,
|
||||
) -> Arc<Self> {
|
||||
Arc::new(TraitEnvironment { krate, block, traits_from_clauses, env })
|
||||
|
|
@ -70,10 +63,7 @@ impl<'db> TraitEnvironment<'db> {
|
|||
Arc::make_mut(this).block = Some(block);
|
||||
}
|
||||
|
||||
pub fn traits_in_scope_from_clauses(
|
||||
&self,
|
||||
ty: crate::next_solver::Ty<'db>,
|
||||
) -> impl Iterator<Item = TraitId> + '_ {
|
||||
pub fn traits_in_scope_from_clauses(&self, ty: Ty<'db>) -> impl Iterator<Item = TraitId> + '_ {
|
||||
self.traits_from_clauses
|
||||
.iter()
|
||||
.filter_map(move |(self_ty, trait_id)| (*self_ty == ty).then_some(*trait_id))
|
||||
|
|
@ -83,92 +73,19 @@ impl<'db> TraitEnvironment<'db> {
|
|||
/// This should be used in `hir` only.
|
||||
pub fn structurally_normalize_ty<'db>(
|
||||
infcx: &InferCtxt<'db>,
|
||||
ty: crate::next_solver::Ty<'db>,
|
||||
ty: Ty<'db>,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
) -> crate::next_solver::Ty<'db> {
|
||||
let crate::next_solver::TyKind::Alias(..) = ty.kind() else { return ty };
|
||||
) -> Ty<'db> {
|
||||
let TyKind::Alias(..) = ty.kind() else { return ty };
|
||||
let mut ocx = ObligationCtxt::new(infcx);
|
||||
let ty = ocx.structurally_normalize_ty(&ObligationCause::dummy(), env.env, ty).unwrap_or(ty);
|
||||
ty.replace_infer_with_error(infcx.interner)
|
||||
}
|
||||
|
||||
fn identity_subst(
|
||||
binders: chalk_ir::CanonicalVarKinds<Interner>,
|
||||
) -> chalk_ir::Canonical<chalk_ir::Substitution<Interner>> {
|
||||
let identity_subst = chalk_ir::Substitution::from_iter(
|
||||
Interner,
|
||||
binders.iter(Interner).enumerate().map(|(index, c)| {
|
||||
let index_db = chalk_ir::BoundVar::new(DebruijnIndex::INNERMOST, index);
|
||||
match &c.kind {
|
||||
chalk_ir::VariableKind::Ty(_) => {
|
||||
chalk_ir::GenericArgData::Ty(TyKind::BoundVar(index_db).intern(Interner))
|
||||
.intern(Interner)
|
||||
}
|
||||
chalk_ir::VariableKind::Lifetime => chalk_ir::GenericArgData::Lifetime(
|
||||
chalk_ir::LifetimeData::BoundVar(index_db).intern(Interner),
|
||||
)
|
||||
.intern(Interner),
|
||||
chalk_ir::VariableKind::Const(ty) => chalk_ir::GenericArgData::Const(
|
||||
chalk_ir::ConstData {
|
||||
ty: ty.clone(),
|
||||
value: chalk_ir::ConstValue::BoundVar(index_db),
|
||||
}
|
||||
.intern(Interner),
|
||||
)
|
||||
.intern(Interner),
|
||||
}
|
||||
}),
|
||||
);
|
||||
chalk_ir::Canonical { binders, value: identity_subst }
|
||||
}
|
||||
|
||||
fn solve_nextsolver<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
krate: Crate,
|
||||
block: Option<BlockId>,
|
||||
goal: &chalk_ir::UCanonical<chalk_ir::InEnvironment<chalk_ir::Goal<Interner>>>,
|
||||
) -> Result<
|
||||
(HasChanged, Certainty, rustc_type_ir::Canonical<DbInterner<'db>, Vec<GenericArg<'db>>>),
|
||||
rustc_type_ir::solve::NoSolution,
|
||||
> {
|
||||
// FIXME: should use analysis_in_body, but that needs GenericDefId::Block
|
||||
let context = SolverContext(
|
||||
DbInterner::new_with(db, Some(krate), block)
|
||||
.infer_ctxt()
|
||||
.build(TypingMode::non_body_analysis()),
|
||||
);
|
||||
|
||||
match goal.canonical.value.goal.data(Interner) {
|
||||
// FIXME: args here should be...what? not empty
|
||||
GoalData::All(goals) if goals.is_empty(Interner) => {
|
||||
return Ok((HasChanged::No, Certainty::Yes, mini_canonicalize(context, vec![])));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let goal = goal.canonical.to_nextsolver(context.cx());
|
||||
tracing::info!(?goal);
|
||||
|
||||
let (goal, var_values) = context.instantiate_canonical(&goal);
|
||||
tracing::info!(?var_values);
|
||||
|
||||
let res = context.evaluate_root_goal(goal, Span::dummy(), None);
|
||||
|
||||
let vars =
|
||||
var_values.var_values.iter().map(|g| context.0.resolve_vars_if_possible(g)).collect();
|
||||
let canonical_var_values = mini_canonicalize(context, vars);
|
||||
|
||||
let res = res.map(|r| (r.has_changed, r.certainty, canonical_var_values));
|
||||
|
||||
tracing::debug!("solve_nextsolver({:?}) => {:?}", goal, res);
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum NextTraitSolveResult {
|
||||
Certain(chalk_ir::Canonical<chalk_ir::ConstrainedSubst<Interner>>),
|
||||
Uncertain(chalk_ir::Canonical<chalk_ir::Substitution<Interner>>),
|
||||
Certain,
|
||||
Uncertain,
|
||||
NoSolution,
|
||||
}
|
||||
|
||||
|
|
@ -178,75 +95,17 @@ impl NextTraitSolveResult {
|
|||
}
|
||||
|
||||
pub fn certain(&self) -> bool {
|
||||
matches!(self, NextTraitSolveResult::Certain(..))
|
||||
matches!(self, NextTraitSolveResult::Certain)
|
||||
}
|
||||
|
||||
pub fn uncertain(&self) -> bool {
|
||||
matches!(self, NextTraitSolveResult::Uncertain(..))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next_trait_solve(
|
||||
db: &dyn HirDatabase,
|
||||
krate: Crate,
|
||||
block: Option<BlockId>,
|
||||
goal: Canonical<InEnvironment<Goal>>,
|
||||
) -> NextTraitSolveResult {
|
||||
let detail = match &goal.value.goal.data(Interner) {
|
||||
GoalData::DomainGoal(DomainGoal::Holds(WhereClause::Implemented(it))) => {
|
||||
db.trait_signature(it.hir_trait_id()).name.display(db, Edition::LATEST).to_string()
|
||||
}
|
||||
GoalData::DomainGoal(DomainGoal::Holds(WhereClause::AliasEq(_))) => "alias_eq".to_owned(),
|
||||
_ => "??".to_owned(),
|
||||
};
|
||||
let _p = tracing::info_span!("next_trait_solve", ?detail).entered();
|
||||
tracing::info!("next_trait_solve({:?})", goal.value.goal);
|
||||
|
||||
if let GoalData::DomainGoal(DomainGoal::Holds(WhereClause::AliasEq(AliasEq {
|
||||
alias: AliasTy::Projection(projection_ty),
|
||||
..
|
||||
}))) = &goal.value.goal.data(Interner)
|
||||
&& let TyKind::BoundVar(_) = projection_ty.self_type_parameter(db).kind(Interner)
|
||||
{
|
||||
// Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible
|
||||
// FIXME
|
||||
return NextTraitSolveResult::Uncertain(identity_subst(goal.binders.clone()));
|
||||
}
|
||||
|
||||
// Chalk see `UnevaluatedConst` as a unique concrete value, but we see it as an alias for another const. So
|
||||
// we should get rid of it when talking to chalk.
|
||||
let goal = goal
|
||||
.try_fold_with(&mut UnevaluatedConstEvaluatorFolder { db }, DebruijnIndex::INNERMOST)
|
||||
.unwrap();
|
||||
|
||||
// We currently don't deal with universes (I think / hope they're not yet
|
||||
// relevant for our use cases?)
|
||||
let u_canonical = chalk_ir::UCanonical { canonical: goal, universes: 1 };
|
||||
tracing::info!(?u_canonical);
|
||||
|
||||
let next_solver_res = solve_nextsolver(db, krate, block, &u_canonical);
|
||||
|
||||
match next_solver_res {
|
||||
Err(_) => NextTraitSolveResult::NoSolution,
|
||||
Ok((_, Certainty::Yes, args)) => NextTraitSolveResult::Certain(
|
||||
convert_canonical_args_for_result(DbInterner::new_with(db, Some(krate), block), args),
|
||||
),
|
||||
Ok((_, Certainty::Maybe { .. }, args)) => {
|
||||
let subst = convert_canonical_args_for_result(
|
||||
DbInterner::new_with(db, Some(krate), block),
|
||||
args,
|
||||
);
|
||||
NextTraitSolveResult::Uncertain(chalk_ir::Canonical {
|
||||
binders: subst.binders,
|
||||
value: subst.value.subst,
|
||||
})
|
||||
}
|
||||
matches!(self, NextTraitSolveResult::Uncertain)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next_trait_solve_canonical_in_ctxt<'db>(
|
||||
infer_ctxt: &InferCtxt<'db>,
|
||||
goal: crate::next_solver::Canonical<'db, crate::next_solver::Goal<'db, Predicate<'db>>>,
|
||||
goal: Canonical<'db, Goal<'db, Predicate<'db>>>,
|
||||
) -> NextTraitSolveResult {
|
||||
let context = SolverContext(infer_ctxt.clone());
|
||||
|
||||
|
|
@ -257,33 +116,21 @@ pub fn next_trait_solve_canonical_in_ctxt<'db>(
|
|||
|
||||
let res = context.evaluate_root_goal(goal, Span::dummy(), None);
|
||||
|
||||
let vars =
|
||||
var_values.var_values.iter().map(|g| context.0.resolve_vars_if_possible(g)).collect();
|
||||
let canonical_var_values = mini_canonicalize(context, vars);
|
||||
|
||||
let res = res.map(|r| (r.has_changed, r.certainty, canonical_var_values));
|
||||
let res = res.map(|r| (r.has_changed, r.certainty));
|
||||
|
||||
tracing::debug!("solve_nextsolver({:?}) => {:?}", goal, res);
|
||||
|
||||
match res {
|
||||
Err(_) => NextTraitSolveResult::NoSolution,
|
||||
Ok((_, Certainty::Yes, args)) => NextTraitSolveResult::Certain(
|
||||
convert_canonical_args_for_result(infer_ctxt.interner, args),
|
||||
),
|
||||
Ok((_, Certainty::Maybe { .. }, args)) => {
|
||||
let subst = convert_canonical_args_for_result(infer_ctxt.interner, args);
|
||||
NextTraitSolveResult::Uncertain(chalk_ir::Canonical {
|
||||
binders: subst.binders,
|
||||
value: subst.value.subst,
|
||||
})
|
||||
}
|
||||
Ok((_, Certainty::Yes)) => NextTraitSolveResult::Certain,
|
||||
Ok((_, Certainty::Maybe { .. })) => NextTraitSolveResult::Uncertain,
|
||||
}
|
||||
}
|
||||
|
||||
/// Solve a trait goal using next trait solver.
|
||||
pub fn next_trait_solve_in_ctxt<'db, 'a>(
|
||||
infer_ctxt: &'a InferCtxt<'db>,
|
||||
goal: crate::next_solver::Goal<'db, crate::next_solver::Predicate<'db>>,
|
||||
goal: Goal<'db, Predicate<'db>>,
|
||||
) -> Result<(HasChanged, Certainty), rustc_type_ir::solve::NoSolution> {
|
||||
tracing::info!(?goal);
|
||||
|
||||
|
|
@ -377,7 +224,7 @@ impl FnTrait {
|
|||
|
||||
/// This should not be used in `hir-ty`, only in `hir`.
|
||||
pub fn implements_trait_unique<'db>(
|
||||
ty: crate::next_solver::Ty<'db>,
|
||||
ty: Ty<'db>,
|
||||
db: &'db dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
trait_: TraitId,
|
||||
|
|
@ -392,7 +239,7 @@ pub fn implements_trait_unique_with_args<'db>(
|
|||
db: &'db dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
trait_: TraitId,
|
||||
args: crate::next_solver::GenericArgs<'db>,
|
||||
args: GenericArgs<'db>,
|
||||
) -> bool {
|
||||
implements_trait_unique_impl(db, env, trait_, &mut |_| args)
|
||||
}
|
||||
|
|
@ -401,7 +248,7 @@ fn implements_trait_unique_impl<'db>(
|
|||
db: &'db dyn HirDatabase,
|
||||
env: Arc<TraitEnvironment<'db>>,
|
||||
trait_: TraitId,
|
||||
create_args: &mut dyn FnMut(&InferCtxt<'db>) -> crate::next_solver::GenericArgs<'db>,
|
||||
create_args: &mut dyn FnMut(&InferCtxt<'db>) -> GenericArgs<'db>,
|
||||
) -> bool {
|
||||
let interner = DbInterner::new_with(db, Some(env.krate), env.block);
|
||||
// FIXME(next-solver): I believe this should be `PostAnalysis`.
|
||||
|
|
@ -409,7 +256,7 @@ fn implements_trait_unique_impl<'db>(
|
|||
|
||||
let args = create_args(&infcx);
|
||||
let trait_ref = rustc_type_ir::TraitRef::new_from_args(interner, trait_.into(), args);
|
||||
let goal = crate::next_solver::Goal::new(interner, env.env, trait_ref);
|
||||
let goal = Goal::new(interner, env.env, trait_ref);
|
||||
|
||||
let result = crate::traits::next_trait_solve_in_ctxt(&infcx, goal);
|
||||
matches!(result, Ok((_, Certainty::Yes)))
|
||||
|
|
|
|||
|
|
@ -1,40 +1,30 @@
|
|||
//! Helper functions for working with def, which don't need to be a separate
|
||||
//! query, but can't be computed directly from `*Data` (ie, which need a `db`).
|
||||
|
||||
use std::{cell::LazyCell, iter};
|
||||
use std::cell::LazyCell;
|
||||
|
||||
use base_db::{
|
||||
Crate,
|
||||
target::{self, TargetData},
|
||||
};
|
||||
use chalk_ir::{DebruijnIndex, fold::FallibleTypeFolder};
|
||||
use hir_def::{
|
||||
EnumId, EnumVariantId, FunctionId, Lookup, TraitId, TypeAliasId, TypeOrConstParamId,
|
||||
EnumId, EnumVariantId, FunctionId, Lookup, TraitId,
|
||||
db::DefDatabase,
|
||||
hir::generics::WherePredicate,
|
||||
lang_item::LangItem,
|
||||
resolver::{HasResolver, TypeNs},
|
||||
type_ref::{TraitBoundModifier, TypeRef},
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use intern::sym;
|
||||
use rustc_abi::TargetDataLayout;
|
||||
use rustc_hash::FxHashSet;
|
||||
use rustc_type_ir::inherent::{IntoKind, SliceLike};
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use span::Edition;
|
||||
|
||||
use crate::{
|
||||
ChalkTraitId, Const, ConstScalar, Interner, TargetFeatures, TraitRef, TraitRefExt,
|
||||
consteval::unknown_const,
|
||||
TargetFeatures,
|
||||
db::HirDatabase,
|
||||
layout::{Layout, TagEncoding},
|
||||
mir::pad16,
|
||||
next_solver::{
|
||||
DbInterner,
|
||||
mapping::{ChalkToNextSolver, NextSolverToChalk, convert_args_for_result},
|
||||
},
|
||||
to_chalk_trait_id,
|
||||
};
|
||||
|
||||
pub(crate) fn fn_traits(db: &dyn DefDatabase, krate: Crate) -> impl Iterator<Item = TraitId> + '_ {
|
||||
|
|
@ -75,49 +65,6 @@ pub fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> SmallVec<[Trai
|
|||
result
|
||||
}
|
||||
|
||||
/// Given a trait ref (`Self: Trait`), builds all the implied trait refs for
|
||||
/// super traits. The original trait ref will be included. So the difference to
|
||||
/// `all_super_traits` is that we keep track of type parameters; for example if
|
||||
/// we have `Self: Trait<u32, i32>` and `Trait<T, U>: OtherTrait<U>` we'll get
|
||||
/// `Self: OtherTrait<i32>`.
|
||||
pub(super) fn all_super_trait_refs<T>(
|
||||
db: &dyn HirDatabase,
|
||||
trait_ref: TraitRef,
|
||||
cb: impl FnMut(TraitRef) -> Option<T>,
|
||||
) -> Option<T> {
|
||||
let seen = iter::once(trait_ref.trait_id).collect();
|
||||
SuperTraits { db, seen, stack: vec![trait_ref] }.find_map(cb)
|
||||
}
|
||||
|
||||
struct SuperTraits<'a> {
|
||||
db: &'a dyn HirDatabase,
|
||||
stack: Vec<TraitRef>,
|
||||
seen: FxHashSet<ChalkTraitId>,
|
||||
}
|
||||
|
||||
impl SuperTraits<'_> {
|
||||
fn elaborate(&mut self, trait_ref: &TraitRef) {
|
||||
direct_super_trait_refs(self.db, trait_ref, |trait_ref| {
|
||||
if !self.seen.contains(&trait_ref.trait_id) {
|
||||
self.stack.push(trait_ref);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for SuperTraits<'_> {
|
||||
type Item = TraitRef;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if let Some(next) = self.stack.pop() {
|
||||
self.elaborate(&next);
|
||||
Some(next)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn direct_super_traits_cb(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut(TraitId)) {
|
||||
let resolver = LazyCell::new(|| trait_.resolver(db));
|
||||
let (generic_params, store) = db.generic_params_and_store(trait_.into());
|
||||
|
|
@ -148,49 +95,6 @@ fn direct_super_traits_cb(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut(
|
|||
.for_each(cb);
|
||||
}
|
||||
|
||||
fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef, cb: impl FnMut(TraitRef)) {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let generic_params = db.generic_params(trait_ref.hir_trait_id().into());
|
||||
let trait_self = match generic_params.trait_self_param() {
|
||||
Some(p) => TypeOrConstParamId { parent: trait_ref.hir_trait_id().into(), local_id: p },
|
||||
None => return,
|
||||
};
|
||||
let trait_ref_args: crate::next_solver::GenericArgs<'_> =
|
||||
trait_ref.substitution.to_nextsolver(interner);
|
||||
db.generic_predicates_for_param_ns(trait_self.parent, trait_self, None)
|
||||
.iter()
|
||||
.filter_map(|pred| {
|
||||
let pred = pred.kind();
|
||||
// FIXME: how to correctly handle higher-ranked bounds here?
|
||||
let pred = pred.no_bound_vars().expect("FIXME unexpected higher-ranked trait bound");
|
||||
match pred {
|
||||
rustc_type_ir::ClauseKind::Trait(t) => {
|
||||
let t =
|
||||
rustc_type_ir::EarlyBinder::bind(t).instantiate(interner, trait_ref_args);
|
||||
let trait_id = to_chalk_trait_id(t.def_id().0);
|
||||
|
||||
let substitution =
|
||||
convert_args_for_result(interner, t.trait_ref.args.as_slice());
|
||||
let tr = chalk_ir::TraitRef { trait_id, substitution };
|
||||
Some(tr)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
.for_each(cb);
|
||||
}
|
||||
|
||||
pub(super) fn associated_type_by_name_including_super_traits(
|
||||
db: &dyn HirDatabase,
|
||||
trait_ref: TraitRef,
|
||||
name: &Name,
|
||||
) -> Option<(TraitRef, TypeAliasId)> {
|
||||
all_super_trait_refs(db, trait_ref, |t| {
|
||||
let assoc_type = t.hir_trait_id().trait_items(db).associated_type_by_name(name)?;
|
||||
Some((t, assoc_type))
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Unsafety {
|
||||
Safe,
|
||||
|
|
@ -263,41 +167,6 @@ pub fn is_fn_unsafe_to_call(
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct UnevaluatedConstEvaluatorFolder<'a> {
|
||||
pub(crate) db: &'a dyn HirDatabase,
|
||||
}
|
||||
|
||||
impl FallibleTypeFolder<Interner> for UnevaluatedConstEvaluatorFolder<'_> {
|
||||
type Error = ();
|
||||
|
||||
fn as_dyn(&mut self) -> &mut dyn FallibleTypeFolder<Interner, Error = ()> {
|
||||
self
|
||||
}
|
||||
|
||||
fn interner(&self) -> Interner {
|
||||
Interner
|
||||
}
|
||||
|
||||
fn try_fold_const(
|
||||
&mut self,
|
||||
constant: Const,
|
||||
_outer_binder: DebruijnIndex,
|
||||
) -> Result<Const, Self::Error> {
|
||||
if let chalk_ir::ConstValue::Concrete(c) = &constant.data(Interner).value
|
||||
&& let ConstScalar::UnevaluatedConst(id, subst) = &c.interned
|
||||
{
|
||||
let interner = DbInterner::conjure();
|
||||
if let Ok(eval) = self.db.const_eval(*id, subst.to_nextsolver(interner), None) {
|
||||
return Ok(eval.to_chalk(interner));
|
||||
} else {
|
||||
return Ok(unknown_const(constant.data(Interner).ty.to_nextsolver(interner))
|
||||
.to_chalk(interner));
|
||||
}
|
||||
}
|
||||
Ok(constant)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn detect_variant_from_bytes<'a>(
|
||||
layout: &'a Layout,
|
||||
db: &dyn HirDatabase,
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ impl<'db> Context<'db> {
|
|||
GenericDefId::AdtId(adt) => {
|
||||
let db = self.db;
|
||||
let mut add_constraints_from_variant = |variant| {
|
||||
for (_, field) in db.field_types_ns(variant).iter() {
|
||||
for (_, field) in db.field_types(variant).iter() {
|
||||
self.add_constraints_from_ty(
|
||||
field.instantiate_identity(),
|
||||
Variance::Covariant,
|
||||
|
|
|
|||
|
|
@ -484,7 +484,7 @@ impl<'db> HirDisplay<'db> for TypeParam {
|
|||
let param_data = ¶ms[self.id.local_id()];
|
||||
let krate = self.id.parent().krate(f.db).id;
|
||||
let ty = self.ty(f.db).ty;
|
||||
let predicates = f.db.generic_predicates_ns(self.id.parent());
|
||||
let predicates = f.db.generic_predicates(self.id.parent());
|
||||
let predicates = predicates
|
||||
.instantiate_identity()
|
||||
.into_iter()
|
||||
|
|
|
|||
|
|
@ -1271,7 +1271,7 @@ impl<'db> InstantiatedField<'db> {
|
|||
let interner = DbInterner::new_with(db, Some(krate.base()), None);
|
||||
|
||||
let var_id = self.inner.parent.into();
|
||||
let field = db.field_types_ns(var_id)[self.inner.id];
|
||||
let field = db.field_types(var_id)[self.inner.id];
|
||||
let ty = field.instantiate(interner, self.args);
|
||||
TypeNs::new(db, var_id, ty)
|
||||
}
|
||||
|
|
@ -1350,7 +1350,7 @@ impl Field {
|
|||
/// context of the field definition.
|
||||
pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> TypeNs<'db> {
|
||||
let var_id = self.parent.into();
|
||||
let ty = db.field_types_ns(var_id)[self.id].skip_binder();
|
||||
let ty = db.field_types(var_id)[self.id].skip_binder();
|
||||
TypeNs::new(db, var_id, ty)
|
||||
}
|
||||
|
||||
|
|
@ -1368,7 +1368,7 @@ impl Field {
|
|||
};
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let args = generic_args_from_tys(interner, def_id.into(), generics.map(|ty| ty.ty));
|
||||
let ty = db.field_types_ns(var_id)[self.id].instantiate(interner, args);
|
||||
let ty = db.field_types(var_id)[self.id].instantiate(interner, args);
|
||||
Type::new(db, var_id, ty)
|
||||
}
|
||||
|
||||
|
|
@ -3693,7 +3693,7 @@ impl GenericDef {
|
|||
};
|
||||
|
||||
expr_store_diagnostics(db, acc, &source_map);
|
||||
push_ty_diagnostics(db, acc, db.generic_defaults_ns_with_diagnostics(def).1, &source_map);
|
||||
push_ty_diagnostics(db, acc, db.generic_defaults_with_diagnostics(def).1, &source_map);
|
||||
push_ty_diagnostics(
|
||||
db,
|
||||
acc,
|
||||
|
|
@ -4192,7 +4192,7 @@ impl TypeParam {
|
|||
/// parameter, not additional bounds that might be added e.g. by a method if
|
||||
/// the parameter comes from an impl!
|
||||
pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> {
|
||||
db.generic_predicates_for_param_ns(self.id.parent(), self.id.into(), None)
|
||||
db.generic_predicates_for_param(self.id.parent(), self.id.into(), None)
|
||||
.iter()
|
||||
.filter_map(|pred| match &pred.kind().skip_binder() {
|
||||
ClauseKind::Trait(trait_ref) => Some(Trait::from(trait_ref.def_id().0)),
|
||||
|
|
@ -4282,7 +4282,7 @@ impl ConstParam {
|
|||
|
||||
fn generic_arg_from_param(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Option<GenericArg<'_>> {
|
||||
let local_idx = hir_ty::param_idx(db, id)?;
|
||||
let defaults = db.generic_defaults_ns(id.parent);
|
||||
let defaults = db.generic_defaults(id.parent);
|
||||
let ty = defaults.get(local_idx)?;
|
||||
// FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s.
|
||||
Some(ty.instantiate_identity())
|
||||
|
|
@ -4883,7 +4883,7 @@ impl<'db> Type<'db> {
|
|||
if variant_data.fields().is_empty() {
|
||||
vec![]
|
||||
} else {
|
||||
let field_types = self.interner.db().field_types_ns(id);
|
||||
let field_types = self.interner.db().field_types(id);
|
||||
variant_data
|
||||
.fields()
|
||||
.iter()
|
||||
|
|
@ -5216,7 +5216,7 @@ impl<'db> Type<'db> {
|
|||
_ => return Vec::new(),
|
||||
};
|
||||
|
||||
db.field_types_ns(variant_id)
|
||||
db.field_types(variant_id)
|
||||
.iter()
|
||||
.map(|(local_id, ty)| {
|
||||
let def = Field { parent: variant_id.into(), id: local_id };
|
||||
|
|
@ -6450,7 +6450,7 @@ fn generic_args_from_tys<'db>(
|
|||
|
||||
fn has_non_default_type_params(db: &dyn HirDatabase, generic_def: GenericDefId) -> bool {
|
||||
let params = db.generic_params(generic_def);
|
||||
let defaults = db.generic_defaults_ns(generic_def);
|
||||
let defaults = db.generic_defaults(generic_def);
|
||||
params
|
||||
.iter_type_or_consts()
|
||||
.filter(|(_, param)| matches!(param, TypeOrConstParamData::TypeParamData(_)))
|
||||
|
|
|
|||
|
|
@ -712,8 +712,7 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
let variant = self.infer()?.variant_resolution_for_expr_or_pat(expr_id)?;
|
||||
let variant_data = variant.fields(db);
|
||||
let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? };
|
||||
let field_ty =
|
||||
(*db.field_types_ns(variant).get(field.local_id)?).instantiate(interner, subst);
|
||||
let field_ty = (*db.field_types(variant).get(field.local_id)?).instantiate(interner, subst);
|
||||
Some((
|
||||
field.into(),
|
||||
local,
|
||||
|
|
@ -735,8 +734,7 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
let variant_data = variant.fields(db);
|
||||
let field = FieldId { parent: variant, local_id: variant_data.field(&field_name)? };
|
||||
let (adt, subst) = self.infer()?[pat_id.as_pat()?].as_adt()?;
|
||||
let field_ty =
|
||||
(*db.field_types_ns(variant).get(field.local_id)?).instantiate(interner, subst);
|
||||
let field_ty = (*db.field_types(variant).get(field.local_id)?).instantiate(interner, subst);
|
||||
Some((
|
||||
field.into(),
|
||||
Type::new_with_resolver(db, &self.resolver, field_ty),
|
||||
|
|
@ -802,7 +800,7 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
|variant: VariantId, subst: GenericArgs<'db>, container: &mut _| {
|
||||
let fields = variant.fields(db);
|
||||
let field = fields.field(&field_name.as_name())?;
|
||||
let field_types = db.field_types_ns(variant);
|
||||
let field_types = db.field_types(variant);
|
||||
*container = Either::Right(field_types[field].instantiate(interner, subst));
|
||||
let generic_def = match variant {
|
||||
VariantId::EnumVariantId(it) => it.loc(db).parent.into(),
|
||||
|
|
@ -1255,7 +1253,7 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
missing_fields: Vec<LocalFieldId>,
|
||||
) -> Vec<(Field, Type<'db>)> {
|
||||
let interner = DbInterner::new_with(db, None, None);
|
||||
let field_types = db.field_types_ns(variant);
|
||||
let field_types = db.field_types(variant);
|
||||
|
||||
missing_fields
|
||||
.into_iter()
|
||||
|
|
|
|||
|
|
@ -9393,7 +9393,7 @@ fn main(a$0: T) {}
|
|||
*a*
|
||||
|
||||
```rust
|
||||
a: T<T>
|
||||
a: T
|
||||
```
|
||||
|
||||
---
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue