Merge pull request #20738 from jackh726/next-trait-solver-next4

Remove non-ns version of impl_self_ty and impl_trait
This commit is contained in:
Shoyu Vanilla (Flint) 2025-09-25 10:30:54 +00:00 committed by GitHub
commit 84e87d5bba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 97 additions and 127 deletions

View File

@ -378,6 +378,6 @@ impl<'db> TyBuilder<EarlyBinder<'db, crate::next_solver::Ty<'db>>> {
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))
TyBuilder::subst_for_def(db, def, None).with_data(db.impl_self_ty(def))
}
}

View File

@ -16,8 +16,8 @@ use smallvec::SmallVec;
use triomphe::Arc;
use crate::{
Binders, Const, ImplTraitId, ImplTraits, InferenceResult, Substitution, TraitEnvironment,
TraitRef, Ty, TyDefId, ValueTyDefId, chalk_db,
Binders, Const, ImplTraitId, ImplTraits, InferenceResult, Substitution, TraitEnvironment, Ty,
TyDefId, ValueTyDefId, chalk_db,
consteval::ConstEvalError,
drop::DropGlue,
dyn_compatibility::DynCompatibilityViolation,
@ -143,9 +143,12 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
def: ImplId,
) -> (crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>, Diagnostics);
#[salsa::invoke(crate::lower::impl_self_ty_query)]
#[salsa::invoke(crate::lower_nextsolver::impl_self_ty_query)]
#[salsa::transparent]
fn impl_self_ty(&self, def: ImplId) -> Binders<Ty>;
fn impl_self_ty<'db>(
&'db self,
def: ImplId,
) -> crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>;
// FIXME: Make this a non-interned query.
#[salsa::invoke_interned(crate::lower_nextsolver::const_param_ty_with_diagnostics_query)]
@ -169,9 +172,12 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
Diagnostics,
)>;
#[salsa::invoke(crate::lower::impl_trait_query)]
#[salsa::invoke(crate::lower_nextsolver::impl_trait_query)]
#[salsa::transparent]
fn impl_trait(&self, def: ImplId) -> Option<Binders<TraitRef>>;
fn impl_trait<'db>(
&'db self,
def: ImplId,
) -> Option<crate::next_solver::EarlyBinder<'db, crate::next_solver::TraitRef<'db>>>;
#[salsa::invoke(crate::lower_nextsolver::field_types_with_diagnostics_query)]
fn field_types_with_diagnostics<'db>(
@ -325,24 +331,10 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
// next trait solver
#[salsa::invoke(crate::lower_nextsolver::impl_self_ty_query)]
#[salsa::transparent]
fn impl_self_ty_ns<'db>(
&'db self,
def: ImplId,
) -> crate::next_solver::EarlyBinder<'db, crate::next_solver::Ty<'db>>;
#[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::impl_trait_query)]
#[salsa::transparent]
fn impl_trait_ns<'db>(
&'db self,
def: ImplId,
) -> Option<crate::next_solver::EarlyBinder<'db, crate::next_solver::TraitRef<'db>>>;
#[salsa::invoke(crate::lower_nextsolver::field_types_query)]
#[salsa::transparent]
fn field_types_ns<'db>(

View File

@ -1864,7 +1864,9 @@ impl<'db> InferenceContext<'db> {
TypeNs::SelfType(impl_id) => {
let generics = crate::generics::generics(self.db, impl_id.into());
let substs = generics.placeholder_subst(self.db);
let mut ty = self.db.impl_self_ty(impl_id).substitute(Interner, &substs);
let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
let mut ty =
self.db.impl_self_ty(impl_id).instantiate(interner, args).to_chalk(interner);
let Some(remaining_idx) = unresolved else {
drop(ctx);

View File

@ -74,8 +74,11 @@ impl<'db> InferenceContext<'db> {
}
ValueNs::ImplSelf(impl_id) => {
let generics = crate::generics::generics(self.db, impl_id.into());
let interner = DbInterner::new_with(self.db, None, None);
let substs = generics.placeholder_subst(self.db);
let ty = self.db.impl_self_ty(impl_id).substitute(Interner, &substs);
let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
let ty =
self.db.impl_self_ty(impl_id).instantiate(interner, args).to_chalk(interner);
return if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() {
Some(ValuePathResolution::GenericDef(
struct_id.into(),
@ -359,10 +362,13 @@ impl<'db> InferenceContext<'db> {
};
let substs = match container {
ItemContainerId::ImplId(impl_id) => {
let interner = DbInterner::new_with(self.db, None, None);
let impl_substs = TyBuilder::subst_for_def(self.db, impl_id, None)
.fill_with_inference_vars(&mut self.table)
.build();
let impl_self_ty = self.db.impl_self_ty(impl_id).substitute(Interner, &impl_substs);
let args: crate::next_solver::GenericArgs<'_> = impl_substs.to_nextsolver(interner);
let impl_self_ty =
self.db.impl_self_ty(impl_id).instantiate(interner, args).to_chalk(interner);
self.unify(&impl_self_ty, &ty);
impl_substs
}

View File

@ -25,7 +25,7 @@ use chalk_ir::{
use either::Either;
use hir_def::{
AdtId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId,
GenericParamId, ImplId, ItemContainerId, LocalFieldId, Lookup, StaticId, StructId, TypeAliasId,
GenericParamId, ItemContainerId, LocalFieldId, Lookup, StaticId, StructId, TypeAliasId,
TypeOrConstParamId, UnionId, VariantId,
builtin_type::BuiltinType,
expr_store::{ExpressionStore, path::Path},
@ -34,8 +34,8 @@ use hir_def::{
resolver::{HasResolver, LifetimeNs, Resolver, TypeNs},
signatures::{FunctionSignature, TraitFlags},
type_ref::{
ConstRef, LifetimeRefId, LiteralConstRef, PathId, TraitBoundModifier,
TraitRef as HirTraitRef, TypeBound, TypeRef, TypeRefId,
ConstRef, LifetimeRefId, LiteralConstRef, PathId, TraitBoundModifier, TypeBound, TypeRef,
TypeRefId,
},
};
use hir_expand::name::Name;
@ -59,6 +59,10 @@ use crate::{
},
make_binders,
mapping::{from_chalk_trait_id, lt_to_placeholder_idx},
next_solver::{
DbInterner,
mapping::{ChalkToNextSolver, NextSolverToChalk},
},
static_lifetime, to_chalk_trait_id, to_placeholder_idx,
utils::all_super_trait_refs,
variable_kinds_from_iter,
@ -565,14 +569,6 @@ impl<'a> TyLoweringContext<'a> {
Some((ctx.lower_trait_ref_from_resolved_path(resolved, explicit_self_ty, false), ctx))
}
fn lower_trait_ref(
&mut self,
trait_ref: &HirTraitRef,
explicit_self_ty: Ty,
) -> Option<TraitRef> {
self.lower_trait_ref_from_path(trait_ref.path, explicit_self_ty).map(|it| it.0)
}
/// When lowering predicates from parents (impl, traits) for children defs (fns, consts, types), `generics` should
/// contain the `Generics` for the **child**, while `predicate_owner` should contain the `GenericDefId` of the
/// **parent**. This is important so we generate the correct bound var/placeholder.
@ -851,21 +847,21 @@ fn named_associated_type_shorthand_candidates<R>(
})
};
let interner = DbInterner::new_with(db, None, None);
match res {
TypeNs::SelfType(impl_id) => {
// we're _in_ the impl -- the binders get added back later. Correct,
// but it would be nice to make this more explicit
let trait_ref = db.impl_trait(impl_id)?.into_value_and_skipped_binders().0;
let trait_ref = db.impl_trait(impl_id)?;
let impl_id_as_generic_def: GenericDefId = impl_id.into();
if impl_id_as_generic_def != def {
let subst = TyBuilder::subst_for_def(db, impl_id, None)
.fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
.build();
let trait_ref = subst.apply(trait_ref, Interner);
let args: crate::next_solver::GenericArgs<'_> = subst.to_nextsolver(interner);
let trait_ref = trait_ref.instantiate(interner, args).to_chalk(interner);
search(trait_ref)
} else {
search(trait_ref)
search(trait_ref.skip_binder().to_chalk(interner))
}
}
TypeNs::GenericParam(param_id) => {
@ -1335,31 +1331,6 @@ impl ValueTyDefId {
}
}
pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binders<Ty> {
impl_self_ty_with_diagnostics_query(db, impl_id).0
}
pub(crate) fn impl_self_ty_with_diagnostics_query(
db: &dyn HirDatabase,
impl_id: ImplId,
) -> (Binders<Ty>, Diagnostics) {
let impl_data = db.impl_signature(impl_id);
let resolver = impl_id.resolver(db);
let generics = generics(db, impl_id.into());
let mut ctx = TyLoweringContext::new(
db,
&resolver,
&impl_data.store,
impl_id.into(),
LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true },
)
.with_type_param_mode(ParamLoweringMode::Variable);
(
make_binders(db, &generics, ctx.lower_ty(impl_data.self_ty)),
create_diagnostics(ctx.diagnostics),
)
}
pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
const_param_ty_with_diagnostics_query(db, def).0
}
@ -1397,30 +1368,6 @@ pub(crate) fn const_param_ty_cycle_result(
TyKind::Error.intern(Interner)
}
pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
impl_trait_with_diagnostics_query(db, impl_id).map(|it| it.0)
}
pub(crate) fn impl_trait_with_diagnostics_query(
db: &dyn HirDatabase,
impl_id: ImplId,
) -> Option<(Binders<TraitRef>, Diagnostics)> {
let impl_data = db.impl_signature(impl_id);
let resolver = impl_id.resolver(db);
let mut ctx = TyLoweringContext::new(
db,
&resolver,
&impl_data.store,
impl_id.into(),
LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true },
)
.with_type_param_mode(ParamLoweringMode::Variable);
let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
let target_trait = impl_data.target_trait.as_ref()?;
let trait_ref = Binders::new(binders, ctx.lower_trait_ref(target_trait, self_ty)?);
Some((trait_ref, create_diagnostics(ctx.diagnostics)))
}
pub(crate) fn return_type_impl_traits(
db: &dyn HirDatabase,
def: hir_def::FunctionId,

View File

@ -255,8 +255,15 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
// `def` can be either impl itself or item within, and we need impl itself
// now.
let generics = generics.parent_or_self();
let interner = DbInterner::new_with(self.ctx.db, None, None);
let subst = generics.placeholder_subst(self.ctx.db);
self.ctx.db.impl_self_ty(impl_id).substitute(Interner, &subst)
let args: crate::next_solver::GenericArgs<'_> =
subst.to_nextsolver(interner);
self.ctx
.db
.impl_self_ty(impl_id)
.instantiate(interner, args)
.to_chalk(interner)
}
ParamLoweringMode::Variable => TyBuilder::impl_self_ty(self.ctx.db, impl_id)
.fill_with_bound_vars(self.ctx.in_binders, 0)

View File

@ -920,7 +920,7 @@ pub(crate) fn impl_trait_with_diagnostics_query<'db>(
impl_id.into(),
LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true },
);
let self_ty = db.impl_self_ty_ns(impl_id).skip_binder();
let self_ty = db.impl_self_ty(impl_id).skip_binder();
let target_trait = impl_data.target_trait.as_ref()?;
let trait_ref = EarlyBinder::bind(ctx.lower_trait_ref(target_trait, self_ty)?);
Some((trait_ref, create_diagnostics(ctx.diagnostics)))
@ -2024,7 +2024,7 @@ fn named_associated_type_shorthand_candidates<'db, R>(
match res {
TypeNs::SelfType(impl_id) => {
let trait_ref = db.impl_trait_ns(impl_id)?;
let trait_ref = db.impl_trait(impl_id)?;
// FIXME(next-solver): same method in `lower` checks for impl or not
// Is that needed here?

View File

@ -287,7 +287,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
}
}
}
TypeNs::SelfType(impl_id) => self.ctx.db.impl_self_ty_ns(impl_id).skip_binder(),
TypeNs::SelfType(impl_id) => self.ctx.db.impl_self_ty(impl_id).skip_binder(),
TypeNs::AdtSelfType(adt) => {
let args = crate::next_solver::GenericArgs::identity_for_item(
self.ctx.interner,

View File

@ -297,11 +297,12 @@ impl TraitImpls {
continue;
}
let target_trait = match db.impl_trait(impl_id) {
Some(tr) => tr.skip_binders().hir_trait_id(),
Some(tr) => tr.skip_binder().def_id.0,
None => continue,
};
let self_ty = db.impl_self_ty(impl_id);
let self_ty_fp = TyFingerprint::for_trait_impl(self_ty.skip_binders());
let interner = DbInterner::new_with(db, None, None);
let self_ty = db.impl_self_ty(impl_id).instantiate_identity().to_chalk(interner);
let self_ty_fp = TyFingerprint::for_trait_impl(&self_ty);
map.entry(target_trait).or_default().entry(self_ty_fp).or_default().push(impl_id);
}
@ -414,8 +415,8 @@ impl InherentImpls {
continue;
}
let self_ty = db.impl_self_ty(impl_id);
let self_ty = self_ty.skip_binders();
let interner = DbInterner::new_with(db, None, None);
let self_ty = &db.impl_self_ty(impl_id).instantiate_identity().to_chalk(interner);
match is_inherent_impl_coherent(db, def_map, impl_id, self_ty) {
true => {
@ -897,10 +898,13 @@ fn find_matching_impl(
table.run_in_snapshot(|table| {
let impl_substs =
TyBuilder::subst_for_def(db, impl_, None).fill_with_inference_vars(table).build();
let args: crate::next_solver::GenericArgs<'_> =
impl_substs.to_nextsolver(table.interner);
let trait_ref = db
.impl_trait(impl_)
.expect("non-trait method in find_matching_impl")
.substitute(Interner, &impl_substs);
.instantiate(table.interner, args)
.to_chalk(table.interner);
if !table.unify(&trait_ref, &actual_trait_ref) {
return None;
@ -1018,7 +1022,9 @@ pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool {
let local_crate = impl_.lookup(db).container.krate();
let is_local = |tgt_crate| tgt_crate == local_crate;
let trait_ref = impl_trait.substitute(Interner, &substs);
let interner = DbInterner::new_with(db, None, None);
let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
let trait_ref = impl_trait.instantiate(interner, args).to_chalk(interner);
let trait_id = from_chalk_trait_id(trait_ref.trait_id);
if is_local(trait_id.module(db).krate()) {
// trait to be implemented is local
@ -1824,7 +1830,7 @@ fn is_valid_impl_fn_candidate(
let _p = tracing::info_span!("subst_for_def").entered();
let impl_subst = table.infer_ctxt.fresh_args_for_item(impl_id.into());
let expect_self_ty = db
.impl_self_ty_ns(impl_id)
.impl_self_ty(impl_id)
.instantiate(table.interner, &impl_subst)
.to_chalk(table.interner);

View File

@ -432,9 +432,12 @@ impl MirEvalError {
let self_ = match func.lookup(db).container {
ItemContainerId::ImplId(impl_id) => Some({
let generics = crate::generics::generics(db, impl_id.into());
let interner = DbInterner::new_with(db, None, None);
let substs = generics.placeholder_subst(db);
let args: crate::next_solver::GenericArgs<'_> =
substs.to_nextsolver(interner);
db.impl_self_ty(impl_id)
.substitute(Interner, &substs)
.instantiate(interner, args)
.display(db, display_target)
.to_string()
}),

View File

@ -1394,7 +1394,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
self,
impl_id: Self::ImplId,
) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
let trait_ref = self.db().impl_trait_ns(impl_id.0).expect("expected an impl of trait");
let trait_ref = self.db().impl_trait(impl_id.0).expect("expected an impl of trait");
trait_ref.map_bound(|trait_ref| {
let clause: Clause<'_> = trait_ref.upcast(self);
Clauses::new_from_iter(
@ -1633,7 +1633,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
|impls| {
for i in impls.for_trait(trait_) {
use rustc_type_ir::TypeVisitable;
let contains_errors = self.db().impl_trait_ns(i).map_or(false, |b| {
let contains_errors = self.db().impl_trait(i).map_or(false, |b| {
b.skip_binder().visit_with(&mut ContainsTypeErrors).is_break()
});
if contains_errors {
@ -1656,7 +1656,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
for fp in fps {
for i in impls.for_trait_and_self_ty(trait_, *fp) {
use rustc_type_ir::TypeVisitable;
let contains_errors = self.db().impl_trait_ns(i).map_or(false, |b| {
let contains_errors = self.db().impl_trait(i).map_or(false, |b| {
b.skip_binder().visit_with(&mut ContainsTypeErrors).is_break()
});
if contains_errors {
@ -1702,7 +1702,7 @@ impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
impl_id: Self::ImplId,
) -> EarlyBinder<Self, rustc_type_ir::TraitRef<Self>> {
let db = self.db();
db.impl_trait_ns(impl_id.0)
db.impl_trait(impl_id.0)
// ImplIds for impls where the trait ref can't be resolved should never reach trait solving
.expect("invalid impl passed to trait solver")
}

View File

@ -156,16 +156,16 @@ impl<'db> SolverDelegate for SolverContext<'db> {
SolverDefId::TypeAliasId(id) => id,
_ => panic!("Unexpected SolverDefId"),
};
let trait_ref = self
let trait_ = self
.0
.interner
.db()
.impl_trait(impl_id.0)
// ImplIds for impls where the trait ref can't be resolved should never reach solver
.expect("invalid impl passed to next-solver")
.into_value_and_skipped_binders()
.skip_binder()
.def_id
.0;
let trait_ = trait_ref.hir_trait_id();
let trait_data = trait_.trait_items(self.0.interner.db());
let id =
impl_id.0.impl_items(self.0.interner.db()).items.iter().find_map(|item| -> Option<_> {

View File

@ -504,8 +504,10 @@ impl SomeStruct {
"crate_local_def_map",
"trait_impls_in_crate_shim",
"attrs_shim",
"impl_trait_with_diagnostics_shim",
"impl_signature_shim",
"impl_signature_with_source_map_shim",
"impl_self_ty_with_diagnostics_shim",
"struct_signature_shim",
"struct_signature_with_source_map_shim",
"attrs_shim",

View File

@ -2050,7 +2050,7 @@ impl dyn Error + Send {
/// Attempts to downcast the box to a concrete type.
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error + Send>> {
let err: Box<dyn Error> = self;
// ^^^^ expected Box<dyn Error + '?>, got Box<dyn Error + Send + '?>
// ^^^^ expected Box<dyn Error + '?>, got Box<dyn Error + Send + 'static>
// FIXME, type mismatch should not occur
<dyn Error>::downcast(err).map_err(|_| loop {})
//^^^^^^^^^^^^^^^^^^^^^ type: fn downcast<{unknown}>(Box<dyn Error + 'static>) -> Result<Box<{unknown}>, Box<dyn Error + 'static>>

View File

@ -865,10 +865,13 @@ impl Module {
.collect();
if !missing.is_empty() {
let self_ty = db.impl_self_ty(impl_def.id).substitute(
Interner,
&hir_ty::generics::generics(db, impl_def.id.into()).placeholder_subst(db),
);
let interner = DbInterner::new_with(db, None, None);
let args: crate::next_solver::GenericArgs<'_> =
hir_ty::generics::generics(db, impl_def.id.into())
.placeholder_subst(db)
.to_nextsolver(interner);
let self_ty =
db.impl_self_ty(impl_def.id).instantiate(interner, args).to_chalk(interner);
let self_ty = if let TyKind::Alias(AliasTy::Projection(projection)) =
self_ty.kind(Interner)
{
@ -4542,21 +4545,23 @@ impl Impl {
}
pub fn trait_(self, db: &dyn HirDatabase) -> Option<Trait> {
let trait_ref = db.impl_trait_ns(self.id)?;
let trait_ref = db.impl_trait(self.id)?;
let id = trait_ref.skip_binder().def_id;
Some(Trait { id: id.0 })
}
pub fn trait_ref(self, db: &dyn HirDatabase) -> Option<TraitRef<'_>> {
let trait_ref = db.impl_trait_ns(self.id)?.instantiate_identity();
let trait_ref = db.impl_trait(self.id)?.instantiate_identity();
let resolver = self.id.resolver(db);
Some(TraitRef::new_with_resolver(db, &resolver, trait_ref))
}
pub fn self_ty(self, db: &dyn HirDatabase) -> Type<'_> {
let resolver = self.id.resolver(db);
let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
let substs = TyBuilder::placeholder_subst(db, self.id);
let ty = db.impl_self_ty(self.id).substitute(Interner, &substs);
let args: crate::next_solver::GenericArgs<'_> = substs.to_nextsolver(interner);
let ty = db.impl_self_ty(self.id).instantiate(interner, args).to_chalk(interner);
Type::new_with_resolver_inner(db, &resolver, ty)
}

View File

@ -429,18 +429,18 @@ trait Tr<T> {
impl Tr<$0
"#,
expect![[r#"
en Enum Enum
ma makro!() macro_rules! makro
en Enum Enum
ma makro!() macro_rules! makro
md module
sp Self dyn Tr<{unknown}>
st Record Record
st S S
st Tuple Tuple
st Unit Unit
sp Self dyn Tr<{unknown}> + 'static
st Record Record
st S S
st Tuple Tuple
st Unit Unit
tt Tr
tt Trait
un Union Union
bt u32 u32
un Union Union
bt u32 u32
kw crate::
kw self::
"#]],

View File

@ -191,7 +191,7 @@ impl Tr for () {
//^ impl Tr for ()
impl dyn Tr {
}
//^ impl dyn Tr
//^ impl dyn Tr + 'static
static S0: () = 0;
static S1: () = {};