Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #20586 from ChayimFriedman2/placeholder-ns
fix: Make sense of the mess that were (are) different kind of generics in the solver
Shoyu Vanilla (Flint) 8 months ago
parent ebc2465 · parent 41611b1 · commit a79e27b
-rw-r--r--crates/hir-ty/src/chalk_ext.rs2
-rw-r--r--crates/hir-ty/src/consteval.rs29
-rw-r--r--crates/hir-ty/src/consteval_nextsolver.rs2
-rw-r--r--crates/hir-ty/src/db.rs6
-rw-r--r--crates/hir-ty/src/display.rs46
-rw-r--r--crates/hir-ty/src/dyn_compatibility.rs20
-rw-r--r--crates/hir-ty/src/generics.rs8
-rw-r--r--crates/hir-ty/src/infer/closure.rs4
-rw-r--r--crates/hir-ty/src/layout.rs17
-rw-r--r--crates/hir-ty/src/lib.rs4
-rw-r--r--crates/hir-ty/src/lower.rs12
-rw-r--r--crates/hir-ty/src/lower/path.rs8
-rw-r--r--crates/hir-ty/src/lower_nextsolver.rs13
-rw-r--r--crates/hir-ty/src/lower_nextsolver/path.rs2
-rw-r--r--crates/hir-ty/src/mapping.rs36
-rw-r--r--crates/hir-ty/src/mir/monomorphization.rs4
-rw-r--r--crates/hir-ty/src/next_solver/consts.rs3
-rw-r--r--crates/hir-ty/src/next_solver/generic_arg.rs38
-rw-r--r--crates/hir-ty/src/next_solver/generics.rs63
-rw-r--r--crates/hir-ty/src/next_solver/infer/mod.rs13
-rw-r--r--crates/hir-ty/src/next_solver/mapping.rs191
-rw-r--r--crates/hir-ty/src/next_solver/region.rs3
-rw-r--r--crates/hir-ty/src/next_solver/ty.rs12
-rw-r--r--crates/hir-ty/src/variance.rs4
-rw-r--r--crates/hir/src/display.rs11
-rw-r--r--crates/hir/src/lib.rs6
26 files changed, 324 insertions, 233 deletions
diff --git a/crates/hir-ty/src/chalk_ext.rs b/crates/hir-ty/src/chalk_ext.rs
index 8fa1aff0ef..33ae099c69 100644
--- a/crates/hir-ty/src/chalk_ext.rs
+++ b/crates/hir-ty/src/chalk_ext.rs
@@ -306,7 +306,7 @@ impl TyExt for Ty {
predicates.map(|it| it.into_value_and_skipped_binders().0)
}
TyKind::Placeholder(idx) => {
- let id = from_placeholder_idx(db, *idx);
+ let id = from_placeholder_idx(db, *idx).0;
let generic_params = db.generic_params(id.parent);
let param_data = &generic_params[id.local_id];
match param_data {
diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs
index abf97f3d0e..0f2cc17f56 100644
--- a/crates/hir-ty/src/consteval.rs
+++ b/crates/hir-ty/src/consteval.rs
@@ -107,25 +107,24 @@ pub(crate) fn path_to_const<'g>(
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 => {
- ConstValue::Placeholder(to_placeholder_idx(db, p.into()))
+ let idx = args.type_or_const_param_idx(p.into()).unwrap();
+ ConstValue::Placeholder(to_placeholder_idx(db, p.into(), idx as u32))
}
- ParamLoweringMode::Variable => {
- let args = args();
- 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;
- }
+ 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))
}
diff --git a/crates/hir-ty/src/consteval_nextsolver.rs b/crates/hir-ty/src/consteval_nextsolver.rs
index 00fc4e5610..4f95c9a13a 100644
--- a/crates/hir-ty/src/consteval_nextsolver.rs
+++ b/crates/hir-ty/src/consteval_nextsolver.rs
@@ -49,7 +49,7 @@ pub(crate) fn path_to_const<'a, 'g>(
.and_then(|(idx, p)| p.const_param().map(|p| (idx, p.clone())))
{
Some((idx, _param)) => {
- Some(Const::new_param(interner, ParamConst { index: idx as u32 }))
+ Some(Const::new_param(interner, ParamConst { index: idx as u32, id: p }))
}
None => {
never!(
diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs
index 97754f4723..0b7213d785 100644
--- a/crates/hir-ty/src/db.rs
+++ b/crates/hir-ty/src/db.rs
@@ -410,13 +410,15 @@ fn hir_database_is_dyn_compatible() {
#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
#[derive(PartialOrd, Ord)]
pub struct InternedTypeOrConstParamId {
- pub loc: TypeOrConstParamId,
+ /// This stores the param and its index.
+ pub loc: (TypeOrConstParamId, u32),
}
#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
#[derive(PartialOrd, Ord)]
pub struct InternedLifetimeParamId {
- pub loc: LifetimeParamId,
+ /// This stores the param and its index.
+ pub loc: (LifetimeParamId, u32),
}
#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index 0df727a8e5..5b8093f6b7 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -61,9 +61,8 @@ use crate::{
next_solver::{
BoundExistentialPredicate, Ctor, DbInterner, GenericArgs, SolverDefId,
mapping::{
- ChalkToNextSolver, bound_var_to_lifetime_idx, bound_var_to_type_or_const_param_idx,
- convert_args_for_result, convert_const_for_result, convert_region_for_result,
- convert_ty_for_result,
+ ChalkToNextSolver, convert_args_for_result, convert_const_for_result,
+ convert_region_for_result, convert_ty_for_result,
},
},
primitive, to_assoc_type_id,
@@ -641,7 +640,7 @@ impl HirDisplay for ProjectionTy {
&& !f.bounds_formatting_ctx.contains(self)
{
let db = f.db;
- let id = from_placeholder_idx(db, *idx);
+ let id = from_placeholder_idx(db, *idx).0;
let generics = generics(db, id.parent);
let substs = generics.placeholder_subst(db);
@@ -736,14 +735,14 @@ impl HirDisplay for Const {
impl<'db> HirDisplay for crate::next_solver::Const<'db> {
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
match self.kind() {
+ rustc_type_ir::ConstKind::Placeholder(_) => write!(f, "<placeholder>"),
rustc_type_ir::ConstKind::Bound(db, bound_const) => {
write!(f, "?{}.{}", db.as_u32(), bound_const.as_u32())
}
rustc_type_ir::ConstKind::Infer(..) => write!(f, "#c#"),
- rustc_type_ir::ConstKind::Placeholder(idx) => {
- let id = bound_var_to_type_or_const_param_idx(f.db, idx.bound);
- let generics = generics(f.db, id.parent);
- let param_data = &generics[id.local_id];
+ rustc_type_ir::ConstKind::Param(param) => {
+ let generics = generics(f.db, param.id.parent());
+ let param_data = &generics[param.id.local_id()];
write!(f, "{}", param_data.name().unwrap().display(f.db, f.edition()))?;
Ok(())
}
@@ -765,7 +764,6 @@ impl<'db> HirDisplay for crate::next_solver::Const<'db> {
}
rustc_type_ir::ConstKind::Error(..) => f.write_char('_'),
rustc_type_ir::ConstKind::Expr(..) => write!(f, "<const-expr>"),
- rustc_type_ir::ConstKind::Param(_) => write!(f, "<param>"),
}
}
}
@@ -1178,7 +1176,7 @@ impl<'db> HirDisplay for crate::next_solver::Ty<'db> {
if let TyKind::Ref(l, _, _) = kind {
f.write_char('&')?;
if f.render_region(l) {
- convert_region_for_result(l).hir_fmt(f)?;
+ convert_region_for_result(interner, l).hir_fmt(f)?;
f.write_char(' ')?;
}
match m {
@@ -1611,14 +1609,10 @@ impl<'db> HirDisplay for crate::next_solver::Ty<'db> {
write!(f, "{{closure}}")?;
}
}
- TyKind::Placeholder(idx) => {
- let placeholder_index = chalk_ir::PlaceholderIndex {
- idx: idx.bound.var.as_usize(),
- ui: chalk_ir::UniverseIndex { counter: idx.universe.as_usize() },
- };
- let id = from_placeholder_idx(db, placeholder_index);
- let generics = generics(db, id.parent);
- let param_data = &generics[id.local_id];
+ TyKind::Placeholder(_) => write!(f, "{{placeholder}}")?,
+ TyKind::Param(param) => {
+ let generics = generics(db, param.id.parent());
+ let param_data = &generics[param.id.local_id()];
match param_data {
TypeOrConstParamData::TypeParamData(p) => match p.provenance {
TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => {
@@ -1634,7 +1628,7 @@ impl<'db> HirDisplay for crate::next_solver::Ty<'db> {
TypeParamProvenance::ArgumentImplTrait => {
let substs = generics.placeholder_subst(db);
let bounds = db
- .generic_predicates(id.parent)
+ .generic_predicates(param.id.parent())
.iter()
.map(|pred| pred.clone().substitute(Interner, &substs))
.filter(|wc| match wc.skip_binders() {
@@ -1656,7 +1650,7 @@ impl<'db> HirDisplay for crate::next_solver::Ty<'db> {
WhereClause::LifetimeOutlives(_) => false,
})
.collect::<Vec<_>>();
- let krate = id.parent.module(db).krate();
+ let krate = param.id.parent().module(db).krate();
write_bounds_like_dyn_trait_with_prefix(
f,
"impl",
@@ -1671,7 +1665,6 @@ impl<'db> HirDisplay for crate::next_solver::Ty<'db> {
}
}
}
- TyKind::Param(_) => write!(f, "{{param}}")?,
TyKind::Bound(debruijn_index, ty) => {
let idx = chalk_ir::BoundVar {
debruijn: chalk_ir::DebruijnIndex::new(debruijn_index.as_u32()),
@@ -2294,7 +2287,7 @@ impl HirDisplay for LifetimeData {
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
match self {
LifetimeData::Placeholder(idx) => {
- let id = lt_from_placeholder_idx(f.db, *idx);
+ let id = lt_from_placeholder_idx(f.db, *idx).0;
let generics = generics(f.db, id.parent);
let param_data = &generics[id.local_id];
write!(f, "{}", param_data.name.display(f.db, f.edition()))?;
@@ -2319,10 +2312,9 @@ impl HirDisplay for LifetimeData {
impl<'db> HirDisplay for crate::next_solver::Region<'db> {
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
match self.kind() {
- rustc_type_ir::RegionKind::RePlaceholder(idx) => {
- let id = bound_var_to_lifetime_idx(f.db, idx.bound.var);
- let generics = generics(f.db, id.parent);
- let param_data = &generics[id.local_id];
+ rustc_type_ir::RegionKind::ReEarlyParam(param) => {
+ let generics = generics(f.db, param.id.parent);
+ let param_data = &generics[param.id.local_id];
write!(f, "{}", param_data.name.display(f.db, f.edition()))?;
Ok(())
}
@@ -2339,7 +2331,7 @@ impl<'db> HirDisplay for crate::next_solver::Region<'db> {
}
}
rustc_type_ir::RegionKind::ReErased => write!(f, "'<erased>"),
- rustc_type_ir::RegionKind::ReEarlyParam(_) => write!(f, "<param>"),
+ rustc_type_ir::RegionKind::RePlaceholder(_) => write!(f, "<placeholder>"),
rustc_type_ir::RegionKind::ReLateParam(_) => write!(f, "<late-param>"),
}
}
diff --git a/crates/hir-ty/src/dyn_compatibility.rs b/crates/hir-ty/src/dyn_compatibility.rs
index b0c61c29db..23280b1f3b 100644
--- a/crates/hir-ty/src/dyn_compatibility.rs
+++ b/crates/hir-ty/src/dyn_compatibility.rs
@@ -2,10 +2,12 @@
use std::ops::ControlFlow;
+use hir_def::hir::generics::LocalTypeOrConstParamId;
use hir_def::{
AssocItemId, ConstId, CrateRootModuleId, FunctionId, GenericDefId, HasModule, TraitId,
TypeAliasId, lang_item::LangItem, signatures::TraitFlags,
};
+use hir_def::{TypeOrConstParamId, TypeParamId};
use intern::Symbol;
use rustc_hash::FxHashSet;
use rustc_type_ir::{
@@ -384,7 +386,6 @@ where
}
// Allow `impl AutoTrait` predicates
- let interner = DbInterner::new_with(db, Some(trait_.krate(db)), None);
if let ClauseKind::Trait(TraitPredicate {
trait_ref: pred_trait_ref,
polarity: PredicatePolarity::Positive,
@@ -392,11 +393,8 @@ where
&& let SolverDefId::TraitId(trait_id) = pred_trait_ref.def_id
&& let trait_data = db.trait_signature(trait_id)
&& trait_data.flags.contains(TraitFlags::AUTO)
- && pred_trait_ref.self_ty()
- == crate::next_solver::Ty::new(
- interner,
- rustc_type_ir::TyKind::Param(crate::next_solver::ParamTy { index: 0 }),
- )
+ && let rustc_type_ir::TyKind::Param(crate::next_solver::ParamTy { index: 0, .. }) =
+ pred_trait_ref.self_ty().kind()
{
continue;
}
@@ -422,9 +420,13 @@ fn receiver_is_dispatchable<'db>(
let sig = sig.instantiate_identity();
let interner: DbInterner<'_> = DbInterner::new_with(db, Some(trait_.krate(db)), None);
+ let self_param_id = TypeParamId::from_unchecked(TypeOrConstParamId {
+ 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 }),
+ rustc_type_ir::TyKind::Param(crate::next_solver::ParamTy { index: 0, id: self_param_id }),
);
// `self: Self` can't be dispatched on, but this is already considered dyn-compatible
@@ -452,7 +454,9 @@ fn receiver_is_dispatchable<'db>(
};
// Type `U`
- let unsized_self_ty = crate::next_solver::Ty::new_param(interner, u32::MAX, Symbol::empty());
+ // 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, Symbol::empty());
// `Receiver[Self => U]`
let unsized_receiver_ty = receiver_for_self_ty(interner, func, receiver_ty, unsized_self_ty);
diff --git a/crates/hir-ty/src/generics.rs b/crates/hir-ty/src/generics.rs
index 412b3ac425..e179e41b1c 100644
--- a/crates/hir-ty/src/generics.rs
+++ b/crates/hir-ty/src/generics.rs
@@ -256,15 +256,15 @@ impl Generics {
pub fn placeholder_subst(&self, db: &dyn HirDatabase) -> Substitution {
Substitution::from_iter(
Interner,
- self.iter_id().map(|id| match id {
+ self.iter_id().enumerate().map(|(index, id)| match id {
GenericParamId::TypeParamId(id) => {
- to_placeholder_idx(db, id.into()).to_ty(Interner).cast(Interner)
+ to_placeholder_idx(db, id.into(), index as u32).to_ty(Interner).cast(Interner)
}
- GenericParamId::ConstParamId(id) => to_placeholder_idx(db, id.into())
+ 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).to_lifetime(Interner).cast(Interner)
+ lt_to_placeholder_idx(db, id, index as u32).to_lifetime(Interner).cast(Interner)
}
}),
)
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs
index 38ac2e1170..9ef046afdb 100644
--- a/crates/hir-ty/src/infer/closure.rs
+++ b/crates/hir-ty/src/infer/closure.rs
@@ -866,7 +866,7 @@ impl CapturedItemWithoutTy {
idx: chalk_ir::PlaceholderIndex,
outer_binder: DebruijnIndex,
) -> Result<chalk_ir::Const<Interner>, Self::Error> {
- let x = from_placeholder_idx(self.db, idx);
+ let x = from_placeholder_idx(self.db, idx).0;
let Some(idx) = self.generics.type_or_const_param_idx(x) else {
return Err(());
};
@@ -878,7 +878,7 @@ impl CapturedItemWithoutTy {
idx: chalk_ir::PlaceholderIndex,
outer_binder: DebruijnIndex,
) -> std::result::Result<Ty, Self::Error> {
- let x = from_placeholder_idx(self.db, idx);
+ let x = from_placeholder_idx(self.db, idx).0;
let Some(idx) = self.generics.type_or_const_param_idx(x) else {
return Err(());
};
diff --git a/crates/hir-ty/src/layout.rs b/crates/hir-ty/src/layout.rs
index e2ee8935a8..f8abb3b7f6 100644
--- a/crates/hir-ty/src/layout.rs
+++ b/crates/hir-ty/src/layout.rs
@@ -19,14 +19,15 @@ use rustc_type_ir::{
};
use triomphe::Arc;
+use crate::utils::ClosureSubst;
use crate::{
- TraitEnvironment,
+ Interner, TraitEnvironment,
consteval_nextsolver::try_const_usize,
db::HirDatabase,
next_solver::{
DbInterner, GenericArgs, ParamEnv, SolverDefId, Ty, TyKind, TypingMode,
infer::{DbInternerInferExt, traits::ObligationCause},
- mapping::{ChalkToNextSolver, convert_binder_to_early_binder},
+ mapping::{ChalkToNextSolver, convert_args_for_result},
project::solve_normalize::deeply_normalize,
},
};
@@ -333,9 +334,15 @@ pub fn layout_of_ty_query<'db>(
let fields = captures
.iter()
.map(|it| {
- let ty =
- convert_binder_to_early_binder(interner, it.ty.to_nextsolver(interner))
- .instantiate(interner, args);
+ let ty = it
+ .ty
+ .clone()
+ .substitute(
+ Interner,
+ ClosureSubst(&convert_args_for_result(interner, args.inner()))
+ .parent_subst(),
+ )
+ .to_nextsolver(interner);
db.layout_of_ty(ty, trait_env.clone())
})
.collect::<Result<Vec<_>, _>>()?;
diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs
index 7fdfb20572..c16bbb7b99 100644
--- a/crates/hir-ty/src/lib.rs
+++ b/crates/hir-ty/src/lib.rs
@@ -124,7 +124,7 @@ pub use lower_nextsolver::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_foreign_def_id, to_placeholder_idx, to_placeholder_idx_no_index,
};
pub use method_resolution::check_orphan_rules;
pub use target_feature::TargetFeatures;
@@ -1007,7 +1007,7 @@ struct PlaceholderCollector<'db> {
impl PlaceholderCollector<'_> {
fn collect(&mut self, idx: PlaceholderIndex) {
- let id = from_placeholder_idx(self.db, idx);
+ let id = from_placeholder_idx(self.db, idx).0;
self.placeholders.insert(id);
}
}
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index 098c62ba97..79f78c545e 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -340,7 +340,13 @@ impl<'a> TyLoweringContext<'a> {
res = Some(TypeNs::GenericParam(type_param_id));
match self.type_param_mode {
ParamLoweringMode::Placeholder => {
- TyKind::Placeholder(to_placeholder_idx(self.db, type_param_id.into()))
+ let generics = self.generics();
+ let idx = generics.type_or_const_param_idx(type_param_id.into()).unwrap();
+ TyKind::Placeholder(to_placeholder_idx(
+ self.db,
+ type_param_id.into(),
+ idx as u32,
+ ))
}
ParamLoweringMode::Variable => {
let idx =
@@ -777,7 +783,9 @@ impl<'a> TyLoweringContext<'a> {
LifetimeNs::Static => static_lifetime(),
LifetimeNs::LifetimeParam(id) => match self.type_param_mode {
ParamLoweringMode::Placeholder => {
- LifetimeData::Placeholder(lt_to_placeholder_idx(self.db, id))
+ let generics = self.generics();
+ let idx = generics.lifetime_idx(id).unwrap();
+ LifetimeData::Placeholder(lt_to_placeholder_idx(self.db, id, idx as u32))
}
ParamLoweringMode::Variable => {
let idx = match self.generics().lifetime_idx(id) {
diff --git a/crates/hir-ty/src/lower/path.rs b/crates/hir-ty/src/lower/path.rs
index fb85909d7f..b0132e4dcb 100644
--- a/crates/hir-ty/src/lower/path.rs
+++ b/crates/hir-ty/src/lower/path.rs
@@ -222,7 +222,13 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
}
TypeNs::GenericParam(param_id) => match self.ctx.type_param_mode {
ParamLoweringMode::Placeholder => {
- TyKind::Placeholder(to_placeholder_idx(self.ctx.db, param_id.into()))
+ let generics = self.ctx.generics();
+ let idx = generics.type_or_const_param_idx(param_id.into()).unwrap();
+ TyKind::Placeholder(to_placeholder_idx(
+ self.ctx.db,
+ param_id.into(),
+ idx as u32,
+ ))
}
ParamLoweringMode::Variable => {
let idx = match self.ctx.generics().type_or_const_param_idx(param_id.into()) {
diff --git a/crates/hir-ty/src/lower_nextsolver.rs b/crates/hir-ty/src/lower_nextsolver.rs
index d87181f545..4578922ce3 100644
--- a/crates/hir-ty/src/lower_nextsolver.rs
+++ b/crates/hir-ty/src/lower_nextsolver.rs
@@ -64,8 +64,7 @@ use crate::{
AdtDef, AliasTy, Binder, BoundExistentialPredicates, BoundRegionKind, BoundTyKind,
BoundVarKind, BoundVarKinds, Clause, Clauses, Const, DbInterner, EarlyBinder,
EarlyParamRegion, ErrorGuaranteed, GenericArgs, PolyFnSig, Predicate, Region, SolverDefId,
- TraitPredicate, TraitRef, Ty, Tys, abi::Safety, generics::GenericParamDefKind,
- mapping::ChalkToNextSolver,
+ TraitPredicate, TraitRef, Ty, Tys, abi::Safety, mapping::ChalkToNextSolver,
},
};
@@ -322,6 +321,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
};
Ty::new_param(
self.interner,
+ type_param_id,
idx as u32,
type_data
.name
@@ -866,7 +866,10 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
None => return Region::error(self.interner),
Some(idx) => idx,
};
- Region::new_early_param(self.interner, EarlyParamRegion { index: idx as u32 })
+ Region::new_early_param(
+ self.interner,
+ EarlyParamRegion { index: idx as u32, id },
+ )
}
},
None => Region::error(self.interner),
@@ -1344,11 +1347,11 @@ where
{
continue;
}
- let GenericParamDefKind::Type = p.kind else {
+ let GenericParamId::TypeParamId(param_id) = p.id else {
continue;
};
let idx = idx as u32 + generics.parent_count as u32;
- let param_ty = Ty::new_param(interner, idx, p.name.clone());
+ let param_ty = Ty::new_param(interner, param_id, idx, p.name.clone());
if explicitly_unsized_tys.contains(&param_ty) {
continue;
}
diff --git a/crates/hir-ty/src/lower_nextsolver/path.rs b/crates/hir-ty/src/lower_nextsolver/path.rs
index e3efb38306..ccdb5a0bdb 100644
--- a/crates/hir-ty/src/lower_nextsolver/path.rs
+++ b/crates/hir-ty/src/lower_nextsolver/path.rs
@@ -281,6 +281,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
};
Ty::new_param(
self.ctx.interner,
+ param_id,
idx as u32,
p.name
.as_ref()
@@ -758,6 +759,7 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
self.ctx.ctx.db.generic_defaults(def).get(preceding_args.len()).map(|default| {
convert_binder_to_early_binder(
self.ctx.ctx.interner,
+ def,
default.to_nextsolver(self.ctx.ctx.interner),
)
.instantiate(self.ctx.ctx.interner, preceding_args)
diff --git a/crates/hir-ty/src/mapping.rs b/crates/hir-ty/src/mapping.rs
index 448fbdf673..5125a38825 100644
--- a/crates/hir-ty/src/mapping.rs
+++ b/crates/hir-ty/src/mapping.rs
@@ -104,7 +104,10 @@ 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 {
+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 =
@@ -112,15 +115,32 @@ pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> Type
interned_id.loc(db)
}
-pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeOrConstParamId) -> PlaceholderIndex {
- let interned_id = InternedTypeOrConstParamId::new(db, id);
+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 lt_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> LifetimeParamId {
+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 =
@@ -128,8 +148,12 @@ pub fn lt_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> L
interned_id.loc(db)
}
-pub fn lt_to_placeholder_idx(db: &dyn HirDatabase, id: LifetimeParamId) -> PlaceholderIndex {
- let interned_id = InternedLifetimeParamId::new(db, id);
+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,
diff --git a/crates/hir-ty/src/mir/monomorphization.rs b/crates/hir-ty/src/mir/monomorphization.rs
index d8f443145c..b0b9223169 100644
--- a/crates/hir-ty/src/mir/monomorphization.rs
+++ b/crates/hir-ty/src/mir/monomorphization.rs
@@ -99,7 +99,7 @@ impl FallibleTypeFolder<Interner> for Filler<'_> {
idx: chalk_ir::PlaceholderIndex,
_outer_binder: DebruijnIndex,
) -> std::result::Result<chalk_ir::Const<Interner>, Self::Error> {
- let it = from_placeholder_idx(self.db, idx);
+ let it = from_placeholder_idx(self.db, idx).0;
let Some(idx) = self.generics.as_ref().and_then(|g| g.type_or_const_param_idx(it)) else {
not_supported!("missing idx in generics");
};
@@ -117,7 +117,7 @@ impl FallibleTypeFolder<Interner> for Filler<'_> {
idx: chalk_ir::PlaceholderIndex,
_outer_binder: DebruijnIndex,
) -> std::result::Result<Ty, Self::Error> {
- let it = from_placeholder_idx(self.db, idx);
+ let it = from_placeholder_idx(self.db, idx).0;
let Some(idx) = self.generics.as_ref().and_then(|g| g.type_or_const_param_idx(it)) else {
not_supported!("missing idx in generics");
};
diff --git a/crates/hir-ty/src/next_solver/consts.rs b/crates/hir-ty/src/next_solver/consts.rs
index ce581cfad4..cfafc65d18 100644
--- a/crates/hir-ty/src/next_solver/consts.rs
+++ b/crates/hir-ty/src/next_solver/consts.rs
@@ -2,6 +2,7 @@
use std::hash::Hash;
+use hir_def::{ConstParamId, TypeOrConstParamId};
use intern::{Interned, Symbol};
use rustc_ast_ir::try_visit;
use rustc_ast_ir::visit::VisitorResult;
@@ -84,6 +85,8 @@ pub type PlaceholderConst = Placeholder<rustc_type_ir::BoundVar>;
#[derive(Copy, Clone, Hash, Eq, PartialEq)]
pub struct ParamConst {
+ // FIXME: See `ParamTy`.
+ pub id: ConstParamId,
pub index: u32,
}
diff --git a/crates/hir-ty/src/next_solver/generic_arg.rs b/crates/hir-ty/src/next_solver/generic_arg.rs
index 76186e3746..d284eb9c6b 100644
--- a/crates/hir-ty/src/next_solver/generic_arg.rs
+++ b/crates/hir-ty/src/next_solver/generic_arg.rs
@@ -1,5 +1,6 @@
//! Things related to generic args in the next-trait-solver.
+use hir_def::GenericParamId;
use intern::{Interned, Symbol};
use rustc_type_ir::{
ClosureArgs, CollectAndApply, ConstVid, CoroutineArgs, CoroutineClosureArgs, FnSig, FnSigTys,
@@ -14,7 +15,7 @@ use crate::db::HirDatabase;
use super::{
Const, DbInterner, EarlyParamRegion, ErrorGuaranteed, ParamConst, Region, SolverDefId, Ty, Tys,
- generics::{GenericParamDef, GenericParamDefKind, Generics},
+ generics::{GenericParamDef, Generics},
interned_vec_db,
};
@@ -203,7 +204,7 @@ impl<'db> GenericArgs<'db> {
mut mk_kind: F,
) -> GenericArgs<'db>
where
- F: FnMut(&Symbol, u32, GenericParamDefKind, &[GenericArg<'db>]) -> GenericArg<'db>,
+ F: FnMut(&Symbol, u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
{
let defs = interner.generics_of(def_id);
let count = defs.count();
@@ -218,7 +219,7 @@ impl<'db> GenericArgs<'db> {
defs: Generics,
mk_kind: &mut F,
) where
- F: FnMut(&Symbol, u32, GenericParamDefKind, &[GenericArg<'db>]) -> GenericArg<'db>,
+ F: FnMut(&Symbol, u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
{
let self_len = defs.own_params.len() as u32;
if let Some(def_id) = defs.parent {
@@ -230,12 +231,12 @@ impl<'db> GenericArgs<'db> {
fn fill_single<F>(args: &mut SmallVec<[GenericArg<'db>; 8]>, defs: &Generics, mk_kind: &mut F)
where
- F: FnMut(&Symbol, u32, GenericParamDefKind, &[GenericArg<'db>]) -> GenericArg<'db>,
+ F: FnMut(&Symbol, u32, GenericParamId, &[GenericArg<'db>]) -> GenericArg<'db>,
{
let start_len = args.len();
args.reserve(defs.own_params.len());
for param in &defs.own_params {
- let kind = mk_kind(&param.name, args.len() as u32, param.kind, args);
+ let kind = mk_kind(&param.name, args.len() as u32, param.id, args);
args.push(kind);
}
}
@@ -412,26 +413,25 @@ pub fn mk_param<'db>(
interner: DbInterner<'db>,
index: u32,
name: &Symbol,
- kind: GenericParamDefKind,
+ id: GenericParamId,
) -> GenericArg<'db> {
let name = name.clone();
- match kind {
- GenericParamDefKind::Lifetime => {
- Region::new_early_param(interner, EarlyParamRegion { index }).into()
+ match id {
+ GenericParamId::LifetimeParamId(id) => {
+ Region::new_early_param(interner, EarlyParamRegion { index, id }).into()
+ }
+ GenericParamId::TypeParamId(id) => Ty::new_param(interner, id, index, name).into(),
+ GenericParamId::ConstParamId(id) => {
+ Const::new_param(interner, ParamConst { index, id }).into()
}
- GenericParamDefKind::Type => Ty::new_param(interner, index, name).into(),
- GenericParamDefKind::Const => Const::new_param(interner, ParamConst { index }).into(),
}
}
-pub fn error_for_param_kind<'db>(
- kind: GenericParamDefKind,
- interner: DbInterner<'db>,
-) -> GenericArg<'db> {
- match kind {
- GenericParamDefKind::Lifetime => Region::error(interner).into(),
- GenericParamDefKind::Type => Ty::new_error(interner, ErrorGuaranteed).into(),
- GenericParamDefKind::Const => Const::error(interner).into(),
+pub fn error_for_param_kind<'db>(id: GenericParamId, interner: DbInterner<'db>) -> GenericArg<'db> {
+ match id {
+ GenericParamId::LifetimeParamId(_) => Region::error(interner).into(),
+ GenericParamId::TypeParamId(_) => Ty::new_error(interner, ErrorGuaranteed).into(),
+ GenericParamId::ConstParamId(_) => Const::error(interner).into(),
}
}
diff --git a/crates/hir-ty/src/next_solver/generics.rs b/crates/hir-ty/src/next_solver/generics.rs
index a3ba8eb834..5ec9a18a6c 100644
--- a/crates/hir-ty/src/next_solver/generics.rs
+++ b/crates/hir-ty/src/next_solver/generics.rs
@@ -24,35 +24,40 @@ use super::{Const, EarlyParamRegion, ErrorGuaranteed, ParamConst, Region, Solver
use super::{DbInterner, GenericArg};
pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
- let mk_lt = |index, lt: &LifetimeParamData| {
+ let mk_lt = |parent, index, local_id, lt: &LifetimeParamData| {
let name = lt.name.symbol().clone();
- let kind = GenericParamDefKind::Lifetime;
- GenericParamDef { name, index, kind }
+ let id = GenericParamId::LifetimeParamId(LifetimeParamId { parent, local_id });
+ GenericParamDef { name, index, id }
};
- let mk_ty = |index, p: &TypeOrConstParamData| {
+ let mk_ty = |parent, index, local_id, p: &TypeOrConstParamData| {
let name = p.name().map(|n| n.symbol().clone()).unwrap_or_else(|| sym::MISSING_NAME);
- let kind = match p {
- TypeOrConstParamData::TypeParamData(_) => GenericParamDefKind::Type,
- TypeOrConstParamData::ConstParamData(_) => GenericParamDefKind::Const,
+ let id = TypeOrConstParamId { parent, local_id };
+ let id = match p {
+ TypeOrConstParamData::TypeParamData(_) => {
+ GenericParamId::TypeParamId(TypeParamId::from_unchecked(id))
+ }
+ TypeOrConstParamData::ConstParamData(_) => {
+ GenericParamId::ConstParamId(ConstParamId::from_unchecked(id))
+ }
};
- GenericParamDef { name, index, kind }
+ GenericParamDef { name, index, id }
};
- let own_params_for_generic_params = |params: &GenericParams| {
+ let own_params_for_generic_params = |parent, params: &GenericParams| {
let mut result = Vec::with_capacity(params.len());
let mut type_and_consts = params.iter_type_or_consts();
let mut index = 0;
if let Some(self_param) = params.trait_self_param() {
- result.push(mk_ty(0, &params[self_param]));
+ result.push(mk_ty(parent, 0, self_param, &params[self_param]));
type_and_consts.next();
index += 1;
}
- result.extend(params.iter_lt().map(|(_, data)| {
- let lt = mk_lt(index, data);
+ result.extend(params.iter_lt().map(|(local_id, data)| {
+ let lt = mk_lt(parent, index, local_id, data);
index += 1;
lt
}));
- result.extend(type_and_consts.map(|(_, data)| {
- let ty = mk_ty(index, data);
+ result.extend(type_and_consts.map(|(local_id, data)| {
+ let ty = mk_ty(parent, index, local_id, data);
index += 1;
ty
}));
@@ -60,9 +65,10 @@ pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
};
let (parent, own_params) = match (def.try_into(), def) {
- (Ok(def), _) => {
- (parent_generic_def(db, def), own_params_for_generic_params(&db.generic_params(def)))
- }
+ (Ok(def), _) => (
+ parent_generic_def(db, def),
+ own_params_for_generic_params(def, &db.generic_params(def)),
+ ),
(_, SolverDefId::InternedOpaqueTyId(id)) => {
match db.lookup_intern_impl_trait_id(id) {
crate::ImplTraitId::ReturnTypeImplTrait(function_id, _) => {
@@ -79,7 +85,19 @@ pub(crate) fn generics(db: &dyn HirDatabase, def: SolverDefId) -> Generics {
provenance: TypeParamProvenance::TypeParamList,
});
// Yes, there is a parent but we don't include it in the generics
- (None, vec![mk_ty(0, &param)])
+ // FIXME: It seems utterly sensitive to fake a generic param here.
+ // Also, what a horrible mess!
+ (
+ None,
+ vec![mk_ty(
+ GenericDefId::FunctionId(salsa::plumbing::FromId::from_id(unsafe {
+ salsa::Id::from_index(salsa::Id::MAX_U32 - 1)
+ })),
+ 0,
+ LocalTypeOrConstParamId::from_raw(la_arena::RawIdx::from_u32(0)),
+ &param,
+ )],
+ )
}
}
}
@@ -106,7 +124,7 @@ pub struct GenericParamDef {
pub(crate) name: Symbol,
//def_id: GenericDefId,
index: u32,
- pub(crate) kind: GenericParamDefKind,
+ pub(crate) id: GenericParamId,
}
impl GenericParamDef {
@@ -117,13 +135,6 @@ impl GenericParamDef {
}
}
-#[derive(Copy, Clone, Debug)]
-pub enum GenericParamDefKind {
- Lifetime,
- Type,
- Const,
-}
-
impl<'db> rustc_type_ir::inherent::GenericsOf<DbInterner<'db>> for Generics {
fn count(&self) -> usize {
self.parent_count + self.own_params.len()
diff --git a/crates/hir-ty/src/next_solver/infer/mod.rs b/crates/hir-ty/src/next_solver/infer/mod.rs
index 19ae76f7e3..58832aef89 100644
--- a/crates/hir-ty/src/next_solver/infer/mod.rs
+++ b/crates/hir-ty/src/next_solver/infer/mod.rs
@@ -8,6 +8,7 @@ pub use BoundRegionConversionTime::*;
pub use at::DefineOpaqueTypes;
use ena::undo_log::UndoLogs;
use ena::unify as ut;
+use hir_def::GenericParamId;
use intern::Symbol;
use opaque_types::{OpaqueHiddenType, OpaqueTypeStorage};
use region_constraints::{
@@ -38,7 +39,7 @@ use crate::next_solver::fold::BoundVarReplacerDelegate;
use crate::next_solver::infer::opaque_types::table::OpaqueTypeStorageEntries;
use crate::next_solver::{BoundRegion, BoundTy, BoundVarKind};
-use super::generics::{GenericParamDef, GenericParamDefKind};
+use super::generics::GenericParamDef;
use super::{
AliasTerm, Binder, BoundRegionKind, CanonicalQueryInput, CanonicalVarValues, Const, ConstKind,
DbInterner, ErrorGuaranteed, FxIndexMap, GenericArg, GenericArgs, OpaqueTypeKey, ParamEnv,
@@ -600,14 +601,14 @@ impl<'db> InferCtxt<'db> {
self.next_region_var_in_universe(universe)
}
- fn var_for_def(&self, kind: GenericParamDefKind, name: &Symbol) -> GenericArg<'db> {
- match kind {
- GenericParamDefKind::Lifetime => {
+ fn var_for_def(&self, id: GenericParamId, name: &Symbol) -> GenericArg<'db> {
+ match id {
+ GenericParamId::LifetimeParamId(_) => {
// Create a region inference variable for the given
// region parameter definition.
self.next_region_var().into()
}
- GenericParamDefKind::Type => {
+ GenericParamId::TypeParamId(_) => {
// Create a type inference variable for the given
// type parameter definition. The generic parameters are
// for actual parameters that may be referred to by
@@ -624,7 +625,7 @@ impl<'db> InferCtxt<'db> {
Ty::new_var(self.interner, ty_var_id).into()
}
- GenericParamDefKind::Const => {
+ GenericParamId::ConstParamId(_) => {
let origin = ConstVariableOrigin { param_def_id: None };
let const_var_id = self
.inner
diff --git a/crates/hir-ty/src/next_solver/mapping.rs b/crates/hir-ty/src/next_solver/mapping.rs
index 203f030dfd..6755d065e1 100644
--- a/crates/hir-ty/src/next_solver/mapping.rs
+++ b/crates/hir-ty/src/next_solver/mapping.rs
@@ -9,6 +9,7 @@ use hir_def::{
CallableDefId, ConstParamId, FunctionId, GeneralConstId, LifetimeParamId, TypeAliasId,
TypeOrConstParamId, TypeParamId, signatures::TraitFlags,
};
+use hir_def::{GenericDefId, GenericParamId};
use intern::sym;
use rustc_type_ir::{
AliasTerm, BoundVar, DebruijnIndex, ExistentialProjection, ExistentialTraitRef, Interner as _,
@@ -35,6 +36,9 @@ use crate::{
},
to_assoc_type_id, to_chalk_trait_id, to_foreign_def_id,
};
+use crate::{
+ from_placeholder_idx, lt_from_placeholder_idx, lt_to_placeholder_idx, to_placeholder_idx,
+};
use super::{
BoundExistentialPredicate, BoundExistentialPredicates, BoundRegion, BoundRegionKind, BoundTy,
@@ -44,47 +48,24 @@ use super::{
Region, SolverDefId, SubtypePredicate, Term, TraitRef, Ty, Tys, ValueConst, VariancesOf,
};
-pub fn to_placeholder_idx<T: Clone + std::fmt::Debug>(
- db: &dyn HirDatabase,
- id: TypeOrConstParamId,
- map: impl Fn(BoundVar) -> T,
-) -> Placeholder<T> {
- let interned_id = InternedTypeOrConstParamId::new(db, id);
- Placeholder {
- universe: UniverseIndex::ZERO,
- bound: map(BoundVar::from_usize(interned_id.as_id().index() as usize)),
- }
-}
-
-pub fn bound_var_to_type_or_const_param_idx(
- db: &dyn HirDatabase,
- var: rustc_type_ir::BoundVar,
-) -> TypeOrConstParamId {
- // SAFETY: We cannot really encapsulate this unfortunately, so just hope this is sound.
- let interned_id = InternedTypeOrConstParamId::from_id(unsafe { Id::from_index(var.as_u32()) });
- interned_id.loc(db)
-}
-
-pub fn bound_var_to_lifetime_idx(
- db: &dyn HirDatabase,
- var: rustc_type_ir::BoundVar,
-) -> LifetimeParamId {
- // SAFETY: We cannot really encapsulate this unfortunately, so just hope this is sound.
- let interned_id = InternedLifetimeParamId::from_id(unsafe { Id::from_index(var.as_u32()) });
- interned_id.loc(db)
-}
-
+// FIXME: This should urgently go (as soon as we finish the migration off Chalk, that is).
pub fn convert_binder_to_early_binder<'db, T: rustc_type_ir::TypeFoldable<DbInterner<'db>>>(
interner: DbInterner<'db>,
+ def: GenericDefId,
binder: rustc_type_ir::Binder<DbInterner<'db>, T>,
) -> rustc_type_ir::EarlyBinder<DbInterner<'db>, T> {
- let mut folder = BinderToEarlyBinder { interner, debruijn: rustc_type_ir::DebruijnIndex::ZERO };
+ let mut folder = BinderToEarlyBinder {
+ interner,
+ debruijn: rustc_type_ir::DebruijnIndex::ZERO,
+ params: crate::generics::generics(interner.db, def).iter_id().collect(),
+ };
rustc_type_ir::EarlyBinder::bind(binder.skip_binder().fold_with(&mut folder))
}
struct BinderToEarlyBinder<'db> {
interner: DbInterner<'db>,
debruijn: rustc_type_ir::DebruijnIndex,
+ params: Vec<GenericParamId>,
}
impl<'db> rustc_type_ir::TypeFolder<DbInterner<'db>> for BinderToEarlyBinder<'db> {
@@ -109,7 +90,13 @@ impl<'db> rustc_type_ir::TypeFolder<DbInterner<'db>> for BinderToEarlyBinder<'db
match t.kind() {
rustc_type_ir::TyKind::Bound(debruijn, bound_ty) if self.debruijn == debruijn => {
let var: rustc_type_ir::BoundVar = bound_ty.var();
- Ty::new(self.cx(), rustc_type_ir::TyKind::Param(ParamTy { index: var.as_u32() }))
+ let GenericParamId::TypeParamId(id) = self.params[bound_ty.var.as_usize()] else {
+ unreachable!()
+ };
+ Ty::new(
+ self.cx(),
+ rustc_type_ir::TyKind::Param(ParamTy { index: var.as_u32(), id }),
+ )
}
_ => t.super_fold_with(self),
}
@@ -119,10 +106,15 @@ impl<'db> rustc_type_ir::TypeFolder<DbInterner<'db>> for BinderToEarlyBinder<'db
match r.kind() {
rustc_type_ir::ReBound(debruijn, bound_region) if self.debruijn == debruijn => {
let var: rustc_type_ir::BoundVar = bound_region.var();
+ let GenericParamId::LifetimeParamId(id) = self.params[bound_region.var.as_usize()]
+ else {
+ unreachable!()
+ };
Region::new(
self.cx(),
rustc_type_ir::RegionKind::ReEarlyParam(EarlyParamRegion {
index: var.as_u32(),
+ id,
}),
)
}
@@ -133,9 +125,12 @@ impl<'db> rustc_type_ir::TypeFolder<DbInterner<'db>> for BinderToEarlyBinder<'db
fn fold_const(&mut self, c: Const<'db>) -> Const<'db> {
match c.kind() {
rustc_type_ir::ConstKind::Bound(debruijn, var) if self.debruijn == debruijn => {
+ let GenericParamId::ConstParamId(id) = self.params[var.as_usize()] else {
+ unreachable!()
+ };
Const::new(
self.cx(),
- rustc_type_ir::ConstKind::Param(ParamConst { index: var.as_u32() }),
+ rustc_type_ir::ConstKind::Param(ParamConst { index: var.as_u32(), id }),
)
}
_ => c.super_fold_with(self),
@@ -274,12 +269,6 @@ impl<'db> ChalkToNextSolver<'db, Ty<'db>> for chalk_ir::Ty<Interner> {
SolverDefId::TypeAliasId(crate::from_foreign_def_id(*foreign_def_id)),
),
chalk_ir::TyKind::Error => rustc_type_ir::TyKind::Error(ErrorGuaranteed),
- chalk_ir::TyKind::Placeholder(placeholder_index) => {
- rustc_type_ir::TyKind::Placeholder(PlaceholderTy::new_anon(
- placeholder_index.ui.to_nextsolver(interner),
- rustc_type_ir::BoundVar::from_usize(placeholder_index.idx),
- ))
- }
chalk_ir::TyKind::Dyn(dyn_ty) => {
// exists<type> { for<...> ^1.0: ... }
let bounds = BoundExistentialPredicates::new_from_iter(
@@ -405,6 +394,26 @@ impl<'db> ChalkToNextSolver<'db, Ty<'db>> for chalk_ir::Ty<Interner> {
rustc_type_ir::TyKind::FnPtr(sig_tys, header)
}
+ // The schema here is quite confusing.
+ // The new solver, like rustc, uses `Param` and `EarlyBinder` for generic params. It uses `BoundVar`
+ // and `Placeholder` together with `Binder` for HRTB, which we mostly don't handle.
+ // Chalk uses `Placeholder` for generic params and `BoundVar` quite liberally, and this is quite a
+ // problem. `chalk_ir::TyKind::BoundVar` can represent either HRTB or generic params, depending on the
+ // context. When returned from signature queries, the outer `Binders` represent the generic params.
+ // But there are also inner `Binders` for HRTB.
+ // AFAIK there is no way to tell which of the meanings is relevant, so we just use `rustc_type_ir::Bound`
+ // here, and hope for the best. If you are working with new solver types, therefore, use the new solver
+ // lower queries.
+ // Hopefully sooner than later Chalk will be ripped from the codebase and we can avoid that problem.
+ // For details about the rustc setup, read: https://rustc-dev-guide.rust-lang.org/generic_parameters_summary.html
+ // and the following chapters.
+ chalk_ir::TyKind::Placeholder(placeholder_index) => {
+ let (id, index) = from_placeholder_idx(interner.db, *placeholder_index);
+ rustc_type_ir::TyKind::Param(ParamTy {
+ id: TypeParamId::from_unchecked(id),
+ index,
+ })
+ }
chalk_ir::TyKind::BoundVar(bound_var) => rustc_type_ir::TyKind::Bound(
bound_var.debruijn.to_nextsolver(interner),
BoundTy {
@@ -440,10 +449,8 @@ impl<'db> ChalkToNextSolver<'db, Region<'db>> for chalk_ir::Lifetime<Interner> {
))
}
chalk_ir::LifetimeData::Placeholder(placeholder_index) => {
- rustc_type_ir::RegionKind::RePlaceholder(PlaceholderRegion::new_anon(
- rustc_type_ir::UniverseIndex::from_u32(placeholder_index.ui.counter as u32),
- rustc_type_ir::BoundVar::from_u32(placeholder_index.idx as u32),
- ))
+ let (id, index) = lt_from_placeholder_idx(interner.db, *placeholder_index);
+ rustc_type_ir::RegionKind::ReEarlyParam(EarlyParamRegion { id, index })
}
chalk_ir::LifetimeData::Static => rustc_type_ir::RegionKind::ReStatic,
chalk_ir::LifetimeData::Erased => rustc_type_ir::RegionKind::ReErased,
@@ -474,10 +481,11 @@ impl<'db> ChalkToNextSolver<'db, Const<'db>> for chalk_ir::Const<Interner> {
))
}
chalk_ir::ConstValue::Placeholder(placeholder_index) => {
- rustc_type_ir::ConstKind::Placeholder(PlaceholderConst::new(
- placeholder_index.ui.to_nextsolver(interner),
- rustc_type_ir::BoundVar::from_usize(placeholder_index.idx),
- ))
+ let (id, index) = from_placeholder_idx(interner.db, *placeholder_index);
+ rustc_type_ir::ConstKind::Param(ParamConst {
+ id: ConstParamId::from_unchecked(id),
+ index,
+ })
}
chalk_ir::ConstValue::Concrete(concrete_const) => match &concrete_const.interned {
ConstScalar::Bytes(bytes, memory) => {
@@ -971,7 +979,7 @@ pub fn convert_args_for_result<'db>(
substs.push(chalk_ir::GenericArgData::Ty(ty).intern(Interner));
}
rustc_type_ir::GenericArgKind::Lifetime(region) => {
- let lifetime = convert_region_for_result(region);
+ let lifetime = convert_region_for_result(interner, region);
substs.push(chalk_ir::GenericArgData::Lifetime(lifetime).intern(Interner));
}
rustc_type_ir::GenericArgKind::Const(const_) => {
@@ -1074,7 +1082,7 @@ pub(crate) fn convert_ty_for_result<'db>(interner: DbInterner<'db>, ty: Ty<'db>)
rustc_ast_ir::Mutability::Mut => chalk_ir::Mutability::Mut,
rustc_ast_ir::Mutability::Not => chalk_ir::Mutability::Not,
};
- let r = convert_region_for_result(r);
+ let r = convert_region_for_result(interner, r);
let ty = convert_ty_for_result(interner, ty);
TyKind::Ref(mutability, r, ty)
}
@@ -1122,17 +1130,23 @@ pub(crate) fn convert_ty_for_result<'db>(interner: DbInterner<'db>, ty: Ty<'db>)
rustc_type_ir::AliasTyKind::Free => unimplemented!(),
},
+ // For `Placeholder`, `Bound` and `Param`, see the comment on the reverse conversion.
rustc_type_ir::TyKind::Placeholder(placeholder) => {
- let ui = chalk_ir::UniverseIndex { counter: placeholder.universe.as_usize() };
- let placeholder_index =
- chalk_ir::PlaceholderIndex { idx: placeholder.bound.var.as_usize(), ui };
- TyKind::Placeholder(placeholder_index)
+ unimplemented!(
+ "A `rustc_type_ir::TyKind::Placeholder` doesn't have a direct \
+ correspondence in Chalk, as it represents a universally instantiated `Bound`.\n\
+ It therefore feels safer to leave it panicking, but if you hit this panic \
+ feel free to do the same as in `rustc_type_ir::TyKind::Bound` here."
+ )
}
-
rustc_type_ir::TyKind::Bound(debruijn_index, ty) => TyKind::BoundVar(chalk_ir::BoundVar {
debruijn: chalk_ir::DebruijnIndex::new(debruijn_index.as_u32()),
index: ty.var.as_usize(),
}),
+ rustc_type_ir::TyKind::Param(param) => {
+ let placeholder = to_placeholder_idx(interner.db, param.id.into(), param.index);
+ TyKind::Placeholder(placeholder)
+ }
rustc_type_ir::TyKind::FnPtr(bound_sig, fn_header) => {
let num_binders = bound_sig.bound_vars().len();
@@ -1254,7 +1268,8 @@ pub(crate) fn convert_ty_for_result<'db>(interner: DbInterner<'db>, ty: Ty<'db>)
chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
);
let bounds = chalk_ir::Binders::new(binders, bounds);
- let dyn_ty = chalk_ir::DynTy { bounds, lifetime: convert_region_for_result(region) };
+ let dyn_ty =
+ chalk_ir::DynTy { bounds, lifetime: convert_region_for_result(interner, region) };
TyKind::Dyn(dyn_ty)
}
@@ -1316,7 +1331,6 @@ pub(crate) fn convert_ty_for_result<'db>(interner: DbInterner<'db>, ty: Ty<'db>)
TyKind::CoroutineWitness(id.into(), subst)
}
- rustc_type_ir::TyKind::Param(_) => unimplemented!(),
rustc_type_ir::TyKind::UnsafeBinder(_) => unimplemented!(),
}
.intern(Interner)
@@ -1327,13 +1341,16 @@ pub fn convert_const_for_result<'db>(
const_: Const<'db>,
) -> crate::Const {
let value: chalk_ir::ConstValue<Interner> = match const_.kind() {
- rustc_type_ir::ConstKind::Param(_) => unimplemented!(),
rustc_type_ir::ConstKind::Infer(rustc_type_ir::InferConst::Var(var)) => {
chalk_ir::ConstValue::InferenceVar(chalk_ir::InferenceVar::from(var.as_u32()))
}
rustc_type_ir::ConstKind::Infer(rustc_type_ir::InferConst::Fresh(fresh)) => {
panic!("Vars should not be freshened.")
}
+ rustc_type_ir::ConstKind::Param(param) => {
+ let placeholder = to_placeholder_idx(interner.db, param.id.into(), param.index);
+ chalk_ir::ConstValue::Placeholder(placeholder)
+ }
rustc_type_ir::ConstKind::Bound(debruijn_index, var) => {
chalk_ir::ConstValue::BoundVar(chalk_ir::BoundVar::new(
chalk_ir::DebruijnIndex::new(debruijn_index.as_u32()),
@@ -1341,10 +1358,12 @@ pub fn convert_const_for_result<'db>(
))
}
rustc_type_ir::ConstKind::Placeholder(placeholder_const) => {
- chalk_ir::ConstValue::Placeholder(chalk_ir::PlaceholderIndex {
- ui: chalk_ir::UniverseIndex { counter: placeholder_const.universe.as_usize() },
- idx: placeholder_const.bound.as_usize(),
- })
+ unimplemented!(
+ "A `rustc_type_ir::ConstKind::Placeholder` doesn't have a direct \
+ correspondence in Chalk, as it represents a universally instantiated `Bound`.\n\
+ It therefore feels safer to leave it panicking, but if you hit this panic \
+ feel free to do the same as in `rustc_type_ir::ConstKind::Bound` here."
+ )
}
rustc_type_ir::ConstKind::Unevaluated(unevaluated_const) => {
let id = match unevaluated_const.def {
@@ -1381,36 +1400,34 @@ pub fn convert_const_for_result<'db>(
chalk_ir::ConstData { ty: crate::TyKind::Error.intern(Interner), value }.intern(Interner)
}
-pub fn convert_region_for_result<'db>(region: Region<'db>) -> crate::Lifetime {
- match region.kind() {
- rustc_type_ir::RegionKind::ReEarlyParam(early) => unimplemented!(),
- rustc_type_ir::RegionKind::ReBound(db, bound) => chalk_ir::Lifetime::new(
- Interner,
+pub fn convert_region_for_result<'db>(
+ interner: DbInterner<'db>,
+ region: Region<'db>,
+) -> crate::Lifetime {
+ let lifetime = match region.kind() {
+ rustc_type_ir::RegionKind::ReEarlyParam(early) => {
+ let placeholder = lt_to_placeholder_idx(interner.db, early.id, early.index);
+ chalk_ir::LifetimeData::Placeholder(placeholder)
+ }
+ rustc_type_ir::RegionKind::ReBound(db, bound) => {
chalk_ir::LifetimeData::BoundVar(chalk_ir::BoundVar::new(
chalk_ir::DebruijnIndex::new(db.as_u32()),
bound.var.as_usize(),
- )),
- ),
- rustc_type_ir::RegionKind::ReLateParam(_) => unimplemented!(),
- rustc_type_ir::RegionKind::ReStatic => {
- chalk_ir::Lifetime::new(Interner, chalk_ir::LifetimeData::Static)
+ ))
}
- rustc_type_ir::RegionKind::ReVar(vid) => chalk_ir::Lifetime::new(
- Interner,
- chalk_ir::LifetimeData::InferenceVar(chalk_ir::InferenceVar::from(vid.as_u32())),
- ),
- rustc_type_ir::RegionKind::RePlaceholder(placeholder) => chalk_ir::Lifetime::new(
- Interner,
- chalk_ir::LifetimeData::Placeholder(chalk_ir::PlaceholderIndex {
- idx: placeholder.bound.var.as_usize(),
- ui: chalk_ir::UniverseIndex { counter: placeholder.universe.as_usize() },
- }),
+ rustc_type_ir::RegionKind::RePlaceholder(placeholder) => unimplemented!(
+ "A `rustc_type_ir::RegionKind::RePlaceholder` doesn't have a direct \
+ correspondence in Chalk, as it represents a universally instantiated `Bound`.\n\
+ It therefore feels safer to leave it panicking, but if you hit this panic \
+ feel free to do the same as in `rustc_type_ir::RegionKind::ReBound` here."
),
- rustc_type_ir::RegionKind::ReErased => {
- chalk_ir::Lifetime::new(Interner, chalk_ir::LifetimeData::Erased)
- }
- rustc_type_ir::RegionKind::ReError(_) => {
- chalk_ir::Lifetime::new(Interner, chalk_ir::LifetimeData::Error)
+ rustc_type_ir::RegionKind::ReLateParam(_) => unimplemented!(),
+ rustc_type_ir::RegionKind::ReStatic => chalk_ir::LifetimeData::Static,
+ rustc_type_ir::RegionKind::ReVar(vid) => {
+ chalk_ir::LifetimeData::InferenceVar(chalk_ir::InferenceVar::from(vid.as_u32()))
}
- }
+ rustc_type_ir::RegionKind::ReErased => chalk_ir::LifetimeData::Erased,
+ rustc_type_ir::RegionKind::ReError(_) => chalk_ir::LifetimeData::Error,
+ };
+ chalk_ir::Lifetime::new(Interner, lifetime)
}
diff --git a/crates/hir-ty/src/next_solver/region.rs b/crates/hir-ty/src/next_solver/region.rs
index c59cdac5f9..d6214d9915 100644
--- a/crates/hir-ty/src/next_solver/region.rs
+++ b/crates/hir-ty/src/next_solver/region.rs
@@ -1,5 +1,6 @@
//! Things related to regions.
+use hir_def::LifetimeParamId;
use intern::{Interned, Symbol};
use rustc_type_ir::{
BoundVar, Flags, INNERMOST, RegionVid, TypeFlags, TypeFoldable, TypeVisitable, VisitorResult,
@@ -110,6 +111,8 @@ pub type PlaceholderRegion = Placeholder<BoundRegion>;
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct EarlyParamRegion {
+ // FIXME: See `ParamTy`.
+ pub id: LifetimeParamId,
pub index: u32,
}
diff --git a/crates/hir-ty/src/next_solver/ty.rs b/crates/hir-ty/src/next_solver/ty.rs
index 5ffae981a6..92f1076e75 100644
--- a/crates/hir-ty/src/next_solver/ty.rs
+++ b/crates/hir-ty/src/next_solver/ty.rs
@@ -1,5 +1,6 @@
//! Things related to tys in the next-trait-solver.
+use hir_def::{GenericDefId, TypeOrConstParamId, TypeParamId};
use intern::{Interned, Symbol, sym};
use rustc_abi::{Float, Integer, Size};
use rustc_ast_ir::{Mutability, try_visit, visit::VisitorResult};
@@ -64,8 +65,8 @@ impl<'db> Ty<'db> {
.unwrap()
}
- pub fn new_param(interner: DbInterner<'db>, index: u32, name: Symbol) -> Self {
- Ty::new(interner, TyKind::Param(ParamTy { index }))
+ pub fn new_param(interner: DbInterner<'db>, id: TypeParamId, index: u32, name: Symbol) -> Self {
+ Ty::new(interner, TyKind::Param(ParamTy { id, index }))
}
pub fn new_placeholder(interner: DbInterner<'db>, placeholder: PlaceholderTy) -> Self {
@@ -847,12 +848,16 @@ pub type PlaceholderTy = Placeholder<BoundTy>;
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct ParamTy {
+ // FIXME: I'm not pleased with this. Ideally a `Param` should only know its index - the defining item
+ // is known from the `EarlyBinder`. This should also be beneficial for memory usage. But code currently
+ // assumes it can get the definition from `Param` alone - so that's what we got.
+ pub id: TypeParamId,
pub index: u32,
}
impl ParamTy {
pub fn to_ty<'db>(self, interner: DbInterner<'db>) -> Ty<'db> {
- Ty::new_param(interner, self.index, sym::MISSING_NAME.clone())
+ Ty::new_param(interner, self.id, self.index, sym::MISSING_NAME.clone())
}
}
@@ -865,6 +870,7 @@ impl std::fmt::Debug for ParamTy {
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct BoundTy {
pub var: BoundVar,
+ // FIXME: This is for diagnostics in rustc, do we really need it?
pub kind: BoundTyKind,
}
diff --git a/crates/hir-ty/src/variance.rs b/crates/hir-ty/src/variance.rs
index d8a058533f..a1ebff04bb 100644
--- a/crates/hir-ty/src/variance.rs
+++ b/crates/hir-ty/src/variance.rs
@@ -344,7 +344,7 @@ impl Context<'_> {
// Chalk has no params, so use placeholders for now?
TyKind::Placeholder(index) => {
- let idx = crate::from_placeholder_idx(self.db, *index);
+ let idx = crate::from_placeholder_idx(self.db, *index).0;
let index = self.generics.type_or_const_param_idx(idx).unwrap();
self.constrain(index, variance);
}
@@ -445,7 +445,7 @@ impl Context<'_> {
);
match region.data(Interner) {
LifetimeData::Placeholder(index) => {
- let idx = crate::lt_from_placeholder_idx(self.db, *index);
+ let idx = crate::lt_from_placeholder_idx(self.db, *index).0;
let inferred = self.generics.lifetime_idx(idx).unwrap();
self.constrain(inferred, variance);
}
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index b9c5131ffb..833a9ef030 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -474,8 +474,8 @@ impl HirDisplay for TypeParam {
let param_data = &params[self.id.local_id()];
let substs = TyBuilder::placeholder_subst(f.db, self.id.parent());
let krate = self.id.parent().krate(f.db).id;
- let ty =
- TyKind::Placeholder(hir_ty::to_placeholder_idx(f.db, self.id.into())).intern(Interner);
+ let ty = TyKind::Placeholder(hir_ty::to_placeholder_idx_no_index(f.db, self.id.into()))
+ .intern(Interner);
let predicates = f.db.generic_predicates(self.id.parent());
let predicates = predicates
.iter()
@@ -528,8 +528,11 @@ impl HirDisplay for TypeParam {
f,
":",
Either::Left(
- &hir_ty::TyKind::Placeholder(hir_ty::to_placeholder_idx(f.db, self.id.into()))
- .intern(Interner),
+ &hir_ty::TyKind::Placeholder(hir_ty::to_placeholder_idx_no_index(
+ f.db,
+ self.id.into(),
+ ))
+ .intern(Interner),
),
&predicates,
default_sized,
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index f03f542e5b..46d3a2bcd6 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -4239,8 +4239,8 @@ impl TypeParam {
pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> {
let resolver = self.id.parent().resolver(db);
- let ty =
- TyKind::Placeholder(hir_ty::to_placeholder_idx(db, self.id.into())).intern(Interner);
+ let ty = TyKind::Placeholder(hir_ty::to_placeholder_idx_no_index(db, self.id.into()))
+ .intern(Interner);
Type::new_with_resolver_inner(db, &resolver, ty)
}
@@ -5933,7 +5933,7 @@ impl<'db> Type<'db> {
pub fn as_type_param(&self, db: &'db dyn HirDatabase) -> Option<TypeParam> {
match self.ty.kind(Interner) {
TyKind::Placeholder(p) => Some(TypeParam {
- id: TypeParamId::from_unchecked(hir_ty::from_placeholder_idx(db, *p)),
+ id: TypeParamId::from_unchecked(hir_ty::from_placeholder_idx(db, *p).0),
}),
_ => None,
}