Skip to content

Commit 002e72a

Browse files
bors[bot]Veykril
andauthored
Merge #8366
8366: Add chalk_ir::Const to TyKind::Array r=flodiebold a=Veykril CC #8313 Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
2 parents 047b531 + 9fbba7b commit 002e72a

File tree

12 files changed

+109
-45
lines changed

12 files changed

+109
-45
lines changed

crates/hir/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1888,7 +1888,7 @@ impl Type {
18881888
substs.iter(&Interner).filter_map(|a| a.ty(&Interner)).any(go)
18891889
}
18901890

1891-
TyKind::Array(ty)
1891+
TyKind::Array(ty, _)
18921892
| TyKind::Slice(ty)
18931893
| TyKind::Raw(_, ty)
18941894
| TyKind::Ref(_, _, ty) => go(ty),
@@ -2151,7 +2151,7 @@ impl Type {
21512151

21522152
TyKind::Ref(_, _, ty)
21532153
| TyKind::Raw(_, ty)
2154-
| TyKind::Array(ty)
2154+
| TyKind::Array(ty, _)
21552155
| TyKind::Slice(ty) => {
21562156
walk_type(db, &type_.derived(ty.clone()), cb);
21572157
}

crates/hir_ty/src/db.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
8888
#[salsa::interned]
8989
fn intern_lifetime_param_id(&self, param_id: LifetimeParamId) -> InternedLifetimeParamId;
9090
#[salsa::interned]
91+
fn intern_const_param_id(&self, param_id: ConstParamId) -> InternedConstParamId;
92+
#[salsa::interned]
9193
fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId;
9294
#[salsa::interned]
9395
fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> InternedClosureId;
@@ -161,6 +163,10 @@ impl_intern_key!(InternedTypeParamId);
161163
pub struct InternedLifetimeParamId(salsa::InternId);
162164
impl_intern_key!(InternedLifetimeParamId);
163165

166+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
167+
pub struct InternedConstParamId(salsa::InternId);
168+
impl_intern_key!(InternedConstParamId);
169+
164170
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
165171
pub struct InternedOpaqueTyId(salsa::InternId);
166172
impl_intern_key!(InternedOpaqueTyId);

crates/hir_ty/src/display.rs

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::{
55
fmt::{self, Debug},
66
};
77

8+
use chalk_ir::BoundVar;
89
use hir_def::{
910
db::DefDatabase,
1011
find_path,
@@ -18,12 +19,12 @@ use hir_def::{
1819
use hir_expand::name::Name;
1920

2021
use crate::{
21-
db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx,
22-
lt_from_placeholder_idx, primitive, subst_prefix, to_assoc_type_id, traits::chalk::from_chalk,
23-
utils::generics, AdtId, AliasEq, AliasTy, CallableDefId, CallableSig, DomainGoal, GenericArg,
24-
ImplTraitId, Interner, Lifetime, LifetimeData, LifetimeOutlives, Mutability, OpaqueTy,
25-
ProjectionTy, ProjectionTyExt, QuantifiedWhereClause, Scalar, TraitRef, Ty, TyExt, TyKind,
26-
WhereClause,
22+
const_from_placeholder_idx, db::HirDatabase, from_assoc_type_id, from_foreign_def_id,
23+
from_placeholder_idx, lt_from_placeholder_idx, primitive, subst_prefix, to_assoc_type_id,
24+
traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy, CallableDefId,
25+
CallableSig, Const, ConstValue, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime,
26+
LifetimeData, LifetimeOutlives, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt,
27+
QuantifiedWhereClause, Scalar, TraitRef, Ty, TyExt, TyKind, WhereClause,
2728
};
2829

2930
pub struct HirFormatter<'a> {
@@ -290,6 +291,29 @@ impl HirDisplay for GenericArg {
290291
}
291292
}
292293

294+
impl HirDisplay for Const {
295+
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
296+
let data = self.interned();
297+
match data.value {
298+
ConstValue::BoundVar(idx) => idx.hir_fmt(f),
299+
ConstValue::InferenceVar(..) => write!(f, "_"),
300+
ConstValue::Placeholder(idx) => {
301+
let id = const_from_placeholder_idx(f.db, idx);
302+
let generics = generics(f.db.upcast(), id.parent);
303+
let param_data = &generics.params.consts[id.local_id];
304+
write!(f, "{}", param_data.name)
305+
}
306+
ConstValue::Concrete(_) => write!(f, "_"),
307+
}
308+
}
309+
}
310+
311+
impl HirDisplay for BoundVar {
312+
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
313+
write!(f, "?{}.{}", self.debruijn.depth(), self.index)
314+
}
315+
}
316+
293317
impl HirDisplay for Ty {
294318
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
295319
if f.should_truncate() {
@@ -309,10 +333,12 @@ impl HirDisplay for Ty {
309333
t.hir_fmt(f)?;
310334
write!(f, "]")?;
311335
}
312-
TyKind::Array(t) => {
336+
TyKind::Array(t, c) => {
313337
write!(f, "[")?;
314338
t.hir_fmt(f)?;
315-
write!(f, "; _]")?;
339+
write!(f, "; ")?;
340+
c.hir_fmt(f)?;
341+
write!(f, "]")?;
316342
}
317343
TyKind::Raw(m, t) | TyKind::Ref(m, _, t) => {
318344
let ty_display =
@@ -617,7 +643,7 @@ impl HirDisplay for Ty {
617643
}
618644
}
619645
}
620-
TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?,
646+
TyKind::BoundVar(idx) => idx.hir_fmt(f)?,
621647
TyKind::Dyn(dyn_ty) => {
622648
write_bounds_like_dyn_trait_with_prefix(
623649
"dyn",
@@ -850,7 +876,7 @@ impl HirDisplay for Lifetime {
850876
impl HirDisplay for LifetimeData {
851877
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
852878
match self {
853-
LifetimeData::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index),
879+
LifetimeData::BoundVar(idx) => idx.hir_fmt(f),
854880
LifetimeData::InferenceVar(_) => write!(f, "_"),
855881
LifetimeData::Placeholder(idx) => {
856882
let id = lt_from_placeholder_idx(f.db, *idx);

crates/hir_ty/src/infer/expr.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use stdx::always;
1515
use syntax::ast::RangeOp;
1616

1717
use crate::{
18-
autoderef,
18+
autoderef, dummy_usize_const,
1919
lower::lower_to_chalk_mutability,
2020
method_resolution, op,
2121
primitive::{self, UintTy},
@@ -702,7 +702,7 @@ impl<'a> InferenceContext<'a> {
702702
}
703703
Expr::Array(array) => {
704704
let elem_ty = match expected.ty.kind(&Interner) {
705-
TyKind::Array(st) | TyKind::Slice(st) => st.clone(),
705+
TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(),
706706
_ => self.table.new_type_var(),
707707
};
708708

@@ -726,7 +726,7 @@ impl<'a> InferenceContext<'a> {
726726
}
727727
}
728728

729-
TyKind::Array(elem_ty).intern(&Interner)
729+
TyKind::Array(elem_ty, dummy_usize_const()).intern(&Interner)
730730
}
731731
Expr::Literal(lit) => match lit {
732732
Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
@@ -736,7 +736,8 @@ impl<'a> InferenceContext<'a> {
736736
}
737737
Literal::ByteString(..) => {
738738
let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner);
739-
let array_type = TyKind::Array(byte_type).intern(&Interner);
739+
let array_type =
740+
TyKind::Array(byte_type, dummy_usize_const()).intern(&Interner);
740741
TyKind::Ref(Mutability::Not, static_lifetime(), array_type).intern(&Interner)
741742
}
742743
Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner),

crates/hir_ty/src/infer/pat.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -214,17 +214,20 @@ impl<'a> InferenceContext<'a> {
214214
return inner_ty;
215215
}
216216
Pat::Slice { prefix, slice, suffix } => {
217-
let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.kind(&Interner) {
218-
TyKind::Array(st) => (TyKind::Array, st.clone()),
219-
TyKind::Slice(st) => (TyKind::Slice, st.clone()),
220-
_ => (TyKind::Slice, self.err_ty()),
217+
let elem_ty = match expected.kind(&Interner) {
218+
TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(),
219+
_ => self.err_ty(),
221220
};
222221

223222
for pat_id in prefix.iter().chain(suffix) {
224223
self.infer_pat(*pat_id, &elem_ty, default_bm);
225224
}
226225

227-
let pat_ty = container_ty(elem_ty).intern(&Interner);
226+
let pat_ty = match expected.kind(&Interner) {
227+
TyKind::Array(_, const_) => TyKind::Array(elem_ty, const_.clone()),
228+
_ => TyKind::Slice(elem_ty),
229+
}
230+
.intern(&Interner);
228231
if let Some(slice_pat_id) = slice {
229232
self.infer_pat(*slice_pat_id, &pat_ty, default_bm);
230233
}

crates/hir_ty/src/infer/unify.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,9 +317,11 @@ impl InferenceTable {
317317
| (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => {
318318
self.unify_substs(substs1, substs2, depth + 1)
319319
}
320+
(TyKind::Array(ty1, c1), TyKind::Array(ty2, c2)) if c1 == c2 => {
321+
self.unify_inner(ty1, ty2, depth + 1)
322+
}
320323
(TyKind::Ref(_, _, ty1), TyKind::Ref(_, _, ty2))
321324
| (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2))
322-
| (TyKind::Array(ty1), TyKind::Array(ty2))
323325
| (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1),
324326
_ => true, /* we checked equals_ctor already */
325327
}

crates/hir_ty/src/lib.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,13 @@ mod test_db;
3030

3131
use std::sync::Arc;
3232

33+
use chalk_ir::UintTy;
3334
use itertools::Itertools;
3435

3536
use base_db::salsa;
3637
use hir_def::{
37-
expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId, GenericDefId, HasModule,
38-
LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId,
38+
expr::ExprId, type_ref::Rawness, AssocContainerId, ConstParamId, FunctionId, GenericDefId,
39+
HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId,
3940
};
4041

4142
use crate::{db::HirDatabase, display::HirDisplay, utils::generics};
@@ -71,6 +72,11 @@ pub type Lifetime = chalk_ir::Lifetime<Interner>;
7172
pub type LifetimeData = chalk_ir::LifetimeData<Interner>;
7273
pub type LifetimeOutlives = chalk_ir::LifetimeOutlives<Interner>;
7374

75+
pub type Const = chalk_ir::Const<Interner>;
76+
pub type ConstData = chalk_ir::ConstData<Interner>;
77+
pub type ConstValue = chalk_ir::ConstValue<Interner>;
78+
pub type ConcreteConst = chalk_ir::ConcreteConst<Interner>;
79+
7480
pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
7581

7682
pub type FnSig = chalk_ir::FnSig<Interner>;
@@ -227,7 +233,9 @@ impl Ty {
227233
pub fn equals_ctor(&self, other: &Ty) -> bool {
228234
match (self.kind(&Interner), other.kind(&Interner)) {
229235
(TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2,
230-
(TyKind::Slice(_), TyKind::Slice(_)) | (TyKind::Array(_), TyKind::Array(_)) => true,
236+
(TyKind::Slice(_), TyKind::Slice(_)) | (TyKind::Array(_, _), TyKind::Array(_, _)) => {
237+
true
238+
}
231239
(TyKind::FnDef(def_id, ..), TyKind::FnDef(def_id2, ..)) => def_id == def_id2,
232240
(TyKind::OpaqueType(ty_id, ..), TyKind::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
233241
(TyKind::AssociatedType(ty_id, ..), TyKind::AssociatedType(ty_id2, ..)) => {
@@ -488,6 +496,12 @@ pub fn lt_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> L
488496
db.lookup_intern_lifetime_param_id(interned_id)
489497
}
490498

499+
pub fn const_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> ConstParamId {
500+
assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT);
501+
let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx));
502+
db.lookup_intern_const_param_id(interned_id)
503+
}
504+
491505
pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId {
492506
chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id))
493507
}
@@ -499,3 +513,12 @@ pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId {
499513
pub fn static_lifetime() -> Lifetime {
500514
LifetimeData::Static.intern(&Interner)
501515
}
516+
517+
pub fn dummy_usize_const() -> Const {
518+
let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner);
519+
chalk_ir::ConstData {
520+
ty: usize_ty,
521+
value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }),
522+
}
523+
.intern(&Interner)
524+
}

crates/hir_ty/src/lower.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use stdx::impl_from;
2727

2828
use crate::{
2929
db::HirDatabase,
30-
static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
30+
dummy_usize_const, static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
3131
traits::chalk::{Interner, ToChalk},
3232
utils::{
3333
all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
@@ -166,7 +166,7 @@ impl<'a> TyLoweringContext<'a> {
166166
}
167167
TypeRef::Array(inner) => {
168168
let inner_ty = self.lower_ty(inner);
169-
TyKind::Array(inner_ty).intern(&Interner)
169+
TyKind::Array(inner_ty, dummy_usize_const()).intern(&Interner)
170170
}
171171
TypeRef::Slice(inner) => {
172172
let inner_ty = self.lower_ty(inner);

crates/hir_ty/src/method_resolution.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,9 @@ fn autoderef_method_receiver(
842842
) -> Vec<Canonical<Ty>> {
843843
let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect();
844844
// As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
845-
if let Some(TyKind::Array(parameters)) = deref_chain.last().map(|ty| ty.value.kind(&Interner)) {
845+
if let Some(TyKind::Array(parameters, _)) =
846+
deref_chain.last().map(|ty| ty.value.kind(&Interner))
847+
{
846848
let kinds = deref_chain.last().unwrap().binders.clone();
847849
let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner);
848850
deref_chain.push(Canonical { value: unsized_ty, binders: kinds })

crates/hir_ty/src/traits/chalk/mapping.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ use base_db::salsa::InternKey;
1010
use hir_def::{GenericDefId, TypeAliasId};
1111

1212
use crate::{
13-
chalk_ext::ProjectionTyExt, db::HirDatabase, primitive::UintTy, static_lifetime, AliasTy,
14-
CallableDefId, Canonical, DomainGoal, FnPointer, GenericArg, InEnvironment, Lifetime, OpaqueTy,
15-
ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TypeWalk, WhereClause,
13+
chalk_ext::ProjectionTyExt, db::HirDatabase, dummy_usize_const, static_lifetime, AliasTy,
14+
CallableDefId, Canonical, Const, DomainGoal, FnPointer, GenericArg, InEnvironment, Lifetime,
15+
OpaqueTy, ProjectionTy, QuantifiedWhereClause, Substitution, TraitRef, Ty, TypeWalk,
16+
WhereClause,
1617
};
1718

1819
use super::interner::*;
@@ -23,7 +24,7 @@ impl ToChalk for Ty {
2324
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
2425
match self.into_inner() {
2526
TyKind::Ref(m, lt, ty) => ref_to_chalk(db, m, lt, ty),
26-
TyKind::Array(ty) => array_to_chalk(db, ty),
27+
TyKind::Array(ty, size) => array_to_chalk(db, ty, size),
2728
TyKind::Function(FnPointer { sig, substitution: substs, .. }) => {
2829
let substitution = chalk_ir::FnSubst(substs.0.to_chalk(db));
2930
chalk_ir::TyKind::Function(chalk_ir::FnPointer {
@@ -110,7 +111,7 @@ impl ToChalk for Ty {
110111
fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
111112
match chalk.data(&Interner).kind.clone() {
112113
chalk_ir::TyKind::Error => TyKind::Error,
113-
chalk_ir::TyKind::Array(ty, _size) => TyKind::Array(from_chalk(db, ty)),
114+
chalk_ir::TyKind::Array(ty, size) => TyKind::Array(from_chalk(db, ty), size),
114115
chalk_ir::TyKind::Placeholder(idx) => TyKind::Placeholder(idx),
115116
chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => {
116117
let associated_ty = proj.associated_ty_id;
@@ -203,15 +204,9 @@ fn ref_to_chalk(
203204

204205
/// We currently don't model constants, but Chalk does. So, we have to insert a
205206
/// fake constant here, because Chalks built-in logic may expect it to be there.
206-
fn array_to_chalk(db: &dyn HirDatabase, ty: Ty) -> chalk_ir::Ty<Interner> {
207+
fn array_to_chalk(db: &dyn HirDatabase, ty: Ty, _: Const) -> chalk_ir::Ty<Interner> {
207208
let arg = ty.to_chalk(db);
208-
let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner);
209-
let const_ = chalk_ir::ConstData {
210-
ty: usize_ty,
211-
value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }),
212-
}
213-
.intern(&Interner);
214-
chalk_ir::TyKind::Array(arg, const_).intern(&Interner)
209+
chalk_ir::TyKind::Array(arg, dummy_usize_const()).intern(&Interner)
215210
}
216211

217212
impl ToChalk for GenericArg {

0 commit comments

Comments
 (0)