Remove lower::ty in favor of lower_nextsolver::ty

This commit is contained in:
Jack Huey 2025-09-22 23:46:40 -04:00
parent f6cf3035c3
commit 3089d23710
14 changed files with 112 additions and 92 deletions

View file

@ -3,17 +3,20 @@
use chalk_ir::{
AdtId, DebruijnIndex, Scalar,
cast::{Cast, CastTo, Caster},
fold::TypeFoldable,
interner::HasInterner,
};
use hir_def::{GenericDefId, GenericParamId, TraitId, TypeAliasId, builtin_type::BuiltinType};
use smallvec::SmallVec;
use crate::{
Binders, BoundVar, CallableSig, GenericArg, GenericArgData, Interner, ProjectionTy,
Substitution, TraitRef, Ty, TyDefId, TyExt, TyKind, consteval::unknown_const_as_generic,
db::HirDatabase, error_lifetime, generics::generics, infer::unify::InferenceTable, primitive,
to_assoc_type_id, to_chalk_trait_id,
BoundVar, CallableSig, GenericArg, GenericArgData, Interner, ProjectionTy, Substitution,
TraitRef, Ty, TyDefId, TyExt, TyKind,
consteval::unknown_const_as_generic,
db::HirDatabase,
error_lifetime,
generics::generics,
infer::unify::InferenceTable,
next_solver::{DbInterner, EarlyBinder, mapping::ChalkToNextSolver},
primitive, to_assoc_type_id, to_chalk_trait_id,
};
#[derive(Debug, Clone, PartialEq, Eq)]
@ -345,19 +348,20 @@ impl TyBuilder<TypeAliasId> {
}
}
impl<T: HasInterner<Interner = Interner> + TypeFoldable<Interner>> TyBuilder<Binders<T>> {
pub fn build(self) -> T {
impl<'db, T: rustc_type_ir::TypeFoldable<DbInterner<'db>>> TyBuilder<EarlyBinder<'db, T>> {
pub fn build(self, interner: DbInterner<'db>) -> T {
let (b, subst) = self.build_internal();
b.substitute(Interner, &subst)
let args: crate::next_solver::GenericArgs<'db> = subst.to_nextsolver(interner);
b.instantiate(interner, args)
}
}
impl TyBuilder<Binders<Ty>> {
impl<'db> TyBuilder<EarlyBinder<'db, crate::next_solver::Ty<'db>>> {
pub fn def_ty(
db: &dyn HirDatabase,
db: &'db dyn HirDatabase,
def: TyDefId,
parent_subst: Option<Substitution>,
) -> TyBuilder<Binders<Ty>> {
) -> TyBuilder<EarlyBinder<'db, crate::next_solver::Ty<'db>>> {
let poly_ty = db.ty(def);
let id: GenericDefId = match def {
TyDefId::BuiltinType(_) => {
@ -370,7 +374,10 @@ impl TyBuilder<Binders<Ty>> {
TyBuilder::subst_for_def(db, id, parent_subst).with_data(poly_ty)
}
pub fn impl_self_ty(db: &dyn HirDatabase, def: hir_def::ImplId) -> TyBuilder<Binders<Ty>> {
TyBuilder::subst_for_def(db, def, None).with_data(db.impl_self_ty(def))
pub 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_ns(def))
}
}

View file

@ -114,9 +114,12 @@ 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::ty_query)]
#[salsa::invoke(crate::lower_nextsolver::ty_query)]
#[salsa::transparent]
fn ty(&self, def: TyDefId) -> Binders<Ty>;
fn ty<'db>(
&'db self,
def: TyDefId,
) -> crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>;
#[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)]
@ -277,13 +280,6 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
// next trait solver
#[salsa::invoke(crate::lower_nextsolver::ty_query)]
#[salsa::transparent]
fn ty_ns<'db>(
&'db self,
def: TyDefId,
) -> crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>;
/// 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)]

View file

@ -1708,6 +1708,7 @@ impl<'db> InferenceContext<'db> {
LifetimeElisionKind::Infer,
);
let mut path_ctx = ctx.at_path(path, node);
let interner = DbInterner::conjure();
let (resolution, unresolved) = if value_ns {
let Some(res) = path_ctx.resolve_path_in_value_ns(HygieneId::ROOT) else {
return (self.err_ty(), None);
@ -1717,15 +1718,27 @@ impl<'db> InferenceContext<'db> {
ValueNs::EnumVariantId(var) => {
let substs = path_ctx.substs_from_path(var.into(), true, false);
drop(ctx);
let ty = self.db.ty(var.lookup(self.db).parent.into());
let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
let args: crate::next_solver::GenericArgs<'_> =
substs.to_nextsolver(interner);
let ty = self
.db
.ty(var.lookup(self.db).parent.into())
.instantiate(interner, args)
.to_chalk(interner);
let ty = self.insert_type_vars(ty);
return (ty, Some(var.into()));
}
ValueNs::StructId(strukt) => {
let substs = path_ctx.substs_from_path(strukt.into(), true, false);
drop(ctx);
let ty = self.db.ty(strukt.into());
let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
let args: crate::next_solver::GenericArgs<'_> =
substs.to_nextsolver(interner);
let ty = self
.db
.ty(strukt.into())
.instantiate(interner, args)
.to_chalk(interner);
let ty = self.insert_type_vars(ty);
return (ty, Some(strukt.into()));
}
ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
@ -1746,22 +1759,29 @@ impl<'db> InferenceContext<'db> {
TypeNs::AdtId(AdtId::StructId(strukt)) => {
let substs = path_ctx.substs_from_path(strukt.into(), true, false);
drop(ctx);
let ty = self.db.ty(strukt.into());
let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
let ty = self.db.ty(strukt.into()).instantiate(interner, args).to_chalk(interner);
let ty = self.insert_type_vars(ty);
forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
}
TypeNs::AdtId(AdtId::UnionId(u)) => {
let substs = path_ctx.substs_from_path(u.into(), true, false);
drop(ctx);
let ty = self.db.ty(u.into());
let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
let ty = self.db.ty(u.into()).instantiate(interner, args).to_chalk(interner);
let ty = self.insert_type_vars(ty);
forbid_unresolved_segments((ty, Some(u.into())), unresolved)
}
TypeNs::EnumVariantId(var) => {
let substs = path_ctx.substs_from_path(var.into(), true, false);
drop(ctx);
let ty = self.db.ty(var.lookup(self.db).parent.into());
let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
let ty = self
.db
.ty(var.lookup(self.db).parent.into())
.instantiate(interner, args)
.to_chalk(interner);
let ty = self.insert_type_vars(ty);
forbid_unresolved_segments((ty, Some(var.into())), unresolved)
}
TypeNs::SelfType(impl_id) => {
@ -1844,8 +1864,10 @@ impl<'db> InferenceContext<'db> {
};
let substs = path_ctx.substs_from_path_segment(it.into(), true, None, false);
drop(ctx);
let ty = self.db.ty(it.into());
let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
let interner = DbInterner::conjure();
let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
let ty = self.db.ty(it.into()).instantiate(interner, args).to_chalk(interner);
let ty = self.insert_type_vars(ty);
self.resolve_variant_on_alias(ty, unresolved, mod_path)
}

View file

@ -780,7 +780,7 @@ impl<'db> InferenceTable<'db> {
}
pub(crate) fn structurally_resolve_type(&mut self, ty: &Ty) -> Ty {
if let TyKind::Alias(..) = ty.kind(Interner) {
if let TyKind::Alias(chalk_ir::AliasTy::Projection(..)) = ty.kind(Interner) {
self.structurally_normalize_ty(ty)
} else {
self.resolve_vars_with_obligations(ty.to_nextsolver(self.interner))

View file

@ -1,18 +1,17 @@
use base_db::target::TargetData;
use chalk_ir::{AdtId, TyKind};
use either::Either;
use hir_def::db::DefDatabase;
use project_model::{Sysroot, toolchain_info::QueryConfig};
use rustc_hash::FxHashMap;
use rustc_type_ir::inherent::{GenericArgs as _, Ty as _};
use syntax::ToSmolStr;
use test_fixture::WithFixture;
use triomphe::Arc;
use crate::{
Interner, Substitution,
db::HirDatabase,
layout::{Layout, LayoutError},
next_solver::{DbInterner, mapping::ChalkToNextSolver},
next_solver::{AdtDef, DbInterner, GenericArgs, mapping::ChalkToNextSolver},
setup_tracing,
test_db::TestDB,
};
@ -80,18 +79,18 @@ fn eval_goal(
Some(adt_or_type_alias_id)
})
.unwrap();
let goal_ty = match adt_or_type_alias_id {
Either::Left(adt_id) => {
TyKind::Adt(AdtId(adt_id), Substitution::empty(Interner)).intern(Interner)
}
Either::Right(ty_id) => {
db.ty(ty_id.into()).substitute(Interner, &Substitution::empty(Interner))
}
};
salsa::attach(&db, || {
let interner = DbInterner::new_with(&db, None, None);
let goal_ty = match adt_or_type_alias_id {
Either::Left(adt_id) => crate::next_solver::Ty::new_adt(
interner,
AdtDef::new(adt_id, interner),
GenericArgs::identity_for_item(interner, adt_id.into()),
),
Either::Right(ty_id) => db.ty(ty_id.into()).instantiate_identity(),
};
db.layout_of_ty(
goal_ty.to_nextsolver(interner),
goal_ty,
db.trait_environment(match adt_or_type_alias_id {
Either::Left(adt) => hir_def::GenericDefId::AdtId(adt),
Either::Right(ty) => hir_def::GenericDefId::TypeAliasId(ty),

View file

@ -1458,16 +1458,6 @@ fn type_for_enum_variant_constructor(
}
}
#[salsa_macros::tracked(cycle_result = type_for_adt_cycle_result)]
fn type_for_adt_tracked(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
type_for_adt(db, adt)
}
fn type_for_adt_cycle_result(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
let generics = generics(db, adt.into());
make_binders(db, &generics, TyKind::Error.intern(Interner))
}
fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
let generics = generics(db, adt.into());
let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
@ -1547,18 +1537,6 @@ impl ValueTyDefId {
}
}
/// Build the declared type of an item. This depends on the namespace; e.g. for
/// `struct Foo(usize)`, we have two types: The type of the struct itself, and
/// the constructor function `(usize) -> Foo` which lives in the values
/// namespace.
pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> {
match def {
TyDefId::BuiltinType(it) => Binders::empty(Interner, TyBuilder::builtin(it)),
TyDefId::AdtId(it) => type_for_adt_tracked(db, it),
TyDefId::TypeAliasId(it) => db.type_for_type_alias_with_diagnostics(it).0,
}
}
pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Option<Binders<Ty>> {
match def {
ValueTyDefId::FunctionId(it) => Some(type_for_fn(db, it)),

View file

@ -28,6 +28,10 @@ use crate::{
error_lifetime,
generics::{Generics, generics},
lower::{LifetimeElisionKind, named_associated_type_shorthand_candidates},
next_solver::{
DbInterner,
mapping::{ChalkToNextSolver, NextSolverToChalk},
},
static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
utils::associated_type_by_name_including_super_traits,
};
@ -256,7 +260,8 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
}
ParamLoweringMode::Variable => TyBuilder::impl_self_ty(self.ctx.db, impl_id)
.fill_with_bound_vars(self.ctx.in_binders, 0)
.build(),
.build(DbInterner::conjure())
.to_chalk(DbInterner::conjure()),
}
}
TypeNs::AdtSelfType(adt) => {
@ -267,7 +272,9 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
generics.bound_vars_subst(self.ctx.db, self.ctx.in_binders)
}
};
self.ctx.db.ty(adt.into()).substitute(Interner, &substs)
let interner = DbInterner::conjure();
let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
self.ctx.db.ty(adt.into()).instantiate(interner, args).to_chalk(interner)
}
TypeNs::AdtId(it) => self.lower_path_inner(it.into(), infer_args),
@ -537,7 +544,9 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
TyDefId::TypeAliasId(it) => it.into(),
};
let substs = self.substs_from_path_segment(generic_def, infer_args, None, false);
self.ctx.db.ty(typeable).substitute(Interner, &substs)
let interner = DbInterner::conjure();
let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
self.ctx.db.ty(typeable).instantiate(interner, args).to_chalk(interner)
}
/// Collect generic arguments from a path into a `Substs`. See also

View file

@ -1697,8 +1697,10 @@ fn is_valid_impl_method_candidate(
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();
let expected_self_ty = TyBuilder::impl_self_ty(db, impl_id)
.fill_with_inference_vars(table)
.build(DbInterner::conjure())
.to_chalk(DbInterner::conjure());
table.unify(&expected_self_ty, self_ty)
});
if !self_ty_matches {

View file

@ -14,6 +14,7 @@ use hir_expand::name::Name;
use intern::{Symbol, sym};
use stdx::never;
use crate::next_solver::mapping::NextSolverToChalk;
use crate::{
DropGlue,
display::DisplayTarget,
@ -1371,9 +1372,8 @@ impl Evaluator<'_> {
result = (l as i8).cmp(&(r as i8));
}
if let Some(e) = LangItem::Ordering.resolve_enum(self.db, self.crate_id) {
let ty = self.db.ty(e.into());
let r = self
.compute_discriminant(ty.skip_binders().clone(), &[result as i8 as u8])?;
let ty = self.db.ty(e.into()).skip_binder().to_chalk(interner);
let r = self.compute_discriminant(ty.clone(), &[result as i8 as u8])?;
destination.write_from_bytes(self, &r.to_le_bytes()[0..destination.size])?;
Ok(())
} else {

View file

@ -1091,9 +1091,9 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
ItemContainerId::ImplId(it) => it,
_ => panic!("assoc ty value should be in impl"),
};
self.db().ty_ns(id.into())
self.db().ty(id.into())
}
SolverDefId::AdtId(id) => self.db().ty_ns(id.into()),
SolverDefId::AdtId(id) => self.db().ty(id.into()),
// FIXME(next-solver): This uses the types of `query mir_borrowck` in rustc.
//
// We currently always use the type from HIR typeck which ignores regions. This

View file

@ -511,7 +511,6 @@ impl SomeStruct {
"struct_signature_shim",
"struct_signature_with_source_map_shim",
"attrs_shim",
"type_for_adt_tracked",
]
"#]],
);
@ -609,7 +608,6 @@ fn main() {
"trait_impls_in_crate_shim",
"impl_trait_with_diagnostics_shim",
"impl_self_ty_with_diagnostics_shim",
"type_for_adt_tracked",
"impl_trait_with_diagnostics_ns_shim",
"impl_self_ty_with_diagnostics_ns_shim",
"generic_predicates_ns_shim",

View file

@ -2053,7 +2053,7 @@ impl dyn Error + Send {
// ^^^^ expected Box<dyn Error + '?>, got Box<dyn Error + Send + '?>
// FIXME, type mismatch should not occur
<dyn Error>::downcast(err).map_err(|_| loop {})
//^^^^^^^^^^^^^^^^^^^^^ type: fn downcast<{unknown}>(Box<dyn Error + '?>) -> Result<Box<{unknown}>, Box<dyn Error + '?>>
//^^^^^^^^^^^^^^^^^^^^^ type: fn downcast<{unknown}>(Box<dyn Error + 'static>) -> Result<Box<{unknown}>, Box<dyn Error + '?>>
}
}
"#,

View file

@ -1504,7 +1504,7 @@ impl<'db> InstantiatedStruct<'db> {
let krate = self.inner.krate(db);
let interner = DbInterner::new_with(db, Some(krate.base()), None);
let ty = db.ty_ns(self.inner.id.into());
let ty = db.ty(self.inner.id.into());
TypeNs::new(db, self.inner.id, ty.instantiate(interner, self.args))
}
}
@ -1664,7 +1664,7 @@ impl<'db> InstantiatedEnum<'db> {
let krate = self.inner.krate(db);
let interner = DbInterner::new_with(db, Some(krate.base()), None);
let ty = db.ty_ns(self.inner.id.into());
let ty = db.ty(self.inner.id.into());
TypeNs::new(db, self.inner.id, ty.instantiate(interner, self.args))
}
}
@ -1851,7 +1851,8 @@ impl Adt {
ParamKind::Lifetime => error_lifetime().cast(Interner),
}
})
.build();
.build(DbInterner::conjure())
.to_chalk(DbInterner::conjure());
Type::new(db, id, ty)
}
@ -4828,32 +4829,40 @@ impl<'db> Type<'db> {
}
fn from_def(db: &'db dyn HirDatabase, def: impl Into<TyDefId> + HasResolver) -> Self {
let interner = DbInterner::new_with(db, None, None);
let ty = db.ty(def.into());
let substs = TyBuilder::unknown_subst(
db,
match def.into() {
TyDefId::AdtId(it) => GenericDefId::AdtId(it),
TyDefId::TypeAliasId(it) => GenericDefId::TypeAliasId(it),
TyDefId::BuiltinType(_) => return Type::new(db, def, ty.skip_binders().clone()),
TyDefId::BuiltinType(_) => {
return Type::new(db, def, ty.skip_binder().to_chalk(interner));
}
},
);
Type::new(db, def, ty.substitute(Interner, &substs))
let args: hir_ty::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
Type::new(db, def, ty.instantiate(interner, args).to_chalk(interner))
}
fn from_def_placeholders(
db: &'db dyn HirDatabase,
def: impl Into<TyDefId> + HasResolver,
) -> Self {
let interner = DbInterner::new_with(db, None, None);
let ty = db.ty(def.into());
let substs = TyBuilder::placeholder_subst(
db,
match def.into() {
TyDefId::AdtId(it) => GenericDefId::AdtId(it),
TyDefId::TypeAliasId(it) => GenericDefId::TypeAliasId(it),
TyDefId::BuiltinType(_) => return Type::new(db, def, ty.skip_binders().clone()),
TyDefId::BuiltinType(_) => {
return Type::new(db, def, ty.skip_binder().to_chalk(interner));
}
},
);
Type::new(db, def, ty.substitute(Interner, &substs))
let args: hir_ty::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
Type::new(db, def, ty.instantiate(interner, args).to_chalk(interner))
}
fn from_value_def(

View file

@ -94,8 +94,8 @@ pub(crate) fn view_memory_layout(
let def = get_definition(&sema, token)?;
let ty = match def {
Definition::Adt(it) => it.ty(db),
Definition::TypeAlias(it) => it.ty(db),
Definition::Adt(it) => salsa::attach(db, || it.ty(db)),
Definition::TypeAlias(it) => salsa::attach(db, || it.ty(db)),
Definition::BuiltinType(it) => it.ty(db),
Definition::SelfType(it) => it.self_ty(db),
Definition::Local(it) => it.ty(db),