Remove lower::value_ty in favor of lower_nextsolver::value_ty

This commit is contained in:
Jack Huey 2025-09-23 00:26:28 -04:00
parent 3089d23710
commit 73a401301d
8 changed files with 61 additions and 134 deletions

View File

@ -127,8 +127,11 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
/// 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::value_ty_query)]
fn value_ty(&self, def: ValueTyDefId) -> Option<Binders<Ty>>;
#[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::impl_self_ty_with_diagnostics_query)]
#[salsa::cycle(cycle_result = crate::lower::impl_self_ty_with_diagnostics_cycle_result)]
@ -280,14 +283,6 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
// next trait solver
/// 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_ns<'db>(
&'db self,
def: ValueTyDefId,
) -> Option<crate::next_solver::EarlyBinder<'db, crate::next_solver::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)]
fn type_for_type_alias_with_diagnostics_ns<'db>(

View File

@ -23,13 +23,13 @@ use syntax::ast::RangeOp;
use tracing::debug;
use crate::autoderef::overloaded_deref_ty;
use crate::next_solver::ErrorGuaranteed;
use crate::next_solver::infer::DefineOpaqueTypes;
use crate::next_solver::obligation_ctxt::ObligationCtxt;
use crate::next_solver::{DbInterner, ErrorGuaranteed};
use crate::{
Adjust, Adjustment, AdtId, AutoBorrow, Binders, CallableDefId, CallableSig, DeclContext,
DeclOrigin, IncorrectGenericsLenKind, Interner, LifetimeElisionKind, Rawness, Scalar,
Substitution, TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt, TyKind, consteval,
Adjust, Adjustment, AdtId, AutoBorrow, CallableDefId, CallableSig, DeclContext, DeclOrigin,
IncorrectGenericsLenKind, Interner, LifetimeElisionKind, Rawness, Scalar, Substitution,
TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt, TyKind, consteval,
generics::generics,
infer::{
AllowTwoPhase, BreakableKind,
@ -1481,7 +1481,10 @@ impl<'db> InferenceContext<'db> {
self.write_method_resolution(tgt_expr, func, subst.clone());
let method_ty = self.db.value_ty(func.into()).unwrap().substitute(Interner, &subst);
let interner = DbInterner::new_with(self.db, None, None);
let args: crate::next_solver::GenericArgs<'_> = subst.to_nextsolver(interner);
let method_ty =
self.db.value_ty(func.into()).unwrap().instantiate(interner, args).to_chalk(interner);
self.register_obligations_for_call(&method_ty);
self.infer_expr_coerce(rhs, &Expectation::has_type(rhs_ty.clone()), ExprIsRead::Yes);
@ -1800,11 +1803,17 @@ impl<'db> InferenceContext<'db> {
self.write_expr_adj(receiver, adjustments.into_boxed_slice());
self.write_method_resolution(tgt_expr, func, substs.clone());
let interner = DbInterner::new_with(self.db, None, None);
let args: crate::next_solver::GenericArgs<'_> =
substs.to_nextsolver(interner);
self.check_method_call(
tgt_expr,
&[],
self.db.value_ty(func.into()).unwrap(),
substs,
self.db
.value_ty(func.into())
.unwrap()
.instantiate(interner, args)
.to_chalk(interner),
ty,
expected,
)
@ -1963,11 +1972,16 @@ impl<'db> InferenceContext<'db> {
let substs = self.substs_for_method_call(tgt_expr, func.into(), generic_args);
self.write_method_resolution(tgt_expr, func, substs.clone());
let interner = DbInterner::new_with(self.db, None, None);
let gen_args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
self.check_method_call(
tgt_expr,
args,
self.db.value_ty(func.into()).expect("we have a function def"),
substs,
self.db
.value_ty(func.into())
.expect("we have a function def")
.instantiate(interner, gen_args)
.to_chalk(interner),
ty,
expected,
)
@ -2012,11 +2026,15 @@ impl<'db> InferenceContext<'db> {
let recovered = match assoc_func_with_same_name {
Some(f) => {
let substs = self.substs_for_method_call(tgt_expr, f.into(), generic_args);
let interner = DbInterner::new_with(self.db, None, None);
let args: crate::next_solver::GenericArgs<'_> =
substs.to_nextsolver(interner);
let f = self
.db
.value_ty(f.into())
.expect("we have a function def")
.substitute(Interner, &substs);
.instantiate(interner, args)
.to_chalk(interner);
let sig = f.callable_sig(self.db).expect("we have a function def");
Some((f, sig, true))
}
@ -2056,12 +2074,10 @@ impl<'db> InferenceContext<'db> {
&mut self,
tgt_expr: ExprId,
args: &[ExprId],
method_ty: Binders<Ty>,
substs: Substitution,
method_ty: Ty,
receiver_ty: Ty,
expected: &Expectation,
) -> Ty {
let method_ty = method_ty.substitute(Interner, &substs);
self.register_obligations_for_call(&method_ty);
let interner = self.table.interner;
let ((formal_receiver_ty, param_tys), ret_ty, is_varargs) =

View File

@ -17,7 +17,10 @@ use crate::{
generics::generics,
infer::diagnostics::InferenceTyLoweringContext as TyLoweringContext,
method_resolution::{self, VisibleFromModule},
next_solver::mapping::ChalkToNextSolver,
next_solver::{
DbInterner,
mapping::{ChalkToNextSolver, NextSolverToChalk},
},
to_chalk_trait_id,
};
@ -36,7 +39,9 @@ impl<'db> InferenceContext<'db> {
self.add_required_obligations_for_value_path(generic_def, &substs);
let ty = self.db.value_ty(value_def)?.substitute(Interner, &substs);
let interner = DbInterner::new_with(self.db, None, None);
let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
let ty = self.db.value_ty(value_def)?.instantiate(interner, args).to_chalk(interner);
let ty = self.process_remote_user_written_ty(ty);
Some(ty)
}
@ -89,9 +94,9 @@ impl<'db> InferenceContext<'db> {
let generic_def = value_def.to_generic_def_id(self.db);
if let GenericDefId::StaticId(_) = generic_def {
let interner = DbInterner::new_with(self.db, None, None);
// `Static` is the kind of item that can never be generic currently. We can just skip the binders to get its type.
let (ty, binders) = self.db.value_ty(value_def)?.into_value_and_skipped_binders();
stdx::always!(binders.is_empty(Interner), "non-empty binders for non-generic def",);
let ty = self.db.value_ty(value_def)?.skip_binder().to_chalk(interner);
return Some(ValuePathResolution::NonGeneric(ty));
};

View File

@ -30,7 +30,6 @@ use hir_def::{
builtin_type::BuiltinType,
expr_store::{ExpressionStore, path::Path},
hir::generics::{GenericParamDataRef, TypeOrConstParamData, WherePredicate},
item_tree::FieldsShape,
lang_item::LangItem,
resolver::{HasResolver, LifetimeNs, Resolver, TypeNs},
signatures::{FunctionSignature, TraitFlags, TypeAliasFlags},
@ -59,7 +58,7 @@ use crate::{
path::{PathDiagnosticCallback, PathLoweringContext},
},
make_binders,
mapping::{ToChalk, from_chalk_trait_id, lt_to_placeholder_idx},
mapping::{from_chalk_trait_id, lt_to_placeholder_idx},
static_lifetime, to_chalk_trait_id, to_placeholder_idx,
utils::all_super_trait_refs,
variable_kinds_from_iter,
@ -1352,51 +1351,6 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
make_binders(db, &generics, sig)
}
/// Build the declared type of a function. This should not need to look at the
/// function body.
fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
let generics = generics(db, def.into());
let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
make_binders(
db,
&generics,
TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(Interner),
)
}
/// Build the declared type of a const.
fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
let data = db.const_signature(def);
let generics = generics(db, def.into());
let resolver = def.resolver(db);
let parent = def.loc(db).container;
let mut ctx = TyLoweringContext::new(
db,
&resolver,
&data.store,
def.into(),
LifetimeElisionKind::for_const(parent),
)
.with_type_param_mode(ParamLoweringMode::Variable);
make_binders(db, &generics, ctx.lower_ty(data.type_ref))
}
/// Build the declared type of a static.
fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
let data = db.static_signature(def);
let resolver = def.resolver(db);
let mut ctx = TyLoweringContext::new(
db,
&resolver,
&data.store,
def.into(),
LifetimeElisionKind::Elided(static_lifetime()),
);
Binders::empty(Interner, ctx.lower_ty(data.type_ref))
}
fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig {
let field_tys = db.field_types(def.into());
let params = field_tys.iter().map(|(_, ty)| ty.skip_binders().clone());
@ -1407,24 +1361,6 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
)
}
/// Build the type of a tuple struct constructor.
fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Option<Binders<Ty>> {
let struct_data = def.fields(db);
match struct_data.shape {
FieldsShape::Record => None,
FieldsShape::Unit => Some(type_for_adt(db, def.into())),
FieldsShape::Tuple => {
let generics = generics(db, AdtId::from(def).into());
let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
Some(make_binders(
db,
&generics,
TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
))
}
}
}
fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
let field_tys = db.field_types(def.into());
let params = field_tys.iter().map(|(_, ty)| ty.skip_binders().clone());
@ -1436,28 +1372,6 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
)
}
/// Build the type of a tuple enum variant constructor.
fn type_for_enum_variant_constructor(
db: &dyn HirDatabase,
def: EnumVariantId,
) -> Option<Binders<Ty>> {
let e = def.lookup(db).parent;
match def.fields(db).shape {
FieldsShape::Record => None,
FieldsShape::Unit => Some(type_for_adt(db, e.into())),
FieldsShape::Tuple => {
let generics = generics(db, e.into());
let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
Some(make_binders(
db,
&generics,
TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs)
.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);
@ -1537,17 +1451,6 @@ impl ValueTyDefId {
}
}
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)),
ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
ValueTyDefId::UnionId(it) => Some(type_for_adt(db, it.into())),
ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it),
ValueTyDefId::ConstId(it) => Some(type_for_const(db, it)),
ValueTyDefId::StaticId(it) => Some(type_for_static(db, it)),
}
}
pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binders<Ty> {
db.impl_self_ty_with_diagnostics(impl_id).0
}

View File

@ -1099,15 +1099,13 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
// We currently always use the type from HIR typeck which ignores regions. This
// should be fine.
SolverDefId::InternedOpaqueTyId(_) => self.type_of_opaque_hir_typeck(def_id),
SolverDefId::FunctionId(id) => self.db.value_ty_ns(id.into()).unwrap(),
SolverDefId::FunctionId(id) => self.db.value_ty(id.into()).unwrap(),
SolverDefId::Ctor(id) => {
let id = match id {
Ctor::Struct(id) => id.into(),
Ctor::Enum(id) => id.into(),
};
self.db
.value_ty_ns(id)
.expect("`SolverDefId::Ctor` should have a function-like ctor")
self.db.value_ty(id).expect("`SolverDefId::Ctor` should have a function-like ctor")
}
_ => panic!("Unexpected def_id `{def_id:?}` provided for `type_of`"),
}

View File

@ -4872,6 +4872,7 @@ impl<'db> Type<'db> {
let Some(ty) = db.value_ty(def.into()) else {
return Type::new(db, def, TyKind::Error.intern(Interner));
};
let interner = DbInterner::new_with(db, None, None);
let substs = TyBuilder::unknown_subst(
db,
match def.into() {
@ -4882,10 +4883,13 @@ impl<'db> Type<'db> {
ValueTyDefId::EnumVariantId(it) => {
GenericDefId::AdtId(AdtId::EnumId(it.lookup(db).parent))
}
ValueTyDefId::StaticId(_) => return Type::new(db, def, ty.skip_binders().clone()),
ValueTyDefId::StaticId(_) => {
return Type::new(db, def, ty.skip_binder().to_chalk(interner));
}
},
);
Type::new(db, def, ty.substitute(Interner, &substs))
let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
Type::new(db, def, ty.instantiate(interner, args).to_chalk(interner))
}
pub fn new_slice(ty: Self) -> Self {

View File

@ -46,6 +46,10 @@ use hir_ty::{
from_assoc_type_id,
lang_items::lang_items_for_bin_op,
method_resolution,
next_solver::{
DbInterner,
mapping::{ChalkToNextSolver, NextSolverToChalk},
},
};
use intern::sym;
use itertools::Itertools;
@ -372,8 +376,10 @@ impl<'db> SourceAnalyzer<'db> {
) -> Option<Callable<'db>> {
let expr_id = self.expr_id(call.clone().into())?.as_expr()?;
let (func, substs) = self.infer()?.method_resolution(expr_id)?;
let ty = db.value_ty(func.into())?.substitute(Interner, &substs);
let ty = Type::new_with_resolver(db, &self.resolver, ty);
let interner = DbInterner::new_with(db, None, None);
let args: hir_ty::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
let ty = db.value_ty(func.into())?.instantiate(interner, args);
let ty = Type::new_with_resolver(db, &self.resolver, ty.to_chalk(interner));
let mut res = ty.as_callable(db)?;
res.is_bound_method = true;
Some(res)

View File

@ -473,7 +473,7 @@ mod tests {
frange.range,
"selection is not an expression(yet contained in one)"
);
let name = NameGenerator::default().for_variable(&expr, &sema);
let name = salsa::attach(sema.db, || NameGenerator::default().for_variable(&expr, &sema));
assert_eq!(&name, expected);
}