aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir/src/lib.rs4
-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/infer/expr.rs9
-rw-r--r--crates/hir_ty/src/infer/pat.rs13
-rw-r--r--crates/hir_ty/src/infer/unify.rs4
-rw-r--r--crates/hir_ty/src/lib.rs29
-rw-r--r--crates/hir_ty/src/lower.rs4
-rw-r--r--crates/hir_ty/src/method_resolution.rs4
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs21
-rw-r--r--crates/hir_ty/src/types.rs4
-rw-r--r--crates/hir_ty/src/walk.rs10
12 files changed, 109 insertions, 45 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 813cd1295..dfc1d8a0c 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -1888,7 +1888,7 @@ impl Type {
1888 substs.iter(&Interner).filter_map(|a| a.ty(&Interner)).any(go) 1888 substs.iter(&Interner).filter_map(|a| a.ty(&Interner)).any(go)
1889 } 1889 }
1890 1890
1891 TyKind::Array(ty) 1891 TyKind::Array(ty, _)
1892 | TyKind::Slice(ty) 1892 | TyKind::Slice(ty)
1893 | TyKind::Raw(_, ty) 1893 | TyKind::Raw(_, ty)
1894 | TyKind::Ref(_, _, ty) => go(ty), 1894 | TyKind::Ref(_, _, ty) => go(ty),
@@ -2151,7 +2151,7 @@ impl Type {
2151 2151
2152 TyKind::Ref(_, _, ty) 2152 TyKind::Ref(_, _, ty)
2153 | TyKind::Raw(_, ty) 2153 | TyKind::Raw(_, ty)
2154 | TyKind::Array(ty) 2154 | TyKind::Array(ty, _)
2155 | TyKind::Slice(ty) => { 2155 | TyKind::Slice(ty) => {
2156 walk_type(db, &type_.derived(ty.clone()), cb); 2156 walk_type(db, &type_.derived(ty.clone()), cb);
2157 } 2157 }
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs
index 07510ae02..326c20240 100644
--- a/crates/hir_ty/src/db.rs
+++ b/crates/hir_ty/src/db.rs
@@ -88,6 +88,8 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
88 #[salsa::interned] 88 #[salsa::interned]
89 fn intern_lifetime_param_id(&self, param_id: LifetimeParamId) -> InternedLifetimeParamId; 89 fn intern_lifetime_param_id(&self, param_id: LifetimeParamId) -> InternedLifetimeParamId;
90 #[salsa::interned] 90 #[salsa::interned]
91 fn intern_const_param_id(&self, param_id: ConstParamId) -> InternedConstParamId;
92 #[salsa::interned]
91 fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId; 93 fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId;
92 #[salsa::interned] 94 #[salsa::interned]
93 fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> InternedClosureId; 95 fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> InternedClosureId;
@@ -162,6 +164,10 @@ pub struct InternedLifetimeParamId(salsa::InternId);
162impl_intern_key!(InternedLifetimeParamId); 164impl_intern_key!(InternedLifetimeParamId);
163 165
164#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 166#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
167pub struct InternedConstParamId(salsa::InternId);
168impl_intern_key!(InternedConstParamId);
169
170#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
165pub struct InternedOpaqueTyId(salsa::InternId); 171pub struct InternedOpaqueTyId(salsa::InternId);
166impl_intern_key!(InternedOpaqueTyId); 172impl_intern_key!(InternedOpaqueTyId);
167 173
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 22416c0cf..8fe4ed3fa 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -5,6 +5,7 @@ use std::{
5 fmt::{self, Debug}, 5 fmt::{self, Debug},
6}; 6};
7 7
8use chalk_ir::BoundVar;
8use hir_def::{ 9use hir_def::{
9 db::DefDatabase, 10 db::DefDatabase,
10 find_path, 11 find_path,
@@ -18,12 +19,12 @@ use hir_def::{
18use hir_expand::name::Name; 19use hir_expand::name::Name;
19 20
20use crate::{ 21use crate::{
21 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, 22 const_from_placeholder_idx, db::HirDatabase, from_assoc_type_id, from_foreign_def_id,
22 lt_from_placeholder_idx, primitive, subst_prefix, to_assoc_type_id, traits::chalk::from_chalk, 23 from_placeholder_idx, lt_from_placeholder_idx, primitive, subst_prefix, to_assoc_type_id,
23 utils::generics, AdtId, AliasEq, AliasTy, CallableDefId, CallableSig, DomainGoal, GenericArg, 24 traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy, CallableDefId,
24 ImplTraitId, Interner, Lifetime, LifetimeData, LifetimeOutlives, Mutability, OpaqueTy, 25 CallableSig, Const, ConstValue, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime,
25 ProjectionTy, ProjectionTyExt, QuantifiedWhereClause, Scalar, TraitRef, Ty, TyExt, TyKind, 26 LifetimeData, LifetimeOutlives, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt,
26 WhereClause, 27 QuantifiedWhereClause, Scalar, TraitRef, Ty, TyExt, TyKind, WhereClause,
27}; 28};
28 29
29pub struct HirFormatter<'a> { 30pub struct HirFormatter<'a> {
@@ -290,6 +291,29 @@ impl HirDisplay for GenericArg {
290 } 291 }
291} 292}
292 293
294impl 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
311impl HirDisplay for BoundVar {
312 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
313 write!(f, "?{}.{}", self.debruijn.depth(), self.index)
314 }
315}
316
293impl HirDisplay for Ty { 317impl HirDisplay for Ty {
294 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 318 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
295 if f.should_truncate() { 319 if f.should_truncate() {
@@ -309,10 +333,12 @@ impl HirDisplay for Ty {
309 t.hir_fmt(f)?; 333 t.hir_fmt(f)?;
310 write!(f, "]")?; 334 write!(f, "]")?;
311 } 335 }
312 TyKind::Array(t) => { 336 TyKind::Array(t, c) => {
313 write!(f, "[")?; 337 write!(f, "[")?;
314 t.hir_fmt(f)?; 338 t.hir_fmt(f)?;
315 write!(f, "; _]")?; 339 write!(f, "; ")?;
340 c.hir_fmt(f)?;
341 write!(f, "]")?;
316 } 342 }
317 TyKind::Raw(m, t) | TyKind::Ref(m, _, t) => { 343 TyKind::Raw(m, t) | TyKind::Ref(m, _, t) => {
318 let ty_display = 344 let ty_display =
@@ -617,7 +643,7 @@ impl HirDisplay for Ty {
617 } 643 }
618 } 644 }
619 } 645 }
620 TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 646 TyKind::BoundVar(idx) => idx.hir_fmt(f)?,
621 TyKind::Dyn(dyn_ty) => { 647 TyKind::Dyn(dyn_ty) => {
622 write_bounds_like_dyn_trait_with_prefix( 648 write_bounds_like_dyn_trait_with_prefix(
623 "dyn", 649 "dyn",
@@ -850,7 +876,7 @@ impl HirDisplay for Lifetime {
850impl HirDisplay for LifetimeData { 876impl HirDisplay for LifetimeData {
851 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 877 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
852 match self { 878 match self {
853 LifetimeData::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index), 879 LifetimeData::BoundVar(idx) => idx.hir_fmt(f),
854 LifetimeData::InferenceVar(_) => write!(f, "_"), 880 LifetimeData::InferenceVar(_) => write!(f, "_"),
855 LifetimeData::Placeholder(idx) => { 881 LifetimeData::Placeholder(idx) => {
856 let id = lt_from_placeholder_idx(f.db, *idx); 882 let id = lt_from_placeholder_idx(f.db, *idx);
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 796487d02..53d94fd0d 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -15,7 +15,7 @@ use stdx::always;
15use syntax::ast::RangeOp; 15use syntax::ast::RangeOp;
16 16
17use crate::{ 17use crate::{
18 autoderef, 18 autoderef, dummy_usize_const,
19 lower::lower_to_chalk_mutability, 19 lower::lower_to_chalk_mutability,
20 method_resolution, op, 20 method_resolution, op,
21 primitive::{self, UintTy}, 21 primitive::{self, UintTy},
@@ -702,7 +702,7 @@ impl<'a> InferenceContext<'a> {
702 } 702 }
703 Expr::Array(array) => { 703 Expr::Array(array) => {
704 let elem_ty = match expected.ty.kind(&Interner) { 704 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(),
706 _ => self.table.new_type_var(), 706 _ => self.table.new_type_var(),
707 }; 707 };
708 708
@@ -726,7 +726,7 @@ impl<'a> InferenceContext<'a> {
726 } 726 }
727 } 727 }
728 728
729 TyKind::Array(elem_ty).intern(&Interner) 729 TyKind::Array(elem_ty, dummy_usize_const()).intern(&Interner)
730 } 730 }
731 Expr::Literal(lit) => match lit { 731 Expr::Literal(lit) => match lit {
732 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), 732 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
@@ -736,7 +736,8 @@ impl<'a> InferenceContext<'a> {
736 } 736 }
737 Literal::ByteString(..) => { 737 Literal::ByteString(..) => {
738 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); 738 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);
740 TyKind::Ref(Mutability::Not, static_lifetime(), array_type).intern(&Interner) 741 TyKind::Ref(Mutability::Not, static_lifetime(), array_type).intern(&Interner)
741 } 742 }
742 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), 743 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner),
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 2848a393c..c1d7a6b76 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -214,17 +214,20 @@ impl<'a> InferenceContext<'a> {
214 return inner_ty; 214 return inner_ty;
215 } 215 }
216 Pat::Slice { prefix, slice, suffix } => { 216 Pat::Slice { prefix, slice, suffix } => {
217 let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.kind(&Interner) { 217 let elem_ty = match expected.kind(&Interner) {
218 TyKind::Array(st) => (TyKind::Array, st.clone()), 218 TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(),
219 TyKind::Slice(st) => (TyKind::Slice, st.clone()), 219 _ => self.err_ty(),
220 _ => (TyKind::Slice, self.err_ty()),
221 }; 220 };
222 221
223 for pat_id in prefix.iter().chain(suffix) { 222 for pat_id in prefix.iter().chain(suffix) {
224 self.infer_pat(*pat_id, &elem_ty, default_bm); 223 self.infer_pat(*pat_id, &elem_ty, default_bm);
225 } 224 }
226 225
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);
228 if let Some(slice_pat_id) = slice { 231 if let Some(slice_pat_id) = slice {
229 self.infer_pat(*slice_pat_id, &pat_ty, default_bm); 232 self.infer_pat(*slice_pat_id, &pat_ty, default_bm);
230 } 233 }
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index c7878ebfd..7d76cda68 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -317,9 +317,11 @@ impl InferenceTable {
317 | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => { 317 | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => {
318 self.unify_substs(substs1, substs2, depth + 1) 318 self.unify_substs(substs1, substs2, depth + 1)
319 } 319 }
320 (TyKind::Array(ty1, c1), TyKind::Array(ty2, c2)) if c1 == c2 => {
321 self.unify_inner(ty1, ty2, depth + 1)
322 }
320 (TyKind::Ref(_, _, ty1), TyKind::Ref(_, _, ty2)) 323 (TyKind::Ref(_, _, ty1), TyKind::Ref(_, _, ty2))
321 | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2)) 324 | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2))
322 | (TyKind::Array(ty1), TyKind::Array(ty2))
323 | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1), 325 | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1),
324 _ => true, /* we checked equals_ctor already */ 326 _ => true, /* we checked equals_ctor already */
325 } 327 }
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index bccc73449..a2a5bcc07 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -30,12 +30,13 @@ mod test_db;
30 30
31use std::sync::Arc; 31use std::sync::Arc;
32 32
33use chalk_ir::UintTy;
33use itertools::Itertools; 34use itertools::Itertools;
34 35
35use base_db::salsa; 36use base_db::salsa;
36use hir_def::{ 37use hir_def::{
37 expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId, GenericDefId, HasModule, 38 expr::ExprId, type_ref::Rawness, AssocContainerId, ConstParamId, FunctionId, GenericDefId,
38 LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, 39 HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId,
39}; 40};
40 41
41use crate::{db::HirDatabase, display::HirDisplay, utils::generics}; 42use crate::{db::HirDatabase, display::HirDisplay, utils::generics};
@@ -71,6 +72,11 @@ pub type Lifetime = chalk_ir::Lifetime<Interner>;
71pub type LifetimeData = chalk_ir::LifetimeData<Interner>; 72pub type LifetimeData = chalk_ir::LifetimeData<Interner>;
72pub type LifetimeOutlives = chalk_ir::LifetimeOutlives<Interner>; 73pub type LifetimeOutlives = chalk_ir::LifetimeOutlives<Interner>;
73 74
75pub type Const = chalk_ir::Const<Interner>;
76pub type ConstData = chalk_ir::ConstData<Interner>;
77pub type ConstValue = chalk_ir::ConstValue<Interner>;
78pub type ConcreteConst = chalk_ir::ConcreteConst<Interner>;
79
74pub type ChalkTraitId = chalk_ir::TraitId<Interner>; 80pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
75 81
76pub type FnSig = chalk_ir::FnSig<Interner>; 82pub type FnSig = chalk_ir::FnSig<Interner>;
@@ -227,7 +233,9 @@ impl Ty {
227 pub fn equals_ctor(&self, other: &Ty) -> bool { 233 pub fn equals_ctor(&self, other: &Ty) -> bool {
228 match (self.kind(&Interner), other.kind(&Interner)) { 234 match (self.kind(&Interner), other.kind(&Interner)) {
229 (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2, 235 (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 }
231 (TyKind::FnDef(def_id, ..), TyKind::FnDef(def_id2, ..)) => def_id == def_id2, 239 (TyKind::FnDef(def_id, ..), TyKind::FnDef(def_id2, ..)) => def_id == def_id2,
232 (TyKind::OpaqueType(ty_id, ..), TyKind::OpaqueType(ty_id2, ..)) => ty_id == ty_id2, 240 (TyKind::OpaqueType(ty_id, ..), TyKind::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
233 (TyKind::AssociatedType(ty_id, ..), TyKind::AssociatedType(ty_id2, ..)) => { 241 (TyKind::AssociatedType(ty_id, ..), TyKind::AssociatedType(ty_id2, ..)) => {
@@ -488,6 +496,12 @@ pub fn lt_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> L
488 db.lookup_intern_lifetime_param_id(interned_id) 496 db.lookup_intern_lifetime_param_id(interned_id)
489} 497}
490 498
499pub 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
491pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId { 505pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId {
492 chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id)) 506 chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id))
493} 507}
@@ -499,3 +513,12 @@ pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId {
499pub fn static_lifetime() -> Lifetime { 513pub fn static_lifetime() -> Lifetime {
500 LifetimeData::Static.intern(&Interner) 514 LifetimeData::Static.intern(&Interner)
501} 515}
516
517pub 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}
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index df6619af3..8be1bcddb 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -27,7 +27,7 @@ use stdx::impl_from;
27 27
28use crate::{ 28use crate::{
29 db::HirDatabase, 29 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,
31 traits::chalk::{Interner, ToChalk}, 31 traits::chalk::{Interner, ToChalk},
32 utils::{ 32 utils::{
33 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, 33 all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
@@ -166,7 +166,7 @@ impl<'a> TyLoweringContext<'a> {
166 } 166 }
167 TypeRef::Array(inner) => { 167 TypeRef::Array(inner) => {
168 let inner_ty = self.lower_ty(inner); 168 let inner_ty = self.lower_ty(inner);
169 TyKind::Array(inner_ty).intern(&Interner) 169 TyKind::Array(inner_ty, dummy_usize_const()).intern(&Interner)
170 } 170 }
171 TypeRef::Slice(inner) => { 171 TypeRef::Slice(inner) => {
172 let inner_ty = self.lower_ty(inner); 172 let inner_ty = self.lower_ty(inner);
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 436dea22b..5042bfbca 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -842,7 +842,9 @@ fn autoderef_method_receiver(
842) -> Vec<Canonical<Ty>> { 842) -> Vec<Canonical<Ty>> {
843 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); 843 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect();
844 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) 844 // 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 {
846 let kinds = deref_chain.last().unwrap().binders.clone(); 848 let kinds = deref_chain.last().unwrap().binders.clone();
847 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); 849 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner);
848 deref_chain.push(Canonical { value: unsized_ty, binders: kinds }) 850 deref_chain.push(Canonical { value: unsized_ty, binders: kinds })
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index 9267e32b5..cf73cb078 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -10,9 +10,10 @@ use base_db::salsa::InternKey;
10use hir_def::{GenericDefId, TypeAliasId}; 10use hir_def::{GenericDefId, TypeAliasId};
11 11
12use crate::{ 12use crate::{
13 chalk_ext::ProjectionTyExt, db::HirDatabase, primitive::UintTy, static_lifetime, AliasTy, 13 chalk_ext::ProjectionTyExt, db::HirDatabase, dummy_usize_const, static_lifetime, AliasTy,
14 CallableDefId, Canonical, DomainGoal, FnPointer, GenericArg, InEnvironment, Lifetime, OpaqueTy, 14 CallableDefId, Canonical, Const, DomainGoal, FnPointer, GenericArg, InEnvironment, Lifetime,
15 ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TypeWalk, WhereClause, 15 OpaqueTy, ProjectionTy, QuantifiedWhereClause, Substitution, TraitRef, Ty, TypeWalk,
16 WhereClause,
16}; 17};
17 18
18use super::interner::*; 19use super::interner::*;
@@ -23,7 +24,7 @@ impl ToChalk for Ty {
23 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> { 24 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
24 match self.into_inner() { 25 match self.into_inner() {
25 TyKind::Ref(m, lt, ty) => ref_to_chalk(db, m, lt, ty), 26 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),
27 TyKind::Function(FnPointer { sig, substitution: substs, .. }) => { 28 TyKind::Function(FnPointer { sig, substitution: substs, .. }) => {
28 let substitution = chalk_ir::FnSubst(substs.0.to_chalk(db)); 29 let substitution = chalk_ir::FnSubst(substs.0.to_chalk(db));
29 chalk_ir::TyKind::Function(chalk_ir::FnPointer { 30 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
@@ -110,7 +111,7 @@ impl ToChalk for Ty {
110 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { 111 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
111 match chalk.data(&Interner).kind.clone() { 112 match chalk.data(&Interner).kind.clone() {
112 chalk_ir::TyKind::Error => TyKind::Error, 113 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),
114 chalk_ir::TyKind::Placeholder(idx) => TyKind::Placeholder(idx), 115 chalk_ir::TyKind::Placeholder(idx) => TyKind::Placeholder(idx),
115 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => { 116 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => {
116 let associated_ty = proj.associated_ty_id; 117 let associated_ty = proj.associated_ty_id;
@@ -203,15 +204,9 @@ fn ref_to_chalk(
203 204
204/// We currently don't model constants, but Chalk does. So, we have to insert a 205/// We currently don't model constants, but Chalk does. So, we have to insert a
205/// fake constant here, because Chalks built-in logic may expect it to be there. 206/// fake constant here, because Chalks built-in logic may expect it to be there.
206fn array_to_chalk(db: &dyn HirDatabase, ty: Ty) -> chalk_ir::Ty<Interner> { 207fn array_to_chalk(db: &dyn HirDatabase, ty: Ty, _: Const) -> chalk_ir::Ty<Interner> {
207 let arg = ty.to_chalk(db); 208 let arg = ty.to_chalk(db);
208 let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner); 209 chalk_ir::TyKind::Array(arg, dummy_usize_const()).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)
215} 210}
216 211
217impl ToChalk for GenericArg { 212impl ToChalk for GenericArg {
diff --git a/crates/hir_ty/src/types.rs b/crates/hir_ty/src/types.rs
index 844e57896..89c0ddd1a 100644
--- a/crates/hir_ty/src/types.rs
+++ b/crates/hir_ty/src/types.rs
@@ -10,7 +10,7 @@ use chalk_ir::{
10use smallvec::SmallVec; 10use smallvec::SmallVec;
11 11
12use crate::{ 12use crate::{
13 AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId, 13 AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, Const, FnDefId, FnSig, ForeignDefId,
14 InferenceVar, Interner, Lifetime, OpaqueTyId, PlaceholderIndex, TypeWalk, VariableKind, 14 InferenceVar, Interner, Lifetime, OpaqueTyId, PlaceholderIndex, TypeWalk, VariableKind,
15 VariableKinds, 15 VariableKinds,
16}; 16};
@@ -114,7 +114,7 @@ pub enum TyKind {
114 Tuple(usize, Substitution), 114 Tuple(usize, Substitution),
115 115
116 /// An array with the given length. Written as `[T; n]`. 116 /// An array with the given length. Written as `[T; n]`.
117 Array(Ty), 117 Array(Ty, Const),
118 118
119 /// The pointee of an array slice. Written as `[T]`. 119 /// The pointee of an array slice. Written as `[T]`.
120 Slice(Ty), 120 Slice(Ty),
diff --git a/crates/hir_ty/src/walk.rs b/crates/hir_ty/src/walk.rs
index 4cc4e24fd..41ebf6137 100644
--- a/crates/hir_ty/src/walk.rs
+++ b/crates/hir_ty/src/walk.rs
@@ -153,7 +153,10 @@ impl TypeWalk for Ty {
153 p.walk(f); 153 p.walk(f);
154 } 154 }
155 } 155 }
156 TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, _, ty) | TyKind::Raw(_, ty) => { 156 TyKind::Slice(ty)
157 | TyKind::Array(ty, _)
158 | TyKind::Ref(_, _, ty)
159 | TyKind::Raw(_, ty) => {
157 ty.walk(f); 160 ty.walk(f);
158 } 161 }
159 TyKind::Function(fn_pointer) => { 162 TyKind::Function(fn_pointer) => {
@@ -187,7 +190,10 @@ impl TypeWalk for Ty {
187 TyKind::Alias(AliasTy::Opaque(o_ty)) => { 190 TyKind::Alias(AliasTy::Opaque(o_ty)) => {
188 o_ty.substitution.walk_mut_binders(f, binders); 191 o_ty.substitution.walk_mut_binders(f, binders);
189 } 192 }
190 TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, _, ty) | TyKind::Raw(_, ty) => { 193 TyKind::Slice(ty)
194 | TyKind::Array(ty, _)
195 | TyKind::Ref(_, _, ty)
196 | TyKind::Raw(_, ty) => {
191 ty.walk_mut_binders(f, binders); 197 ty.walk_mut_binders(f, binders);
192 } 198 }
193 TyKind::Function(fn_pointer) => { 199 TyKind::Function(fn_pointer) => {