Skip to content

Commit 41611b1

Browse files
Make sense of the mess that were (are) different kind of generics in the solver
To the extent possible. Previously they were confused. Sometimes generic params were treated as `Param` and sometimes as `Placeholder`. A completely redundant (in the new solver) mapping of salsa::Id to ints to intern some info where we could just store it uninterned (not in Chalk though, for some weird reason). Plus fix a cute bug in closure substitution that was caught by the assertions of Chalk but the next solver did not have such assertions. Do we need more assertions?
1 parent 21614ed commit 41611b1

26 files changed

+324
-233
lines changed

crates/hir-ty/src/chalk_ext.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ impl TyExt for Ty {
306306
predicates.map(|it| it.into_value_and_skipped_binders().0)
307307
}
308308
TyKind::Placeholder(idx) => {
309-
let id = from_placeholder_idx(db, *idx);
309+
let id = from_placeholder_idx(db, *idx).0;
310310
let generic_params = db.generic_params(id.parent);
311311
let param_data = &generic_params[id.local_id];
312312
match param_data {

crates/hir-ty/src/consteval.rs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -107,25 +107,24 @@ pub(crate) fn path_to_const<'g>(
107107
match resolver.resolve_path_in_value_ns_fully(db, path, HygieneId::ROOT) {
108108
Some(ValueNs::GenericParam(p)) => {
109109
let ty = db.const_param_ty(p);
110+
let args = args();
110111
let value = match mode {
111112
ParamLoweringMode::Placeholder => {
112-
ConstValue::Placeholder(to_placeholder_idx(db, p.into()))
113+
let idx = args.type_or_const_param_idx(p.into()).unwrap();
114+
ConstValue::Placeholder(to_placeholder_idx(db, p.into(), idx as u32))
113115
}
114-
ParamLoweringMode::Variable => {
115-
let args = args();
116-
match args.type_or_const_param_idx(p.into()) {
117-
Some(it) => ConstValue::BoundVar(BoundVar::new(debruijn, it)),
118-
None => {
119-
never!(
120-
"Generic list doesn't contain this param: {:?}, {:?}, {:?}",
121-
args,
122-
path,
123-
p
124-
);
125-
return None;
126-
}
116+
ParamLoweringMode::Variable => match args.type_or_const_param_idx(p.into()) {
117+
Some(it) => ConstValue::BoundVar(BoundVar::new(debruijn, it)),
118+
None => {
119+
never!(
120+
"Generic list doesn't contain this param: {:?}, {:?}, {:?}",
121+
args,
122+
path,
123+
p
124+
);
125+
return None;
127126
}
128-
}
127+
},
129128
};
130129
Some(ConstData { ty, value }.intern(Interner))
131130
}

crates/hir-ty/src/consteval_nextsolver.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub(crate) fn path_to_const<'a, 'g>(
4949
.and_then(|(idx, p)| p.const_param().map(|p| (idx, p.clone())))
5050
{
5151
Some((idx, _param)) => {
52-
Some(Const::new_param(interner, ParamConst { index: idx as u32 }))
52+
Some(Const::new_param(interner, ParamConst { index: idx as u32, id: p }))
5353
}
5454
None => {
5555
never!(

crates/hir-ty/src/db.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,13 +410,15 @@ fn hir_database_is_dyn_compatible() {
410410
#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
411411
#[derive(PartialOrd, Ord)]
412412
pub struct InternedTypeOrConstParamId {
413-
pub loc: TypeOrConstParamId,
413+
/// This stores the param and its index.
414+
pub loc: (TypeOrConstParamId, u32),
414415
}
415416

416417
#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
417418
#[derive(PartialOrd, Ord)]
418419
pub struct InternedLifetimeParamId {
419-
pub loc: LifetimeParamId,
420+
/// This stores the param and its index.
421+
pub loc: (LifetimeParamId, u32),
420422
}
421423

422424
#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]

crates/hir-ty/src/display.rs

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,8 @@ use crate::{
6161
next_solver::{
6262
BoundExistentialPredicate, Ctor, DbInterner, GenericArgs, SolverDefId,
6363
mapping::{
64-
ChalkToNextSolver, bound_var_to_lifetime_idx, bound_var_to_type_or_const_param_idx,
65-
convert_args_for_result, convert_const_for_result, convert_region_for_result,
66-
convert_ty_for_result,
64+
ChalkToNextSolver, convert_args_for_result, convert_const_for_result,
65+
convert_region_for_result, convert_ty_for_result,
6766
},
6867
},
6968
primitive, to_assoc_type_id,
@@ -641,7 +640,7 @@ impl HirDisplay for ProjectionTy {
641640
&& !f.bounds_formatting_ctx.contains(self)
642641
{
643642
let db = f.db;
644-
let id = from_placeholder_idx(db, *idx);
643+
let id = from_placeholder_idx(db, *idx).0;
645644
let generics = generics(db, id.parent);
646645

647646
let substs = generics.placeholder_subst(db);
@@ -736,14 +735,14 @@ impl HirDisplay for Const {
736735
impl<'db> HirDisplay for crate::next_solver::Const<'db> {
737736
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
738737
match self.kind() {
738+
rustc_type_ir::ConstKind::Placeholder(_) => write!(f, "<placeholder>"),
739739
rustc_type_ir::ConstKind::Bound(db, bound_const) => {
740740
write!(f, "?{}.{}", db.as_u32(), bound_const.as_u32())
741741
}
742742
rustc_type_ir::ConstKind::Infer(..) => write!(f, "#c#"),
743-
rustc_type_ir::ConstKind::Placeholder(idx) => {
744-
let id = bound_var_to_type_or_const_param_idx(f.db, idx.bound);
745-
let generics = generics(f.db, id.parent);
746-
let param_data = &generics[id.local_id];
743+
rustc_type_ir::ConstKind::Param(param) => {
744+
let generics = generics(f.db, param.id.parent());
745+
let param_data = &generics[param.id.local_id()];
747746
write!(f, "{}", param_data.name().unwrap().display(f.db, f.edition()))?;
748747
Ok(())
749748
}
@@ -765,7 +764,6 @@ impl<'db> HirDisplay for crate::next_solver::Const<'db> {
765764
}
766765
rustc_type_ir::ConstKind::Error(..) => f.write_char('_'),
767766
rustc_type_ir::ConstKind::Expr(..) => write!(f, "<const-expr>"),
768-
rustc_type_ir::ConstKind::Param(_) => write!(f, "<param>"),
769767
}
770768
}
771769
}
@@ -1178,7 +1176,7 @@ impl<'db> HirDisplay for crate::next_solver::Ty<'db> {
11781176
if let TyKind::Ref(l, _, _) = kind {
11791177
f.write_char('&')?;
11801178
if f.render_region(l) {
1181-
convert_region_for_result(l).hir_fmt(f)?;
1179+
convert_region_for_result(interner, l).hir_fmt(f)?;
11821180
f.write_char(' ')?;
11831181
}
11841182
match m {
@@ -1611,14 +1609,10 @@ impl<'db> HirDisplay for crate::next_solver::Ty<'db> {
16111609
write!(f, "{{closure}}")?;
16121610
}
16131611
}
1614-
TyKind::Placeholder(idx) => {
1615-
let placeholder_index = chalk_ir::PlaceholderIndex {
1616-
idx: idx.bound.var.as_usize(),
1617-
ui: chalk_ir::UniverseIndex { counter: idx.universe.as_usize() },
1618-
};
1619-
let id = from_placeholder_idx(db, placeholder_index);
1620-
let generics = generics(db, id.parent);
1621-
let param_data = &generics[id.local_id];
1612+
TyKind::Placeholder(_) => write!(f, "{{placeholder}}")?,
1613+
TyKind::Param(param) => {
1614+
let generics = generics(db, param.id.parent());
1615+
let param_data = &generics[param.id.local_id()];
16221616
match param_data {
16231617
TypeOrConstParamData::TypeParamData(p) => match p.provenance {
16241618
TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => {
@@ -1634,7 +1628,7 @@ impl<'db> HirDisplay for crate::next_solver::Ty<'db> {
16341628
TypeParamProvenance::ArgumentImplTrait => {
16351629
let substs = generics.placeholder_subst(db);
16361630
let bounds = db
1637-
.generic_predicates(id.parent)
1631+
.generic_predicates(param.id.parent())
16381632
.iter()
16391633
.map(|pred| pred.clone().substitute(Interner, &substs))
16401634
.filter(|wc| match wc.skip_binders() {
@@ -1656,7 +1650,7 @@ impl<'db> HirDisplay for crate::next_solver::Ty<'db> {
16561650
WhereClause::LifetimeOutlives(_) => false,
16571651
})
16581652
.collect::<Vec<_>>();
1659-
let krate = id.parent.module(db).krate();
1653+
let krate = param.id.parent().module(db).krate();
16601654
write_bounds_like_dyn_trait_with_prefix(
16611655
f,
16621656
"impl",
@@ -1671,7 +1665,6 @@ impl<'db> HirDisplay for crate::next_solver::Ty<'db> {
16711665
}
16721666
}
16731667
}
1674-
TyKind::Param(_) => write!(f, "{{param}}")?,
16751668
TyKind::Bound(debruijn_index, ty) => {
16761669
let idx = chalk_ir::BoundVar {
16771670
debruijn: chalk_ir::DebruijnIndex::new(debruijn_index.as_u32()),
@@ -2294,7 +2287,7 @@ impl HirDisplay for LifetimeData {
22942287
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
22952288
match self {
22962289
LifetimeData::Placeholder(idx) => {
2297-
let id = lt_from_placeholder_idx(f.db, *idx);
2290+
let id = lt_from_placeholder_idx(f.db, *idx).0;
22982291
let generics = generics(f.db, id.parent);
22992292
let param_data = &generics[id.local_id];
23002293
write!(f, "{}", param_data.name.display(f.db, f.edition()))?;
@@ -2319,10 +2312,9 @@ impl HirDisplay for LifetimeData {
23192312
impl<'db> HirDisplay for crate::next_solver::Region<'db> {
23202313
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
23212314
match self.kind() {
2322-
rustc_type_ir::RegionKind::RePlaceholder(idx) => {
2323-
let id = bound_var_to_lifetime_idx(f.db, idx.bound.var);
2324-
let generics = generics(f.db, id.parent);
2325-
let param_data = &generics[id.local_id];
2315+
rustc_type_ir::RegionKind::ReEarlyParam(param) => {
2316+
let generics = generics(f.db, param.id.parent);
2317+
let param_data = &generics[param.id.local_id];
23262318
write!(f, "{}", param_data.name.display(f.db, f.edition()))?;
23272319
Ok(())
23282320
}
@@ -2339,7 +2331,7 @@ impl<'db> HirDisplay for crate::next_solver::Region<'db> {
23392331
}
23402332
}
23412333
rustc_type_ir::RegionKind::ReErased => write!(f, "'<erased>"),
2342-
rustc_type_ir::RegionKind::ReEarlyParam(_) => write!(f, "<param>"),
2334+
rustc_type_ir::RegionKind::RePlaceholder(_) => write!(f, "<placeholder>"),
23432335
rustc_type_ir::RegionKind::ReLateParam(_) => write!(f, "<late-param>"),
23442336
}
23452337
}

crates/hir-ty/src/dyn_compatibility.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
33
use std::ops::ControlFlow;
44

5+
use hir_def::hir::generics::LocalTypeOrConstParamId;
56
use hir_def::{
67
AssocItemId, ConstId, CrateRootModuleId, FunctionId, GenericDefId, HasModule, TraitId,
78
TypeAliasId, lang_item::LangItem, signatures::TraitFlags,
89
};
10+
use hir_def::{TypeOrConstParamId, TypeParamId};
911
use intern::Symbol;
1012
use rustc_hash::FxHashSet;
1113
use rustc_type_ir::{
@@ -384,19 +386,15 @@ where
384386
}
385387

386388
// Allow `impl AutoTrait` predicates
387-
let interner = DbInterner::new_with(db, Some(trait_.krate(db)), None);
388389
if let ClauseKind::Trait(TraitPredicate {
389390
trait_ref: pred_trait_ref,
390391
polarity: PredicatePolarity::Positive,
391392
}) = pred
392393
&& let SolverDefId::TraitId(trait_id) = pred_trait_ref.def_id
393394
&& let trait_data = db.trait_signature(trait_id)
394395
&& trait_data.flags.contains(TraitFlags::AUTO)
395-
&& pred_trait_ref.self_ty()
396-
== crate::next_solver::Ty::new(
397-
interner,
398-
rustc_type_ir::TyKind::Param(crate::next_solver::ParamTy { index: 0 }),
399-
)
396+
&& let rustc_type_ir::TyKind::Param(crate::next_solver::ParamTy { index: 0, .. }) =
397+
pred_trait_ref.self_ty().kind()
400398
{
401399
continue;
402400
}
@@ -422,9 +420,13 @@ fn receiver_is_dispatchable<'db>(
422420
let sig = sig.instantiate_identity();
423421

424422
let interner: DbInterner<'_> = DbInterner::new_with(db, Some(trait_.krate(db)), None);
423+
let self_param_id = TypeParamId::from_unchecked(TypeOrConstParamId {
424+
parent: trait_.into(),
425+
local_id: LocalTypeOrConstParamId::from_raw(la_arena::RawIdx::from_u32(0)),
426+
});
425427
let self_param_ty = crate::next_solver::Ty::new(
426428
interner,
427-
rustc_type_ir::TyKind::Param(crate::next_solver::ParamTy { index: 0 }),
429+
rustc_type_ir::TyKind::Param(crate::next_solver::ParamTy { index: 0, id: self_param_id }),
428430
);
429431

430432
// `self: Self` can't be dispatched on, but this is already considered dyn-compatible
@@ -452,7 +454,9 @@ fn receiver_is_dispatchable<'db>(
452454
};
453455

454456
// Type `U`
455-
let unsized_self_ty = crate::next_solver::Ty::new_param(interner, u32::MAX, Symbol::empty());
457+
// FIXME: That seems problematic to fake a generic param like that?
458+
let unsized_self_ty =
459+
crate::next_solver::Ty::new_param(interner, self_param_id, u32::MAX, Symbol::empty());
456460
// `Receiver[Self => U]`
457461
let unsized_receiver_ty = receiver_for_self_ty(interner, func, receiver_ty, unsized_self_ty);
458462

crates/hir-ty/src/generics.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,15 +256,15 @@ impl Generics {
256256
pub fn placeholder_subst(&self, db: &dyn HirDatabase) -> Substitution {
257257
Substitution::from_iter(
258258
Interner,
259-
self.iter_id().map(|id| match id {
259+
self.iter_id().enumerate().map(|(index, id)| match id {
260260
GenericParamId::TypeParamId(id) => {
261-
to_placeholder_idx(db, id.into()).to_ty(Interner).cast(Interner)
261+
to_placeholder_idx(db, id.into(), index as u32).to_ty(Interner).cast(Interner)
262262
}
263-
GenericParamId::ConstParamId(id) => to_placeholder_idx(db, id.into())
263+
GenericParamId::ConstParamId(id) => to_placeholder_idx(db, id.into(), index as u32)
264264
.to_const(Interner, db.const_param_ty(id))
265265
.cast(Interner),
266266
GenericParamId::LifetimeParamId(id) => {
267-
lt_to_placeholder_idx(db, id).to_lifetime(Interner).cast(Interner)
267+
lt_to_placeholder_idx(db, id, index as u32).to_lifetime(Interner).cast(Interner)
268268
}
269269
}),
270270
)

crates/hir-ty/src/infer/closure.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -866,7 +866,7 @@ impl CapturedItemWithoutTy {
866866
idx: chalk_ir::PlaceholderIndex,
867867
outer_binder: DebruijnIndex,
868868
) -> Result<chalk_ir::Const<Interner>, Self::Error> {
869-
let x = from_placeholder_idx(self.db, idx);
869+
let x = from_placeholder_idx(self.db, idx).0;
870870
let Some(idx) = self.generics.type_or_const_param_idx(x) else {
871871
return Err(());
872872
};
@@ -878,7 +878,7 @@ impl CapturedItemWithoutTy {
878878
idx: chalk_ir::PlaceholderIndex,
879879
outer_binder: DebruijnIndex,
880880
) -> std::result::Result<Ty, Self::Error> {
881-
let x = from_placeholder_idx(self.db, idx);
881+
let x = from_placeholder_idx(self.db, idx).0;
882882
let Some(idx) = self.generics.type_or_const_param_idx(x) else {
883883
return Err(());
884884
};

crates/hir-ty/src/layout.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@ use rustc_type_ir::{
1919
};
2020
use triomphe::Arc;
2121

22+
use crate::utils::ClosureSubst;
2223
use crate::{
23-
TraitEnvironment,
24+
Interner, TraitEnvironment,
2425
consteval_nextsolver::try_const_usize,
2526
db::HirDatabase,
2627
next_solver::{
2728
DbInterner, GenericArgs, ParamEnv, SolverDefId, Ty, TyKind, TypingMode,
2829
infer::{DbInternerInferExt, traits::ObligationCause},
29-
mapping::{ChalkToNextSolver, convert_binder_to_early_binder},
30+
mapping::{ChalkToNextSolver, convert_args_for_result},
3031
project::solve_normalize::deeply_normalize,
3132
},
3233
};
@@ -333,9 +334,15 @@ pub fn layout_of_ty_query<'db>(
333334
let fields = captures
334335
.iter()
335336
.map(|it| {
336-
let ty =
337-
convert_binder_to_early_binder(interner, it.ty.to_nextsolver(interner))
338-
.instantiate(interner, args);
337+
let ty = it
338+
.ty
339+
.clone()
340+
.substitute(
341+
Interner,
342+
ClosureSubst(&convert_args_for_result(interner, args.inner()))
343+
.parent_subst(),
344+
)
345+
.to_nextsolver(interner);
339346
db.layout_of_ty(ty, trait_env.clone())
340347
})
341348
.collect::<Result<Vec<_>, _>>()?;

crates/hir-ty/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ pub use lower_nextsolver::associated_type_shorthand_candidates;
124124
pub use mapping::{
125125
ToChalk, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx,
126126
lt_from_placeholder_idx, lt_to_placeholder_idx, to_assoc_type_id, to_chalk_trait_id,
127-
to_foreign_def_id, to_placeholder_idx,
127+
to_foreign_def_id, to_placeholder_idx, to_placeholder_idx_no_index,
128128
};
129129
pub use method_resolution::check_orphan_rules;
130130
pub use target_feature::TargetFeatures;
@@ -1007,7 +1007,7 @@ struct PlaceholderCollector<'db> {
10071007

10081008
impl PlaceholderCollector<'_> {
10091009
fn collect(&mut self, idx: PlaceholderIndex) {
1010-
let id = from_placeholder_idx(self.db, idx);
1010+
let id = from_placeholder_idx(self.db, idx).0;
10111011
self.placeholders.insert(id);
10121012
}
10131013
}

0 commit comments

Comments
 (0)