aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty')
-rw-r--r--crates/hir_ty/src/autoderef.rs47
-rw-r--r--crates/hir_ty/src/builder.rs219
-rw-r--r--crates/hir_ty/src/chalk_cast.rs22
-rw-r--r--crates/hir_ty/src/chalk_ext.rs13
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs5
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs10
-rw-r--r--crates/hir_ty/src/diagnostics/match_check.rs7
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs8
-rw-r--r--crates/hir_ty/src/display.rs75
-rw-r--r--crates/hir_ty/src/infer.rs21
-rw-r--r--crates/hir_ty/src/infer/coerce.rs39
-rw-r--r--crates/hir_ty/src/infer/expr.rs136
-rw-r--r--crates/hir_ty/src/infer/pat.rs45
-rw-r--r--crates/hir_ty/src/infer/path.rs33
-rw-r--r--crates/hir_ty/src/infer/unify.rs72
-rw-r--r--crates/hir_ty/src/lib.rs323
-rw-r--r--crates/hir_ty/src/lower.rs137
-rw-r--r--crates/hir_ty/src/method_resolution.rs33
-rw-r--r--crates/hir_ty/src/op.rs12
-rw-r--r--crates/hir_ty/src/tests.rs2
-rw-r--r--crates/hir_ty/src/traits.rs2
-rw-r--r--crates/hir_ty/src/traits/chalk.rs26
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs39
-rw-r--r--crates/hir_ty/src/utils.rs24
24 files changed, 777 insertions, 573 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index dc5fc759a..70c56cc45 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -13,11 +13,9 @@ use log::{info, warn};
13 13
14use crate::{ 14use crate::{
15 db::HirDatabase, 15 db::HirDatabase,
16 to_assoc_type_id, to_chalk_trait_id,
17 traits::{InEnvironment, Solution}, 16 traits::{InEnvironment, Solution},
18 utils::generics, 17 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner, Ty,
19 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner, 18 TyBuilder, TyKind,
20 ProjectionTy, Substitution, TraitRef, Ty, TyKind,
21}; 19};
22 20
23const AUTODEREF_RECURSION_LIMIT: usize = 10; 21const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -57,21 +55,20 @@ fn deref_by_trait(
57 }; 55 };
58 let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?; 56 let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?;
59 57
60 let generic_params = generics(db.upcast(), target.into()); 58 let projection = {
61 if generic_params.len() != 1 { 59 let b = TyBuilder::assoc_type_projection(db, target);
62 // the Target type + Deref trait should only have one generic parameter, 60 if b.remaining() != 1 {
63 // namely Deref's Self type 61 // the Target type + Deref trait should only have one generic parameter,
64 return None; 62 // namely Deref's Self type
65 } 63 return None;
64 }
65 b.push(ty.goal.value.clone()).build()
66 };
66 67
67 // FIXME make the Canonical / bound var handling nicer 68 // FIXME make the Canonical / bound var handling nicer
68 69
69 let parameters =
70 Substitution::build_for_generics(&generic_params).push(ty.goal.value.clone()).build();
71
72 // Check that the type implements Deref at all 70 // Check that the type implements Deref at all
73 let trait_ref = 71 let trait_ref = projection.trait_ref(db);
74 TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() };
75 let implements_goal = Canonical { 72 let implements_goal = Canonical {
76 binders: ty.goal.binders.clone(), 73 binders: ty.goal.binders.clone(),
77 value: InEnvironment { 74 value: InEnvironment {
@@ -84,11 +81,8 @@ fn deref_by_trait(
84 } 81 }
85 82
86 // Now do the assoc type projection 83 // Now do the assoc type projection
87 let projection = AliasEq { 84 let alias_eq = AliasEq {
88 alias: AliasTy::Projection(ProjectionTy { 85 alias: AliasTy::Projection(projection),
89 associated_ty_id: to_assoc_type_id(target),
90 substitution: parameters,
91 }),
92 ty: TyKind::BoundVar(BoundVar::new( 86 ty: TyKind::BoundVar(BoundVar::new(
93 DebruijnIndex::INNERMOST, 87 DebruijnIndex::INNERMOST,
94 ty.goal.binders.len(&Interner), 88 ty.goal.binders.len(&Interner),
@@ -96,9 +90,7 @@ fn deref_by_trait(
96 .intern(&Interner), 90 .intern(&Interner),
97 }; 91 };
98 92
99 let obligation = projection.cast(&Interner); 93 let in_env = InEnvironment { goal: alias_eq.cast(&Interner), environment: ty.environment };
100
101 let in_env = InEnvironment { goal: obligation, environment: ty.environment };
102 94
103 let canonical = Canonical { 95 let canonical = Canonical {
104 value: in_env, 96 value: in_env,
@@ -131,7 +123,7 @@ fn deref_by_trait(
131 // new variables in that case 123 // new variables in that case
132 124
133 for i in 1..vars.0.binders.len(&Interner) { 125 for i in 1..vars.0.binders.len(&Interner) {
134 if vars.0.value[i - 1].interned(&Interner) 126 if vars.0.value.at(&Interner, i - 1).assert_ty_ref(&Interner).kind(&Interner)
135 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 127 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
136 { 128 {
137 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution); 129 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
@@ -139,7 +131,12 @@ fn deref_by_trait(
139 } 131 }
140 } 132 }
141 Some(Canonical { 133 Some(Canonical {
142 value: vars.0.value[vars.0.value.len() - 1].clone(), 134 value: vars
135 .0
136 .value
137 .at(&Interner, vars.0.value.len(&Interner) - 1)
138 .assert_ty_ref(&Interner)
139 .clone(),
143 binders: vars.0.binders.clone(), 140 binders: vars.0.binders.clone(),
144 }) 141 })
145 } 142 }
diff --git a/crates/hir_ty/src/builder.rs b/crates/hir_ty/src/builder.rs
new file mode 100644
index 000000000..4a9a8058f
--- /dev/null
+++ b/crates/hir_ty/src/builder.rs
@@ -0,0 +1,219 @@
1//! `TyBuilder`, a helper for building instances of `Ty` and related types.
2
3use std::iter;
4
5use chalk_ir::{
6 cast::{Cast, CastTo, Caster},
7 interner::HasInterner,
8 AdtId, BoundVar, DebruijnIndex, Safety, Scalar,
9};
10use hir_def::{builtin_type::BuiltinType, GenericDefId, TraitId, TypeAliasId};
11use smallvec::SmallVec;
12
13use crate::{
14 db::HirDatabase, primitive, to_assoc_type_id, to_chalk_trait_id, utils::generics, Binders,
15 CallableSig, FnPointer, FnSig, GenericArg, Interner, ProjectionTy, Substitution, TraitRef, Ty,
16 TyDefId, TyKind, TypeWalk, ValueTyDefId,
17};
18
19/// This is a builder for `Ty` or anything that needs a `Substitution`.
20pub struct TyBuilder<D> {
21 /// The `data` field is used to keep track of what we're building (e.g. an
22 /// ADT, a `TraitRef`, ...).
23 data: D,
24 vec: SmallVec<[GenericArg; 2]>,
25 param_count: usize,
26}
27
28impl<D> TyBuilder<D> {
29 fn new(data: D, param_count: usize) -> TyBuilder<D> {
30 TyBuilder { data, param_count, vec: SmallVec::with_capacity(param_count) }
31 }
32
33 fn build_internal(self) -> (D, Substitution) {
34 assert_eq!(self.vec.len(), self.param_count);
35 // FIXME: would be good to have a way to construct a chalk_ir::Substitution from the interned form
36 let subst = Substitution(self.vec);
37 (self.data, subst)
38 }
39
40 pub fn push(mut self, arg: impl CastTo<GenericArg>) -> Self {
41 self.vec.push(arg.cast(&Interner));
42 self
43 }
44
45 pub fn remaining(&self) -> usize {
46 self.param_count - self.vec.len()
47 }
48
49 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self {
50 self.fill(
51 (starting_from..)
52 .map(|idx| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)),
53 )
54 }
55
56 pub fn fill_with_unknown(self) -> Self {
57 self.fill(iter::repeat(TyKind::Unknown.intern(&Interner)))
58 }
59
60 pub fn fill(mut self, filler: impl Iterator<Item = impl CastTo<GenericArg>>) -> Self {
61 self.vec.extend(filler.take(self.remaining()).casted(&Interner));
62 assert_eq!(self.remaining(), 0);
63 self
64 }
65
66 pub fn use_parent_substs(mut self, parent_substs: &Substitution) -> Self {
67 assert!(self.vec.is_empty());
68 assert!(parent_substs.len(&Interner) <= self.param_count);
69 self.vec.extend(parent_substs.iter(&Interner).cloned());
70 self
71 }
72}
73
74impl TyBuilder<()> {
75 pub fn unit() -> Ty {
76 TyKind::Tuple(0, Substitution::empty(&Interner)).intern(&Interner)
77 }
78
79 pub fn fn_ptr(sig: CallableSig) -> Ty {
80 TyKind::Function(FnPointer {
81 num_args: sig.params().len(),
82 sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs },
83 substs: Substitution::from_iter(&Interner, sig.params_and_return.iter().cloned()),
84 })
85 .intern(&Interner)
86 }
87
88 pub fn builtin(builtin: BuiltinType) -> Ty {
89 match builtin {
90 BuiltinType::Char => TyKind::Scalar(Scalar::Char).intern(&Interner),
91 BuiltinType::Bool => TyKind::Scalar(Scalar::Bool).intern(&Interner),
92 BuiltinType::Str => TyKind::Str.intern(&Interner),
93 BuiltinType::Int(t) => {
94 TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))).intern(&Interner)
95 }
96 BuiltinType::Uint(t) => {
97 TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))).intern(&Interner)
98 }
99 BuiltinType::Float(t) => {
100 TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))).intern(&Interner)
101 }
102 }
103 }
104
105 pub fn type_params_subst(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substitution {
106 let params = generics(db.upcast(), def.into());
107 params.type_params_subst(db)
108 }
109
110 pub fn subst_for_def(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> TyBuilder<()> {
111 let def = def.into();
112 let params = generics(db.upcast(), def);
113 let param_count = params.len();
114 TyBuilder::new((), param_count)
115 }
116
117 pub fn build(self) -> Substitution {
118 let ((), subst) = self.build_internal();
119 subst
120 }
121}
122
123impl TyBuilder<hir_def::AdtId> {
124 pub fn adt(db: &dyn HirDatabase, adt: hir_def::AdtId) -> TyBuilder<hir_def::AdtId> {
125 let generics = generics(db.upcast(), adt.into());
126 let param_count = generics.len();
127 TyBuilder::new(adt, param_count)
128 }
129
130 pub fn fill_with_defaults(
131 mut self,
132 db: &dyn HirDatabase,
133 mut fallback: impl FnMut() -> Ty,
134 ) -> Self {
135 let defaults = db.generic_defaults(self.data.into());
136 for default_ty in defaults.iter().skip(self.vec.len()) {
137 if default_ty.skip_binders().is_unknown() {
138 self.vec.push(fallback().cast(&Interner));
139 } else {
140 // each default can depend on the previous parameters
141 let subst_so_far = Substitution(self.vec.clone());
142 self.vec.push(default_ty.clone().subst(&subst_so_far).cast(&Interner));
143 }
144 }
145 self
146 }
147
148 pub fn build(self) -> Ty {
149 let (adt, subst) = self.build_internal();
150 TyKind::Adt(AdtId(adt), subst).intern(&Interner)
151 }
152}
153
154pub struct Tuple(usize);
155impl TyBuilder<Tuple> {
156 pub fn tuple(size: usize) -> TyBuilder<Tuple> {
157 TyBuilder::new(Tuple(size), size)
158 }
159
160 pub fn build(self) -> Ty {
161 let (Tuple(size), subst) = self.build_internal();
162 TyKind::Tuple(size, subst).intern(&Interner)
163 }
164}
165
166impl TyBuilder<TraitId> {
167 pub fn trait_ref(db: &dyn HirDatabase, trait_id: TraitId) -> TyBuilder<TraitId> {
168 let generics = generics(db.upcast(), trait_id.into());
169 let param_count = generics.len();
170 TyBuilder::new(trait_id, param_count)
171 }
172
173 pub fn build(self) -> TraitRef {
174 let (trait_id, substitution) = self.build_internal();
175 TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution }
176 }
177}
178
179impl TyBuilder<TypeAliasId> {
180 pub fn assoc_type_projection(
181 db: &dyn HirDatabase,
182 type_alias: TypeAliasId,
183 ) -> TyBuilder<TypeAliasId> {
184 let generics = generics(db.upcast(), type_alias.into());
185 let param_count = generics.len();
186 TyBuilder::new(type_alias, param_count)
187 }
188
189 pub fn build(self) -> ProjectionTy {
190 let (type_alias, substitution) = self.build_internal();
191 ProjectionTy { associated_ty_id: to_assoc_type_id(type_alias), substitution }
192 }
193}
194
195impl<T: TypeWalk + HasInterner<Interner = Interner>> TyBuilder<Binders<T>> {
196 fn subst_binders(b: Binders<T>) -> Self {
197 let param_count = b.num_binders;
198 TyBuilder::new(b, param_count)
199 }
200
201 pub fn build(self) -> T {
202 let (b, subst) = self.build_internal();
203 b.subst(&subst)
204 }
205}
206
207impl TyBuilder<Binders<Ty>> {
208 pub fn def_ty(db: &dyn HirDatabase, def: TyDefId) -> TyBuilder<Binders<Ty>> {
209 TyBuilder::subst_binders(db.ty(def.into()))
210 }
211
212 pub fn impl_self_ty(db: &dyn HirDatabase, def: hir_def::ImplId) -> TyBuilder<Binders<Ty>> {
213 TyBuilder::subst_binders(db.impl_self_ty(def))
214 }
215
216 pub fn value_ty(db: &dyn HirDatabase, def: ValueTyDefId) -> TyBuilder<Binders<Ty>> {
217 TyBuilder::subst_binders(db.value_ty(def))
218 }
219}
diff --git a/crates/hir_ty/src/chalk_cast.rs b/crates/hir_ty/src/chalk_cast.rs
index bf884ae15..df6492113 100644
--- a/crates/hir_ty/src/chalk_cast.rs
+++ b/crates/hir_ty/src/chalk_cast.rs
@@ -5,7 +5,7 @@ use chalk_ir::{
5 interner::HasInterner, 5 interner::HasInterner,
6}; 6};
7 7
8use crate::{AliasEq, DomainGoal, Interner, TraitRef, WhereClause}; 8use crate::{AliasEq, DomainGoal, GenericArg, GenericArgData, Interner, TraitRef, Ty, WhereClause};
9 9
10macro_rules! has_interner { 10macro_rules! has_interner {
11 ($t:ty) => { 11 ($t:ty) => {
@@ -17,6 +17,8 @@ macro_rules! has_interner {
17 17
18has_interner!(WhereClause); 18has_interner!(WhereClause);
19has_interner!(DomainGoal); 19has_interner!(DomainGoal);
20has_interner!(GenericArg);
21has_interner!(Ty);
20 22
21impl CastTo<WhereClause> for TraitRef { 23impl CastTo<WhereClause> for TraitRef {
22 fn cast_to(self, _interner: &Interner) -> WhereClause { 24 fn cast_to(self, _interner: &Interner) -> WhereClause {
@@ -36,6 +38,12 @@ impl CastTo<DomainGoal> for WhereClause {
36 } 38 }
37} 39}
38 40
41impl CastTo<GenericArg> for Ty {
42 fn cast_to(self, interner: &Interner) -> GenericArg {
43 GenericArg::new(interner, GenericArgData::Ty(self))
44 }
45}
46
39macro_rules! transitive_impl { 47macro_rules! transitive_impl {
40 ($a:ty, $b:ty, $c:ty) => { 48 ($a:ty, $b:ty, $c:ty) => {
41 impl CastTo<$c> for $a { 49 impl CastTo<$c> for $a {
@@ -51,3 +59,15 @@ macro_rules! transitive_impl {
51 59
52transitive_impl!(TraitRef, WhereClause, DomainGoal); 60transitive_impl!(TraitRef, WhereClause, DomainGoal);
53transitive_impl!(AliasEq, WhereClause, DomainGoal); 61transitive_impl!(AliasEq, WhereClause, DomainGoal);
62
63macro_rules! reflexive_impl {
64 ($a:ty) => {
65 impl CastTo<$a> for $a {
66 fn cast_to(self, _interner: &Interner) -> $a {
67 self
68 }
69 }
70 };
71}
72
73reflexive_impl!(GenericArg);
diff --git a/crates/hir_ty/src/chalk_ext.rs b/crates/hir_ty/src/chalk_ext.rs
new file mode 100644
index 000000000..b7463366b
--- /dev/null
+++ b/crates/hir_ty/src/chalk_ext.rs
@@ -0,0 +1,13 @@
1//! Various extensions traits for Chalk types.
2
3use crate::{Interner, Ty, TyKind};
4
5pub trait TyExt {
6 fn is_unit(&self) -> bool;
7}
8
9impl TyExt for Ty {
10 fn is_unit(&self) -> bool {
11 matches!(self.kind(&Interner), TyKind::Tuple(0, _))
12 }
13}
diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs
index 33a0f4d7d..1c9f9ede7 100644
--- a/crates/hir_ty/src/diagnostics/decl_check.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check.rs
@@ -91,7 +91,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
91 91
92 fn validate_func(&mut self, func: FunctionId) { 92 fn validate_func(&mut self, func: FunctionId) {
93 let data = self.db.function_data(func); 93 let data = self.db.function_data(func);
94 if data.is_in_extern_block { 94 if data.is_in_extern_block() {
95 cov_mark::hit!(extern_func_incorrect_case_ignored); 95 cov_mark::hit!(extern_func_incorrect_case_ignored);
96 return; 96 return;
97 } 97 }
@@ -99,8 +99,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
99 let body = self.db.body(func.into()); 99 let body = self.db.body(func.into());
100 100
101 // Recursively validate inner scope items, such as static variables and constants. 101 // Recursively validate inner scope items, such as static variables and constants.
102 let db = self.db; 102 for (_, block_def_map) in body.blocks(self.db.upcast()) {
103 for block_def_map in body.block_scopes.iter().filter_map(|block| db.block_def_map(*block)) {
104 for (_, module) in block_def_map.modules() { 103 for (_, module) in block_def_map.modules() {
105 for def_id in module.scope.declarations() { 104 for def_id in module.scope.declarations() {
106 let mut validator = DeclValidator::new(self.db, self.krate, self.sink); 105 let mut validator = DeclValidator::new(self.db, self.krate, self.sink);
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index 3909ad354..8169b759f 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -15,7 +15,7 @@ use crate::{
15 MissingPatFields, RemoveThisSemicolon, 15 MissingPatFields, RemoveThisSemicolon,
16 }, 16 },
17 utils::variant_data, 17 utils::variant_data,
18 AdtId, InferenceResult, Interner, Ty, TyKind, 18 AdtId, InferenceResult, Interner, TyExt, TyKind,
19}; 19};
20 20
21pub(crate) use hir_def::{ 21pub(crate) use hir_def::{
@@ -378,7 +378,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
378 _ => return, 378 _ => return,
379 }; 379 };
380 380
381 let (params, required) = match mismatch.expected.interned(&Interner) { 381 let (params, required) = match mismatch.expected.kind(&Interner) {
382 TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters) 382 TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters)
383 if *enum_id == core_result_enum => 383 if *enum_id == core_result_enum =>
384 { 384 {
@@ -392,7 +392,9 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
392 _ => return, 392 _ => return,
393 }; 393 };
394 394
395 if params.len() > 0 && params[0] == mismatch.actual { 395 if params.len(&Interner) > 0
396 && params.at(&Interner, 0).ty(&Interner) == Some(&mismatch.actual)
397 {
396 let (_, source_map) = db.body_with_source_map(self.owner); 398 let (_, source_map) = db.body_with_source_map(self.owner);
397 399
398 if let Ok(source_ptr) = source_map.expr_syntax(id) { 400 if let Ok(source_ptr) = source_map.expr_syntax(id) {
@@ -421,7 +423,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
421 None => return, 423 None => return,
422 }; 424 };
423 425
424 if mismatch.actual != Ty::unit() || mismatch.expected != *possible_tail_ty { 426 if !mismatch.actual.is_unit() || mismatch.expected != *possible_tail_ty {
425 return; 427 return;
426 } 428 }
427 429
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs
index 9cb472b51..34291578a 100644
--- a/crates/hir_ty/src/diagnostics/match_check.rs
+++ b/crates/hir_ty/src/diagnostics/match_check.rs
@@ -626,7 +626,7 @@ pub(super) fn is_useful(
626 // - enum with no variants 626 // - enum with no variants
627 // - `!` type 627 // - `!` type
628 // In those cases, no match arm is useful. 628 // In those cases, no match arm is useful.
629 match cx.infer[cx.match_expr].strip_references().interned(&Interner) { 629 match cx.infer[cx.match_expr].strip_references().kind(&Interner) {
630 TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ..) => { 630 TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ..) => {
631 if cx.db.enum_data(*enum_id).variants.is_empty() { 631 if cx.db.enum_data(*enum_id).variants.is_empty() {
632 return Ok(Usefulness::NotUseful); 632 return Ok(Usefulness::NotUseful);
@@ -792,7 +792,10 @@ fn pat_constructor(cx: &MatchCheckCtx, pat: PatIdOrWild) -> MatchCheckResult<Opt
792 Pat::Tuple { .. } => { 792 Pat::Tuple { .. } => {
793 let pat_id = pat.as_id().expect("we already know this pattern is not a wild"); 793 let pat_id = pat.as_id().expect("we already know this pattern is not a wild");
794 Some(Constructor::Tuple { 794 Some(Constructor::Tuple {
795 arity: cx.infer.type_of_pat[pat_id].as_tuple().ok_or(MatchCheckErr::Unknown)?.len(), 795 arity: cx.infer.type_of_pat[pat_id]
796 .as_tuple()
797 .ok_or(MatchCheckErr::Unknown)?
798 .len(&Interner),
796 }) 799 })
797 } 800 }
798 Pat::Lit(lit_expr) => match cx.body.exprs[lit_expr] { 801 Pat::Lit(lit_expr) => match cx.body.exprs[lit_expr] {
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs
index 1f49a4909..b5efe9df5 100644
--- a/crates/hir_ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs
@@ -32,7 +32,7 @@ impl<'a, 'b> UnsafeValidator<'a, 'b> {
32 let def = self.owner; 32 let def = self.owner;
33 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def); 33 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def);
34 let is_unsafe = match self.owner { 34 let is_unsafe = match self.owner {
35 DefWithBodyId::FunctionId(it) => db.function_data(it).qualifier.is_unsafe, 35 DefWithBodyId::FunctionId(it) => db.function_data(it).is_unsafe(),
36 DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false, 36 DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false,
37 }; 37 };
38 if is_unsafe 38 if is_unsafe
@@ -86,7 +86,7 @@ fn walk_unsafe(
86 match expr { 86 match expr {
87 &Expr::Call { callee, .. } => { 87 &Expr::Call { callee, .. } => {
88 if let Some(func) = infer[callee].as_fn_def(db) { 88 if let Some(func) = infer[callee].as_fn_def(db) {
89 if db.function_data(func).qualifier.is_unsafe { 89 if db.function_data(func).is_unsafe() {
90 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 90 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
91 } 91 }
92 } 92 }
@@ -103,14 +103,14 @@ fn walk_unsafe(
103 Expr::MethodCall { .. } => { 103 Expr::MethodCall { .. } => {
104 if infer 104 if infer
105 .method_resolution(current) 105 .method_resolution(current)
106 .map(|func| db.function_data(func).qualifier.is_unsafe) 106 .map(|func| db.function_data(func).is_unsafe())
107 .unwrap_or(false) 107 .unwrap_or(false)
108 { 108 {
109 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 109 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
110 } 110 }
111 } 111 }
112 Expr::UnaryOp { expr, op: UnaryOp::Deref } => { 112 Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
113 if let TyKind::Raw(..) = &infer[*expr].interned(&Interner) { 113 if let TyKind::Raw(..) = &infer[*expr].kind(&Interner) {
114 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 114 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
115 } 115 }
116 } 116 }
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 51480304b..385bd9405 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -8,7 +8,7 @@ use hir_def::{
8 find_path, 8 find_path,
9 generics::TypeParamProvenance, 9 generics::TypeParamProvenance,
10 item_scope::ItemInNs, 10 item_scope::ItemInNs,
11 path::{GenericArg, Path, PathKind}, 11 path::{Path, PathKind},
12 type_ref::{TypeBound, TypeRef}, 12 type_ref::{TypeBound, TypeRef},
13 visibility::Visibility, 13 visibility::Visibility,
14 AssocContainerId, Lookup, ModuleId, TraitId, 14 AssocContainerId, Lookup, ModuleId, TraitId,
@@ -18,8 +18,8 @@ use hir_expand::name::Name;
18use crate::{ 18use crate::{
19 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, 19 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive,
20 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy, 20 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy,
21 CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy, 21 CallableDefId, CallableSig, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, OpaqueTy,
22 ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause, 22 ProjectionTy, QuantifiedWhereClause, Scalar, TraitRef, Ty, TyExt, TyKind, WhereClause,
23}; 23};
24 24
25pub struct HirFormatter<'a> { 25pub struct HirFormatter<'a> {
@@ -251,16 +251,16 @@ impl HirDisplay for ProjectionTy {
251 } 251 }
252 252
253 let trait_ = f.db.trait_data(self.trait_(f.db)); 253 let trait_ = f.db.trait_data(self.trait_(f.db));
254 let first_parameter = self.substitution[0].into_displayable( 254 let first_parameter = self.self_type_parameter().into_displayable(
255 f.db, 255 f.db,
256 f.max_size, 256 f.max_size,
257 f.omit_verbose_types, 257 f.omit_verbose_types,
258 f.display_target, 258 f.display_target,
259 ); 259 );
260 write!(f, "<{} as {}", first_parameter, trait_.name)?; 260 write!(f, "<{} as {}", first_parameter, trait_.name)?;
261 if self.substitution.len() > 1 { 261 if self.substitution.len(&Interner) > 1 {
262 write!(f, "<")?; 262 write!(f, "<")?;
263 f.write_joined(&self.substitution[1..], ", ")?; 263 f.write_joined(&self.substitution.interned(&Interner)[1..], ", ")?;
264 write!(f, ">")?; 264 write!(f, ">")?;
265 } 265 }
266 write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?; 266 write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?;
@@ -274,7 +274,15 @@ impl HirDisplay for OpaqueTy {
274 return write!(f, "{}", TYPE_HINT_TRUNCATION); 274 return write!(f, "{}", TYPE_HINT_TRUNCATION);
275 } 275 }
276 276
277 self.substitution[0].hir_fmt(f) 277 self.substitution.at(&Interner, 0).hir_fmt(f)
278 }
279}
280
281impl HirDisplay for GenericArg {
282 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
283 match self.interned() {
284 crate::GenericArgData::Ty(ty) => ty.hir_fmt(f),
285 }
278 } 286 }
279} 287}
280 288
@@ -284,7 +292,7 @@ impl HirDisplay for Ty {
284 return write!(f, "{}", TYPE_HINT_TRUNCATION); 292 return write!(f, "{}", TYPE_HINT_TRUNCATION);
285 } 293 }
286 294
287 match self.interned(&Interner) { 295 match self.kind(&Interner) {
288 TyKind::Never => write!(f, "!")?, 296 TyKind::Never => write!(f, "!")?,
289 TyKind::Str => write!(f, "str")?, 297 TyKind::Str => write!(f, "str")?,
290 TyKind::Scalar(Scalar::Bool) => write!(f, "bool")?, 298 TyKind::Scalar(Scalar::Bool) => write!(f, "bool")?,
@@ -306,7 +314,7 @@ impl HirDisplay for Ty {
306 let ty_display = 314 let ty_display =
307 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); 315 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
308 316
309 if matches!(self.interned(&Interner), TyKind::Raw(..)) { 317 if matches!(self.kind(&Interner), TyKind::Raw(..)) {
310 write!( 318 write!(
311 f, 319 f,
312 "*{}", 320 "*{}",
@@ -328,7 +336,7 @@ impl HirDisplay for Ty {
328 336
329 // FIXME: all this just to decide whether to use parentheses... 337 // FIXME: all this just to decide whether to use parentheses...
330 let datas; 338 let datas;
331 let predicates: Vec<_> = match t.interned(&Interner) { 339 let predicates: Vec<_> = match t.kind(&Interner) {
332 TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => { 340 TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => {
333 dyn_ty.bounds.skip_binders().interned().iter().cloned().collect() 341 dyn_ty.bounds.skip_binders().interned().iter().cloned().collect()
334 } 342 }
@@ -373,9 +381,9 @@ impl HirDisplay for Ty {
373 } 381 }
374 } 382 }
375 TyKind::Tuple(_, substs) => { 383 TyKind::Tuple(_, substs) => {
376 if substs.len() == 1 { 384 if substs.len(&Interner) == 1 {
377 write!(f, "(")?; 385 write!(f, "(")?;
378 substs[0].hir_fmt(f)?; 386 substs.at(&Interner, 0).hir_fmt(f)?;
379 write!(f, ",)")?; 387 write!(f, ",)")?;
380 } else { 388 } else {
381 write!(f, "(")?; 389 write!(f, "(")?;
@@ -399,7 +407,7 @@ impl HirDisplay for Ty {
399 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? 407 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)?
400 } 408 }
401 }; 409 };
402 if parameters.len() > 0 { 410 if parameters.len(&Interner) > 0 {
403 let generics = generics(f.db.upcast(), def.into()); 411 let generics = generics(f.db.upcast(), def.into());
404 let (parent_params, self_param, type_params, _impl_trait_params) = 412 let (parent_params, self_param, type_params, _impl_trait_params) =
405 generics.provenance_split(); 413 generics.provenance_split();
@@ -415,7 +423,7 @@ impl HirDisplay for Ty {
415 f.write_joined(sig.params(), ", ")?; 423 f.write_joined(sig.params(), ", ")?;
416 write!(f, ")")?; 424 write!(f, ")")?;
417 let ret = sig.ret(); 425 let ret = sig.ret();
418 if *ret != Ty::unit() { 426 if !ret.is_unit() {
419 let ret_display = ret.into_displayable( 427 let ret_display = ret.into_displayable(
420 f.db, 428 f.db,
421 f.max_size, 429 f.max_size,
@@ -451,7 +459,7 @@ impl HirDisplay for Ty {
451 } 459 }
452 } 460 }
453 461
454 if parameters.len() > 0 { 462 if parameters.len(&Interner) > 0 {
455 let parameters_to_write = if f.display_target.is_source_code() 463 let parameters_to_write = if f.display_target.is_source_code()
456 || f.omit_verbose_types() 464 || f.omit_verbose_types()
457 { 465 {
@@ -463,9 +471,11 @@ impl HirDisplay for Ty {
463 None => parameters.0.as_ref(), 471 None => parameters.0.as_ref(),
464 Some(default_parameters) => { 472 Some(default_parameters) => {
465 let mut default_from = 0; 473 let mut default_from = 0;
466 for (i, parameter) in parameters.iter().enumerate() { 474 for (i, parameter) in parameters.iter(&Interner).enumerate() {
467 match (parameter.interned(&Interner), default_parameters.get(i)) 475 match (
468 { 476 parameter.assert_ty_ref(&Interner).kind(&Interner),
477 default_parameters.get(i),
478 ) {
469 (&TyKind::Unknown, _) | (_, None) => { 479 (&TyKind::Unknown, _) | (_, None) => {
470 default_from = i + 1; 480 default_from = i + 1;
471 } 481 }
@@ -473,7 +483,8 @@ impl HirDisplay for Ty {
473 let actual_default = default_parameter 483 let actual_default = default_parameter
474 .clone() 484 .clone()
475 .subst(&parameters.prefix(i)); 485 .subst(&parameters.prefix(i));
476 if parameter != &actual_default { 486 if parameter.assert_ty_ref(&Interner) != &actual_default
487 {
477 default_from = i + 1; 488 default_from = i + 1;
478 } 489 }
479 } 490 }
@@ -504,7 +515,7 @@ impl HirDisplay for Ty {
504 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) 515 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
505 if f.display_target.is_test() { 516 if f.display_target.is_test() {
506 write!(f, "{}::{}", trait_.name, type_alias_data.name)?; 517 write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
507 if parameters.len() > 0 { 518 if parameters.len(&Interner) > 0 {
508 write!(f, "<")?; 519 write!(f, "<")?;
509 f.write_joined(&*parameters.0, ", ")?; 520 f.write_joined(&*parameters.0, ", ")?;
510 write!(f, ">")?; 521 write!(f, ">")?;
@@ -537,7 +548,7 @@ impl HirDisplay for Ty {
537 } 548 }
538 ImplTraitId::AsyncBlockTypeImplTrait(..) => { 549 ImplTraitId::AsyncBlockTypeImplTrait(..) => {
539 write!(f, "impl Future<Output = ")?; 550 write!(f, "impl Future<Output = ")?;
540 parameters[0].hir_fmt(f)?; 551 parameters.at(&Interner, 0).hir_fmt(f)?;
541 write!(f, ">")?; 552 write!(f, ">")?;
542 } 553 }
543 } 554 }
@@ -548,7 +559,7 @@ impl HirDisplay for Ty {
548 DisplaySourceCodeError::Closure, 559 DisplaySourceCodeError::Closure,
549 )); 560 ));
550 } 561 }
551 let sig = substs[0].callable_sig(f.db); 562 let sig = substs.at(&Interner, 0).assert_ty_ref(&Interner).callable_sig(f.db);
552 if let Some(sig) = sig { 563 if let Some(sig) = sig {
553 if sig.params().is_empty() { 564 if sig.params().is_empty() {
554 write!(f, "||")?; 565 write!(f, "||")?;
@@ -580,7 +591,7 @@ impl HirDisplay for Ty {
580 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? 591 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
581 } 592 }
582 TypeParamProvenance::ArgumentImplTrait => { 593 TypeParamProvenance::ArgumentImplTrait => {
583 let substs = Substitution::type_params_for_generics(f.db, &generics); 594 let substs = generics.type_params_subst(f.db);
584 let bounds = f 595 let bounds = f
585 .db 596 .db
586 .generic_predicates(id.parent) 597 .generic_predicates(id.parent)
@@ -652,7 +663,7 @@ impl HirDisplay for CallableSig {
652 } 663 }
653 write!(f, ")")?; 664 write!(f, ")")?;
654 let ret = self.ret(); 665 let ret = self.ret();
655 if *ret != Ty::unit() { 666 if !ret.is_unit() {
656 let ret_display = 667 let ret_display =
657 ret.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); 668 ret.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
658 write!(f, " -> {}", ret_display)?; 669 write!(f, " -> {}", ret_display)?;
@@ -718,7 +729,9 @@ fn write_bounds_like_dyn_trait(
718 write!(f, "{}", f.db.trait_data(trait_).name)?; 729 write!(f, "{}", f.db.trait_data(trait_).name)?;
719 if let [_, params @ ..] = &*trait_ref.substitution.0 { 730 if let [_, params @ ..] = &*trait_ref.substitution.0 {
720 if is_fn_trait { 731 if is_fn_trait {
721 if let Some(args) = params.first().and_then(|it| it.as_tuple()) { 732 if let Some(args) =
733 params.first().and_then(|it| it.assert_ty_ref(&Interner).as_tuple())
734 {
722 write!(f, "(")?; 735 write!(f, "(")?;
723 f.write_joined(&*args.0, ", ")?; 736 f.write_joined(&*args.0, ", ")?;
724 write!(f, ")")?; 737 write!(f, ")")?;
@@ -767,16 +780,16 @@ impl TraitRef {
767 return write!(f, "{}", TYPE_HINT_TRUNCATION); 780 return write!(f, "{}", TYPE_HINT_TRUNCATION);
768 } 781 }
769 782
770 self.substitution[0].hir_fmt(f)?; 783 self.self_type_parameter().hir_fmt(f)?;
771 if use_as { 784 if use_as {
772 write!(f, " as ")?; 785 write!(f, " as ")?;
773 } else { 786 } else {
774 write!(f, ": ")?; 787 write!(f, ": ")?;
775 } 788 }
776 write!(f, "{}", f.db.trait_data(self.hir_trait_id()).name)?; 789 write!(f, "{}", f.db.trait_data(self.hir_trait_id()).name)?;
777 if self.substitution.len() > 1 { 790 if self.substitution.len(&Interner) > 1 {
778 write!(f, "<")?; 791 write!(f, "<")?;
779 f.write_joined(&self.substitution[1..], ", ")?; 792 f.write_joined(&self.substitution.interned(&Interner)[1..], ", ")?;
780 write!(f, ">")?; 793 write!(f, ">")?;
781 } 794 }
782 Ok(()) 795 Ok(())
@@ -1016,11 +1029,11 @@ impl HirDisplay for Path {
1016 } 1029 }
1017} 1030}
1018 1031
1019impl HirDisplay for GenericArg { 1032impl HirDisplay for hir_def::path::GenericArg {
1020 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 1033 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
1021 match self { 1034 match self {
1022 GenericArg::Type(ty) => ty.hir_fmt(f), 1035 hir_def::path::GenericArg::Type(ty) => ty.hir_fmt(f),
1023 GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name), 1036 hir_def::path::GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name),
1024 } 1037 }
1025 } 1038 }
1026} 1039}
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 497a1beb7..1b1d4458c 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -38,11 +38,11 @@ use syntax::SmolStr;
38 38
39use super::{ 39use super::{
40 traits::{DomainGoal, Guidance, Solution}, 40 traits::{DomainGoal, Guidance, Solution},
41 InEnvironment, ProjectionTy, Substitution, TraitEnvironment, TraitRef, Ty, TypeWalk, 41 InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty, TypeWalk,
42}; 42};
43use crate::{ 43use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, 44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
45 to_assoc_type_id, to_chalk_trait_id, AliasEq, AliasTy, Interner, TyKind, 45 to_assoc_type_id, AliasEq, AliasTy, Interner, TyBuilder, TyKind,
46}; 46};
47 47
48// This lint has a false positive here. See the link below for details. 48// This lint has a false positive here. See the link below for details.
@@ -325,7 +325,7 @@ impl<'a> InferenceContext<'a> {
325 325
326 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. 326 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it.
327 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { 327 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
328 match ty.interned(&Interner) { 328 match ty.kind(&Interner) {
329 TyKind::Unknown => self.table.new_type_var(), 329 TyKind::Unknown => self.table.new_type_var(),
330 _ => ty, 330 _ => ty,
331 } 331 }
@@ -340,6 +340,8 @@ impl<'a> InferenceContext<'a> {
340 // no change 340 // no change
341 return; 341 return;
342 } 342 }
343 let _span = profile::span("resolve_obligations_as_possible");
344
343 self.last_obligations_check = Some(self.table.revision); 345 self.last_obligations_check = Some(self.table.revision);
344 let obligations = mem::replace(&mut self.obligations, Vec::new()); 346 let obligations = mem::replace(&mut self.obligations, Vec::new());
345 for obligation in obligations { 347 for obligation in obligations {
@@ -407,16 +409,14 @@ impl<'a> InferenceContext<'a> {
407 _ => panic!("resolve_associated_type called with non-associated type"), 409 _ => panic!("resolve_associated_type called with non-associated type"),
408 }; 410 };
409 let ty = self.table.new_type_var(); 411 let ty = self.table.new_type_var();
410 let substs = Substitution::build_for_def(self.db, res_assoc_ty) 412 let trait_ref = TyBuilder::trait_ref(self.db, trait_)
411 .push(inner_ty) 413 .push(inner_ty)
412 .fill(params.iter().cloned()) 414 .fill(params.iter().cloned())
413 .build(); 415 .build();
414 let trait_ref =
415 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs.clone() };
416 let alias_eq = AliasEq { 416 let alias_eq = AliasEq {
417 alias: AliasTy::Projection(ProjectionTy { 417 alias: AliasTy::Projection(ProjectionTy {
418 associated_ty_id: to_assoc_type_id(res_assoc_ty), 418 associated_ty_id: to_assoc_type_id(res_assoc_ty),
419 substitution: substs, 419 substitution: trait_ref.substitution.clone(),
420 }), 420 }),
421 ty: ty.clone(), 421 ty: ty.clone(),
422 }; 422 };
@@ -436,7 +436,7 @@ impl<'a> InferenceContext<'a> {
436 /// to do it as well. 436 /// to do it as well.
437 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 437 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
438 let ty = self.resolve_ty_as_possible(ty); 438 let ty = self.resolve_ty_as_possible(ty);
439 ty.fold(&mut |ty| match ty.interned(&Interner) { 439 ty.fold(&mut |ty| match ty.kind(&Interner) {
440 TyKind::Alias(AliasTy::Projection(proj_ty)) => { 440 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
441 self.normalize_projection_ty(proj_ty.clone()) 441 self.normalize_projection_ty(proj_ty.clone())
442 } 442 }
@@ -487,7 +487,7 @@ impl<'a> InferenceContext<'a> {
487 } 487 }
488 TypeNs::SelfType(impl_id) => { 488 TypeNs::SelfType(impl_id) => {
489 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 489 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
490 let substs = Substitution::type_params_for_generics(self.db, &generics); 490 let substs = generics.type_params_subst(self.db);
491 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 491 let ty = self.db.impl_self_ty(impl_id).subst(&substs);
492 match unresolved { 492 match unresolved {
493 None => { 493 None => {
@@ -514,10 +514,9 @@ impl<'a> InferenceContext<'a> {
514 } 514 }
515 } 515 }
516 TypeNs::TypeAliasId(it) => { 516 TypeNs::TypeAliasId(it) => {
517 let substs = Substitution::build_for_def(self.db, it) 517 let ty = TyBuilder::def_ty(self.db, it.into())
518 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 518 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
519 .build(); 519 .build();
520 let ty = self.db.ty(it.into()).subst(&substs);
521 let variant = ty_variant(&ty); 520 let variant = ty_variant(&ty);
522 forbid_unresolved_segments((ty, variant), unresolved) 521 forbid_unresolved_segments((ty, variant), unresolved)
523 } 522 }
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 9c62932b1..028a4d568 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -7,9 +7,7 @@
7use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; 7use chalk_ir::{cast::Cast, Mutability, TyVariableKind};
8use hir_def::lang_item::LangItemTarget; 8use hir_def::lang_item::LangItemTarget;
9 9
10use crate::{ 10use crate::{autoderef, traits::Solution, Interner, Ty, TyBuilder, TyKind};
11 autoderef, to_chalk_trait_id, traits::Solution, Interner, Substitution, TraitRef, Ty, TyKind,
12};
13 11
14use super::{InEnvironment, InferenceContext}; 12use super::{InEnvironment, InferenceContext};
15 13
@@ -36,7 +34,7 @@ impl<'a> InferenceContext<'a> {
36 ty1.clone() 34 ty1.clone()
37 } else { 35 } else {
38 if let (TyKind::FnDef(..), TyKind::FnDef(..)) = 36 if let (TyKind::FnDef(..), TyKind::FnDef(..)) =
39 (ty1.interned(&Interner), ty2.interned(&Interner)) 37 (ty1.kind(&Interner), ty2.kind(&Interner))
40 { 38 {
41 cov_mark::hit!(coerce_fn_reification); 39 cov_mark::hit!(coerce_fn_reification);
42 // Special case: two function types. Try to coerce both to 40 // Special case: two function types. Try to coerce both to
@@ -44,8 +42,8 @@ impl<'a> InferenceContext<'a> {
44 // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916 42 // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916
45 let sig1 = ty1.callable_sig(self.db).expect("FnDef without callable sig"); 43 let sig1 = ty1.callable_sig(self.db).expect("FnDef without callable sig");
46 let sig2 = ty2.callable_sig(self.db).expect("FnDef without callable sig"); 44 let sig2 = ty2.callable_sig(self.db).expect("FnDef without callable sig");
47 let ptr_ty1 = Ty::fn_ptr(sig1); 45 let ptr_ty1 = TyBuilder::fn_ptr(sig1);
48 let ptr_ty2 = Ty::fn_ptr(sig2); 46 let ptr_ty2 = TyBuilder::fn_ptr(sig2);
49 self.coerce_merge_branch(&ptr_ty1, &ptr_ty2) 47 self.coerce_merge_branch(&ptr_ty1, &ptr_ty2)
50 } else { 48 } else {
51 cov_mark::hit!(coerce_merge_fail_fallback); 49 cov_mark::hit!(coerce_merge_fail_fallback);
@@ -55,7 +53,7 @@ impl<'a> InferenceContext<'a> {
55 } 53 }
56 54
57 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { 55 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool {
58 match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { 56 match (from_ty.kind(&Interner), to_ty.kind(&Interner)) {
59 // Never type will make type variable to fallback to Never Type instead of Unknown. 57 // Never type will make type variable to fallback to Never Type instead of Unknown.
60 (TyKind::Never, TyKind::InferenceVar(tv, TyVariableKind::General)) => { 58 (TyKind::Never, TyKind::InferenceVar(tv, TyVariableKind::General)) => {
61 self.table.type_variable_table.set_diverging(*tv, true); 59 self.table.type_variable_table.set_diverging(*tv, true);
@@ -73,7 +71,7 @@ impl<'a> InferenceContext<'a> {
73 } 71 }
74 72
75 // Pointer weakening and function to pointer 73 // Pointer weakening and function to pointer
76 match (from_ty.interned_mut(), to_ty.interned(&Interner)) { 74 match (from_ty.interned_mut(), to_ty.kind(&Interner)) {
77 // `*mut T` -> `*const T` 75 // `*mut T` -> `*const T`
78 // `&mut T` -> `&T` 76 // `&mut T` -> `&T`
79 (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) 77 (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..))
@@ -95,12 +93,12 @@ impl<'a> InferenceContext<'a> {
95 (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) { 93 (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) {
96 None => return false, 94 None => return false,
97 Some(sig) => { 95 Some(sig) => {
98 from_ty = Ty::fn_ptr(sig); 96 from_ty = TyBuilder::fn_ptr(sig);
99 } 97 }
100 }, 98 },
101 99
102 (TyKind::Closure(.., substs), TyKind::Function { .. }) => { 100 (TyKind::Closure(.., substs), TyKind::Function { .. }) => {
103 from_ty = substs[0].clone(); 101 from_ty = substs.at(&Interner, 0).assert_ty_ref(&Interner).clone();
104 } 102 }
105 103
106 _ => {} 104 _ => {}
@@ -111,7 +109,7 @@ impl<'a> InferenceContext<'a> {
111 } 109 }
112 110
113 // Auto Deref if cannot coerce 111 // Auto Deref if cannot coerce
114 match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { 112 match (from_ty.kind(&Interner), to_ty.kind(&Interner)) {
115 // FIXME: DerefMut 113 // FIXME: DerefMut
116 (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => self.unify_autoderef_behind_ref(st1, st2), 114 (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => self.unify_autoderef_behind_ref(st1, st2),
117 115
@@ -130,18 +128,15 @@ impl<'a> InferenceContext<'a> {
130 _ => return None, 128 _ => return None,
131 }; 129 };
132 130
133 let generic_params = crate::utils::generics(self.db.upcast(), coerce_unsized_trait.into()); 131 let trait_ref = {
134 if generic_params.len() != 2 { 132 let b = TyBuilder::trait_ref(self.db, coerce_unsized_trait);
135 // The CoerceUnsized trait should have two generic params: Self and T. 133 if b.remaining() != 2 {
136 return None; 134 // The CoerceUnsized trait should have two generic params: Self and T.
137 } 135 return None;
136 }
137 b.push(from_ty.clone()).push(to_ty.clone()).build()
138 };
138 139
139 let substs = Substitution::build_for_generics(&generic_params)
140 .push(from_ty.clone())
141 .push(to_ty.clone())
142 .build();
143 let trait_ref =
144 TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs };
145 let goal = InEnvironment::new(self.trait_env.env.clone(), trait_ref.cast(&Interner)); 140 let goal = InEnvironment::new(self.trait_env.env.clone(), trait_ref.cast(&Interner));
146 141
147 let canonicalizer = self.canonicalizer(); 142 let canonicalizer = self.canonicalizer();
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 25ab3ea4c..c584a2c08 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -19,11 +19,11 @@ use crate::{
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},
22 to_assoc_type_id, to_chalk_trait_id, 22 to_chalk_trait_id,
23 traits::{chalk::from_chalk, FnTrait, InEnvironment}, 23 traits::{chalk::from_chalk, FnTrait, InEnvironment},
24 utils::{generics, variant_data, Generics}, 24 utils::{generics, variant_data, Generics},
25 AdtId, Binders, CallableDefId, DomainGoal, FnPointer, FnSig, Interner, Rawness, Scalar, 25 AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Rawness, Scalar, Substitution,
26 Substitution, TraitRef, Ty, TyKind, 26 TraitRef, Ty, TyBuilder, TyKind,
27}; 27};
28 28
29use super::{ 29use super::{
@@ -73,38 +73,33 @@ impl<'a> InferenceContext<'a> {
73 let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?; 73 let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?;
74 let output_assoc_type = 74 let output_assoc_type =
75 self.db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?; 75 self.db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?;
76 let generic_params = generics(self.db.upcast(), fn_once_trait.into());
77 if generic_params.len() != 2 {
78 return None;
79 }
80 76
81 let mut param_builder = Substitution::builder(num_args);
82 let mut arg_tys = vec![]; 77 let mut arg_tys = vec![];
83 for _ in 0..num_args { 78 let arg_ty = TyBuilder::tuple(num_args)
84 let arg = self.table.new_type_var(); 79 .fill(repeat_with(|| {
85 param_builder = param_builder.push(arg.clone()); 80 let arg = self.table.new_type_var();
86 arg_tys.push(arg); 81 arg_tys.push(arg.clone());
87 } 82 arg
88 let parameters = param_builder.build(); 83 }))
89 let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner); 84 .build();
90 let substs = 85
91 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 86 let projection = {
87 let b = TyBuilder::assoc_type_projection(self.db, output_assoc_type);
88 if b.remaining() != 2 {
89 return None;
90 }
91 b.push(ty.clone()).push(arg_ty).build()
92 };
92 93
93 let trait_env = self.trait_env.env.clone(); 94 let trait_env = self.trait_env.env.clone();
94 let implements_fn_trait: DomainGoal = 95 let obligation = InEnvironment {
95 TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() } 96 goal: projection.trait_ref(self.db).cast(&Interner),
96 .cast(&Interner);
97 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment {
98 goal: implements_fn_trait.clone(),
99 environment: trait_env, 97 environment: trait_env,
100 }); 98 };
101 if self.db.trait_solve(krate, goal.value).is_some() { 99 let canonical = self.canonicalizer().canonicalize_obligation(obligation.clone());
102 self.push_obligation(implements_fn_trait); 100 if self.db.trait_solve(krate, canonical.value).is_some() {
103 let output_proj_ty = crate::ProjectionTy { 101 self.push_obligation(obligation.goal);
104 associated_ty_id: to_assoc_type_id(output_assoc_type), 102 let return_ty = self.normalize_projection_ty(projection);
105 substitution: substs,
106 };
107 let return_ty = self.normalize_projection_ty(output_proj_ty);
108 Some((arg_tys, return_ty)) 103 Some((arg_tys, return_ty))
109 } else { 104 } else {
110 None 105 None
@@ -138,7 +133,7 @@ impl<'a> InferenceContext<'a> {
138 both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); 133 both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe);
139 let else_ty = match else_branch { 134 let else_ty = match else_branch {
140 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), 135 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected),
141 None => Ty::unit(), 136 None => TyBuilder::unit(),
142 }; 137 };
143 both_arms_diverge &= self.diverges; 138 both_arms_diverge &= self.diverges;
144 139
@@ -193,7 +188,7 @@ impl<'a> InferenceContext<'a> {
193 break_ty: self.table.new_type_var(), 188 break_ty: self.table.new_type_var(),
194 label: label.map(|label| self.body[label].name.clone()), 189 label: label.map(|label| self.body[label].name.clone()),
195 }); 190 });
196 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 191 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
197 192
198 let ctxt = self.breakables.pop().expect("breakable stack broken"); 193 let ctxt = self.breakables.pop().expect("breakable stack broken");
199 if ctxt.may_break { 194 if ctxt.may_break {
@@ -217,11 +212,11 @@ impl<'a> InferenceContext<'a> {
217 *condition, 212 *condition,
218 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), 213 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
219 ); 214 );
220 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 215 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
221 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 216 let _ctxt = self.breakables.pop().expect("breakable stack broken");
222 // the body may not run, so it diverging doesn't mean we diverge 217 // the body may not run, so it diverging doesn't mean we diverge
223 self.diverges = Diverges::Maybe; 218 self.diverges = Diverges::Maybe;
224 Ty::unit() 219 TyBuilder::unit()
225 } 220 }
226 Expr::For { iterable, body, pat, label } => { 221 Expr::For { iterable, body, pat, label } => {
227 let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); 222 let iterable_ty = self.infer_expr(*iterable, &Expectation::none());
@@ -236,11 +231,11 @@ impl<'a> InferenceContext<'a> {
236 231
237 self.infer_pat(*pat, &pat_ty, BindingMode::default()); 232 self.infer_pat(*pat, &pat_ty, BindingMode::default());
238 233
239 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 234 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
240 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 235 let _ctxt = self.breakables.pop().expect("breakable stack broken");
241 // the body may not run, so it diverging doesn't mean we diverge 236 // the body may not run, so it diverging doesn't mean we diverge
242 self.diverges = Diverges::Maybe; 237 self.diverges = Diverges::Maybe;
243 Ty::unit() 238 TyBuilder::unit()
244 } 239 }
245 Expr::Lambda { body, args, ret_type, arg_types } => { 240 Expr::Lambda { body, args, ret_type, arg_types } => {
246 assert_eq!(args.len(), arg_types.len()); 241 assert_eq!(args.len(), arg_types.len());
@@ -266,7 +261,7 @@ impl<'a> InferenceContext<'a> {
266 let sig_ty = TyKind::Function(FnPointer { 261 let sig_ty = TyKind::Function(FnPointer {
267 num_args: sig_tys.len() - 1, 262 num_args: sig_tys.len() - 1,
268 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, 263 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
269 substs: Substitution(sig_tys.clone().into()), 264 substs: Substitution::from_iter(&Interner, sig_tys.clone()),
270 }) 265 })
271 .intern(&Interner); 266 .intern(&Interner);
272 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); 267 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
@@ -360,7 +355,7 @@ impl<'a> InferenceContext<'a> {
360 let val_ty = if let Some(expr) = expr { 355 let val_ty = if let Some(expr) = expr {
361 self.infer_expr(*expr, &Expectation::none()) 356 self.infer_expr(*expr, &Expectation::none())
362 } else { 357 } else {
363 Ty::unit() 358 TyBuilder::unit()
364 }; 359 };
365 360
366 let last_ty = 361 let last_ty =
@@ -386,7 +381,7 @@ impl<'a> InferenceContext<'a> {
386 if let Some(expr) = expr { 381 if let Some(expr) = expr {
387 self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone())); 382 self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone()));
388 } else { 383 } else {
389 let unit = Ty::unit(); 384 let unit = TyBuilder::unit();
390 self.coerce(&unit, &self.return_ty.clone()); 385 self.coerce(&unit, &self.return_ty.clone());
391 } 386 }
392 TyKind::Never.intern(&Interner) 387 TyKind::Never.intern(&Interner)
@@ -406,7 +401,7 @@ impl<'a> InferenceContext<'a> {
406 401
407 self.unify(&ty, &expected.ty); 402 self.unify(&ty, &expected.ty);
408 403
409 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 404 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
410 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 405 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
411 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); 406 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
412 for field in fields.iter() { 407 for field in fields.iter() {
@@ -455,10 +450,14 @@ impl<'a> InferenceContext<'a> {
455 }) 450 })
456 .unwrap_or(true) 451 .unwrap_or(true)
457 }; 452 };
458 match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { 453 match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) {
459 TyKind::Tuple(_, substs) => { 454 TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| {
460 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) 455 substs
461 } 456 .interned(&Interner)
457 .get(idx)
458 .map(|a| a.assert_ty_ref(&Interner))
459 .cloned()
460 }),
462 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { 461 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
463 let local_id = self.db.struct_data(*s).variant_data.field(name)?; 462 let local_id = self.db.struct_data(*s).variant_data.field(name)?;
464 let field = FieldId { parent: (*s).into(), local_id }; 463 let field = FieldId { parent: (*s).into(), local_id };
@@ -535,17 +534,10 @@ impl<'a> InferenceContext<'a> {
535 Expr::Box { expr } => { 534 Expr::Box { expr } => {
536 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 535 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
537 if let Some(box_) = self.resolve_boxed_box() { 536 if let Some(box_) = self.resolve_boxed_box() {
538 let mut sb = 537 TyBuilder::adt(self.db, box_)
539 Substitution::build_for_generics(&generics(self.db.upcast(), box_.into())); 538 .push(inner_ty)
540 sb = sb.push(inner_ty); 539 .fill_with_defaults(self.db, || self.table.new_type_var())
541 match self.db.generic_defaults(box_.into()).get(1) { 540 .build()
542 Some(alloc_ty) if !alloc_ty.value.is_unknown() && sb.remaining() > 0 => {
543 sb = sb.push(alloc_ty.value.clone());
544 }
545 _ => (),
546 }
547 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
548 Ty::adt_ty(box_, sb.build())
549 } else { 541 } else {
550 self.err_ty() 542 self.err_ty()
551 } 543 }
@@ -573,7 +565,7 @@ impl<'a> InferenceContext<'a> {
573 None => self.err_ty(), 565 None => self.err_ty(),
574 }, 566 },
575 UnaryOp::Neg => { 567 UnaryOp::Neg => {
576 match inner_ty.interned(&Interner) { 568 match inner_ty.kind(&Interner) {
577 // Fast path for builtins 569 // Fast path for builtins
578 TyKind::Scalar(Scalar::Int(_)) 570 TyKind::Scalar(Scalar::Int(_))
579 | TyKind::Scalar(Scalar::Uint(_)) 571 | TyKind::Scalar(Scalar::Uint(_))
@@ -586,7 +578,7 @@ impl<'a> InferenceContext<'a> {
586 } 578 }
587 } 579 }
588 UnaryOp::Not => { 580 UnaryOp::Not => {
589 match inner_ty.interned(&Interner) { 581 match inner_ty.kind(&Interner) {
590 // Fast path for builtins 582 // Fast path for builtins
591 TyKind::Scalar(Scalar::Bool) 583 TyKind::Scalar(Scalar::Bool)
592 | TyKind::Scalar(Scalar::Int(_)) 584 | TyKind::Scalar(Scalar::Int(_))
@@ -635,31 +627,31 @@ impl<'a> InferenceContext<'a> {
635 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 627 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
636 match (range_type, lhs_ty, rhs_ty) { 628 match (range_type, lhs_ty, rhs_ty) {
637 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 629 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
638 Some(adt) => Ty::adt_ty(adt, Substitution::empty()), 630 Some(adt) => TyBuilder::adt(self.db, adt).build(),
639 None => self.err_ty(), 631 None => self.err_ty(),
640 }, 632 },
641 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 633 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
642 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 634 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
643 None => self.err_ty(), 635 None => self.err_ty(),
644 }, 636 },
645 (RangeOp::Inclusive, None, Some(ty)) => { 637 (RangeOp::Inclusive, None, Some(ty)) => {
646 match self.resolve_range_to_inclusive() { 638 match self.resolve_range_to_inclusive() {
647 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 639 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
648 None => self.err_ty(), 640 None => self.err_ty(),
649 } 641 }
650 } 642 }
651 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 643 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
652 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 644 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
653 None => self.err_ty(), 645 None => self.err_ty(),
654 }, 646 },
655 (RangeOp::Inclusive, Some(_), Some(ty)) => { 647 (RangeOp::Inclusive, Some(_), Some(ty)) => {
656 match self.resolve_range_inclusive() { 648 match self.resolve_range_inclusive() {
657 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 649 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
658 None => self.err_ty(), 650 None => self.err_ty(),
659 } 651 }
660 } 652 }
661 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 653 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
662 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 654 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
663 None => self.err_ty(), 655 None => self.err_ty(),
664 }, 656 },
665 (RangeOp::Inclusive, _, None) => self.err_ty(), 657 (RangeOp::Inclusive, _, None) => self.err_ty(),
@@ -692,10 +684,10 @@ impl<'a> InferenceContext<'a> {
692 } 684 }
693 } 685 }
694 Expr::Tuple { exprs } => { 686 Expr::Tuple { exprs } => {
695 let mut tys = match expected.ty.interned(&Interner) { 687 let mut tys = match expected.ty.kind(&Interner) {
696 TyKind::Tuple(_, substs) => substs 688 TyKind::Tuple(_, substs) => substs
697 .iter() 689 .iter(&Interner)
698 .cloned() 690 .map(|a| a.assert_ty_ref(&Interner).clone())
699 .chain(repeat_with(|| self.table.new_type_var())) 691 .chain(repeat_with(|| self.table.new_type_var()))
700 .take(exprs.len()) 692 .take(exprs.len())
701 .collect::<Vec<_>>(), 693 .collect::<Vec<_>>(),
@@ -706,10 +698,10 @@ impl<'a> InferenceContext<'a> {
706 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 698 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
707 } 699 }
708 700
709 TyKind::Tuple(tys.len(), Substitution(tys.into())).intern(&Interner) 701 TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner)
710 } 702 }
711 Expr::Array(array) => { 703 Expr::Array(array) => {
712 let elem_ty = match expected.ty.interned(&Interner) { 704 let elem_ty = match expected.ty.kind(&Interner) {
713 TyKind::Array(st) | TyKind::Slice(st) => st.clone(), 705 TyKind::Array(st) | TyKind::Slice(st) => st.clone(),
714 _ => self.table.new_type_var(), 706 _ => self.table.new_type_var(),
715 }; 707 };
@@ -824,8 +816,8 @@ impl<'a> InferenceContext<'a> {
824 // we don't even make an attempt at coercion 816 // we don't even make an attempt at coercion
825 self.table.new_maybe_never_var() 817 self.table.new_maybe_never_var()
826 } else { 818 } else {
827 self.coerce(&Ty::unit(), &expected.coercion_target()); 819 self.coerce(&TyBuilder::unit(), &expected.coercion_target());
828 Ty::unit() 820 TyBuilder::unit()
829 } 821 }
830 }; 822 };
831 ty 823 ty
@@ -953,11 +945,11 @@ impl<'a> InferenceContext<'a> {
953 substs.push(self.err_ty()); 945 substs.push(self.err_ty());
954 } 946 }
955 assert_eq!(substs.len(), total_len); 947 assert_eq!(substs.len(), total_len);
956 Substitution(substs.into()) 948 Substitution::from_iter(&Interner, substs)
957 } 949 }
958 950
959 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 951 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
960 if let TyKind::FnDef(fn_def, parameters) = callable_ty.interned(&Interner) { 952 if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(&Interner) {
961 let def: CallableDefId = from_chalk(self.db, *fn_def); 953 let def: CallableDefId = from_chalk(self.db, *fn_def);
962 let generic_predicates = self.db.generic_predicates(def.into()); 954 let generic_predicates = self.db.generic_predicates(def.into());
963 for predicate in generic_predicates.iter() { 955 for predicate in generic_predicates.iter() {
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 474363709..5b70d5e5a 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -13,9 +13,8 @@ use hir_expand::name::Name;
13 13
14use super::{BindingMode, Expectation, InferenceContext}; 14use super::{BindingMode, Expectation, InferenceContext};
15use crate::{ 15use crate::{
16 lower::lower_to_chalk_mutability, 16 lower::lower_to_chalk_mutability, utils::variant_data, Interner, Substitution, Ty, TyBuilder,
17 utils::{generics, variant_data}, 17 TyKind,
18 Interner, Substitution, Ty, TyKind,
19}; 18};
20 19
21impl<'a> InferenceContext<'a> { 20impl<'a> InferenceContext<'a> {
@@ -35,7 +34,7 @@ impl<'a> InferenceContext<'a> {
35 } 34 }
36 self.unify(&ty, expected); 35 self.unify(&ty, expected);
37 36
38 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 37 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
39 38
40 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 39 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
41 let (pre, post) = match ellipsis { 40 let (pre, post) = match ellipsis {
@@ -74,7 +73,7 @@ impl<'a> InferenceContext<'a> {
74 73
75 self.unify(&ty, expected); 74 self.unify(&ty, expected);
76 75
77 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 76 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
78 77
79 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 78 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
80 for subpat in subpats { 79 for subpat in subpats {
@@ -134,7 +133,8 @@ impl<'a> InferenceContext<'a> {
134 }; 133 };
135 let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); 134 let n_uncovered_patterns = expectations.len().saturating_sub(args.len());
136 let err_ty = self.err_ty(); 135 let err_ty = self.err_ty();
137 let mut expectations_iter = expectations.iter().chain(repeat(&err_ty)); 136 let mut expectations_iter =
137 expectations.iter().map(|a| a.assert_ty_ref(&Interner)).chain(repeat(&err_ty));
138 let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm); 138 let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm);
139 139
140 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); 140 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len());
@@ -142,7 +142,8 @@ impl<'a> InferenceContext<'a> {
142 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); 142 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
143 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 143 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
144 144
145 TyKind::Tuple(inner_tys.len(), Substitution(inner_tys.into())).intern(&Interner) 145 TyKind::Tuple(inner_tys.len(), Substitution::from_iter(&Interner, inner_tys))
146 .intern(&Interner)
146 } 147 }
147 Pat::Or(ref pats) => { 148 Pat::Or(ref pats) => {
148 if let Some((first_pat, rest)) = pats.split_first() { 149 if let Some((first_pat, rest)) = pats.split_first() {
@@ -209,7 +210,7 @@ impl<'a> InferenceContext<'a> {
209 return inner_ty; 210 return inner_ty;
210 } 211 }
211 Pat::Slice { prefix, slice, suffix } => { 212 Pat::Slice { prefix, slice, suffix } => {
212 let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.interned(&Interner) { 213 let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.kind(&Interner) {
213 TyKind::Array(st) => (TyKind::Array, st.clone()), 214 TyKind::Array(st) => (TyKind::Array, st.clone()),
214 TyKind::Slice(st) => (TyKind::Slice, st.clone()), 215 TyKind::Slice(st) => (TyKind::Slice, st.clone()),
215 _ => (TyKind::Slice, self.err_ty()), 216 _ => (TyKind::Slice, self.err_ty()),
@@ -236,30 +237,20 @@ impl<'a> InferenceContext<'a> {
236 Pat::Box { inner } => match self.resolve_boxed_box() { 237 Pat::Box { inner } => match self.resolve_boxed_box() {
237 Some(box_adt) => { 238 Some(box_adt) => {
238 let (inner_ty, alloc_ty) = match expected.as_adt() { 239 let (inner_ty, alloc_ty) = match expected.as_adt() {
239 Some((adt, subst)) if adt == box_adt => { 240 Some((adt, subst)) if adt == box_adt => (
240 (subst[0].clone(), subst.get(1).cloned()) 241 subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(),
241 } 242 subst.interned(&Interner).get(1).and_then(|a| a.ty(&Interner).cloned()),
243 ),
242 _ => (self.result.standard_types.unknown.clone(), None), 244 _ => (self.result.standard_types.unknown.clone(), None),
243 }; 245 };
244 246
245 let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm); 247 let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm);
246 let mut sb = Substitution::build_for_generics(&generics( 248 let mut b = TyBuilder::adt(self.db, box_adt).push(inner_ty);
247 self.db.upcast(), 249
248 box_adt.into(), 250 if let Some(alloc_ty) = alloc_ty {
249 )); 251 b = b.push(alloc_ty);
250 sb = sb.push(inner_ty);
251 if sb.remaining() == 1 {
252 sb = sb.push(match alloc_ty {
253 Some(alloc_ty) if !alloc_ty.is_unknown() => alloc_ty,
254 _ => match self.db.generic_defaults(box_adt.into()).get(1) {
255 Some(alloc_ty) if !alloc_ty.value.is_unknown() => {
256 alloc_ty.value.clone()
257 }
258 _ => self.table.new_type_var(),
259 },
260 });
261 } 252 }
262 Ty::adt_ty(box_adt, sb.build()) 253 b.fill_with_defaults(self.db, || self.table.new_type_var()).build()
263 } 254 }
264 None => self.err_ty(), 255 None => self.err_ty(),
265 }, 256 },
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index 717738789..671ea355f 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -10,9 +10,7 @@ use hir_def::{
10}; 10};
11use hir_expand::name::Name; 11use hir_expand::name::Name;
12 12
13use crate::{ 13use crate::{method_resolution, Interner, Substitution, Ty, TyBuilder, TyKind, ValueTyDefId};
14 method_resolution, to_chalk_trait_id, Interner, Substitution, Ty, TyKind, ValueTyDefId,
15};
16 14
17use super::{ExprOrPatId, InferenceContext, TraitRef}; 15use super::{ExprOrPatId, InferenceContext, TraitRef};
18 16
@@ -82,7 +80,7 @@ impl<'a> InferenceContext<'a> {
82 } 80 }
83 ValueNs::ImplSelf(impl_id) => { 81 ValueNs::ImplSelf(impl_id) => {
84 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 82 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
85 let substs = Substitution::type_params_for_generics(self.db, &generics); 83 let substs = generics.type_params_subst(self.db);
86 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 84 let ty = self.db.impl_self_ty(impl_id).subst(&substs);
87 if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() { 85 if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() {
88 let ty = self.db.value_ty(struct_id.into()).subst(&substs); 86 let ty = self.db.value_ty(struct_id.into()).subst(&substs);
@@ -95,16 +93,13 @@ impl<'a> InferenceContext<'a> {
95 ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)), 93 ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)),
96 }; 94 };
97 95
98 let ty = self.db.value_ty(typable); 96 let parent_substs = self_subst.unwrap_or_else(|| Substitution::empty(&Interner));
99 // self_subst is just for the parent
100 let parent_substs = self_subst.unwrap_or_else(Substitution::empty);
101 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); 97 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
102 let substs = ctx.substs_from_path(path, typable, true); 98 let substs = ctx.substs_from_path(path, typable, true);
103 let full_substs = Substitution::builder(substs.len()) 99 let ty = TyBuilder::value_ty(self.db, typable)
104 .use_parent_substs(&parent_substs) 100 .use_parent_substs(&parent_substs)
105 .fill(substs.0[parent_substs.len()..].iter().cloned()) 101 .fill(substs.interned(&Interner)[parent_substs.len(&Interner)..].iter().cloned())
106 .build(); 102 .build();
107 let ty = ty.subst(&full_substs);
108 Some(ty) 103 Some(ty)
109 } 104 }
110 105
@@ -147,7 +142,7 @@ impl<'a> InferenceContext<'a> {
147 remaining_segments_for_ty, 142 remaining_segments_for_ty,
148 true, 143 true,
149 ); 144 );
150 if let TyKind::Unknown = ty.interned(&Interner) { 145 if let TyKind::Unknown = ty.kind(&Interner) {
151 return None; 146 return None;
152 } 147 }
153 148
@@ -212,7 +207,7 @@ impl<'a> InferenceContext<'a> {
212 name: &Name, 207 name: &Name,
213 id: ExprOrPatId, 208 id: ExprOrPatId,
214 ) -> Option<(ValueNs, Option<Substitution>)> { 209 ) -> Option<(ValueNs, Option<Substitution>)> {
215 if let TyKind::Unknown = ty.interned(&Interner) { 210 if let TyKind::Unknown = ty.kind(&Interner) {
216 return None; 211 return None;
217 } 212 }
218 213
@@ -245,7 +240,7 @@ impl<'a> InferenceContext<'a> {
245 }; 240 };
246 let substs = match container { 241 let substs = match container {
247 AssocContainerId::ImplId(impl_id) => { 242 AssocContainerId::ImplId(impl_id) => {
248 let impl_substs = Substitution::build_for_def(self.db, impl_id) 243 let impl_substs = TyBuilder::subst_for_def(self.db, impl_id)
249 .fill(iter::repeat_with(|| self.table.new_type_var())) 244 .fill(iter::repeat_with(|| self.table.new_type_var()))
250 .build(); 245 .build();
251 let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs); 246 let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs);
@@ -254,18 +249,12 @@ impl<'a> InferenceContext<'a> {
254 } 249 }
255 AssocContainerId::TraitId(trait_) => { 250 AssocContainerId::TraitId(trait_) => {
256 // we're picking this method 251 // we're picking this method
257 let trait_substs = Substitution::build_for_def(self.db, trait_) 252 let trait_ref = TyBuilder::trait_ref(self.db, trait_)
258 .push(ty.clone()) 253 .push(ty.clone())
259 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 254 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
260 .build(); 255 .build();
261 self.push_obligation( 256 self.push_obligation(trait_ref.clone().cast(&Interner));
262 TraitRef { 257 Some(trait_ref.substitution)
263 trait_id: to_chalk_trait_id(trait_),
264 substitution: trait_substs.clone(),
265 }
266 .cast(&Interner),
267 );
268 Some(trait_substs)
269 } 258 }
270 AssocContainerId::ModuleId(_) => None, 259 AssocContainerId::ModuleId(_) => None,
271 }; 260 };
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 5ea4b7481..a04b935ef 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -49,7 +49,7 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
49 49
50 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { 50 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T {
51 t.fold_binders( 51 t.fold_binders(
52 &mut |ty, binders| match ty.interned(&Interner) { 52 &mut |ty, binders| match ty.kind(&Interner) {
53 &TyKind::InferenceVar(var, kind) => { 53 &TyKind::InferenceVar(var, kind) => {
54 let inner = var.to_inner(); 54 let inner = var.to_inner();
55 if self.var_stack.contains(&inner) { 55 if self.var_stack.contains(&inner) {
@@ -129,29 +129,28 @@ impl<T> Canonicalized<T> {
129 solution: Canonical<Substitution>, 129 solution: Canonical<Substitution>,
130 ) { 130 ) {
131 // the solution may contain new variables, which we need to convert to new inference vars 131 // the solution may contain new variables, which we need to convert to new inference vars
132 let new_vars = Substitution( 132 let new_vars = Substitution::from_iter(
133 solution 133 &Interner,
134 .binders 134 solution.binders.iter(&Interner).map(|k| match k.kind {
135 .iter(&Interner) 135 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(),
136 .map(|k| match k.kind { 136 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(),
137 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(), 137 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(),
138 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(), 138 // HACK: Chalk can sometimes return new lifetime variables. We
139 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(), 139 // want to just skip them, but to not mess up the indices of
140 // HACK: Chalk can sometimes return new lifetime variables. We 140 // other variables, we'll just create a new type variable in
141 // want to just skip them, but to not mess up the indices of 141 // their place instead. This should not matter (we never see the
142 // other variables, we'll just create a new type variable in 142 // actual *uses* of the lifetime variable).
143 // their place instead. This should not matter (we never see the 143 VariableKind::Lifetime => ctx.table.new_type_var(),
144 // actual *uses* of the lifetime variable). 144 _ => panic!("const variable in solution"),
145 VariableKind::Lifetime => ctx.table.new_type_var(), 145 }),
146 _ => panic!("const variable in solution"),
147 })
148 .collect(),
149 ); 146 );
150 for (i, ty) in solution.value.into_iter().enumerate() { 147 for (i, ty) in solution.value.iter(&Interner).enumerate() {
151 let (v, k) = self.free_vars[i]; 148 let (v, k) = self.free_vars[i];
152 // eagerly replace projections in the type; we may be getting types 149 // eagerly replace projections in the type; we may be getting types
153 // e.g. from where clauses where this hasn't happened yet 150 // e.g. from where clauses where this hasn't happened yet
154 let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); 151 let ty = ctx.normalize_associated_types_in(
152 ty.assert_ty_ref(&Interner).clone().subst_bound_vars(&new_vars),
153 );
155 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); 154 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty);
156 } 155 }
157 } 156 }
@@ -163,13 +162,13 @@ pub fn could_unify(t1: &Ty, t2: &Ty) -> bool {
163 162
164pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { 163pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
165 let mut table = InferenceTable::new(); 164 let mut table = InferenceTable::new();
166 let vars = Substitution( 165 let vars = Substitution::from_iter(
166 &Interner,
167 tys.binders 167 tys.binders
168 .iter(&Interner) 168 .iter(&Interner)
169 // we always use type vars here because we want everything to 169 // we always use type vars here because we want everything to
170 // fallback to Unknown in the end (kind of hacky, as below) 170 // fallback to Unknown in the end (kind of hacky, as below)
171 .map(|_| table.new_type_var()) 171 .map(|_| table.new_type_var()),
172 .collect(),
173 ); 172 );
174 let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars); 173 let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars);
175 let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars); 174 let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars);
@@ -178,7 +177,8 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
178 } 177 }
179 // default any type vars that weren't unified back to their original bound vars 178 // default any type vars that weren't unified back to their original bound vars
180 // (kind of hacky) 179 // (kind of hacky)
181 for (i, var) in vars.iter().enumerate() { 180 for (i, var) in vars.iter(&Interner).enumerate() {
181 let var = var.assert_ty_ref(&Interner);
182 if &*table.resolve_ty_shallow(var) == var { 182 if &*table.resolve_ty_shallow(var) == var {
183 table.unify( 183 table.unify(
184 var, 184 var,
@@ -186,11 +186,11 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
186 ); 186 );
187 } 187 }
188 } 188 }
189 Some( 189 Some(Substitution::from_iter(
190 Substitution::builder(tys.binders.len(&Interner)) 190 &Interner,
191 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) 191 vars.iter(&Interner)
192 .build(), 192 .map(|v| table.resolve_ty_completely(v.assert_ty_ref(&Interner).clone())),
193 ) 193 ))
194} 194}
195 195
196#[derive(Clone, Debug)] 196#[derive(Clone, Debug)]
@@ -284,7 +284,9 @@ impl InferenceTable {
284 substs2: &Substitution, 284 substs2: &Substitution,
285 depth: usize, 285 depth: usize,
286 ) -> bool { 286 ) -> bool {
287 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) 287 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| {
288 self.unify_inner(t1.assert_ty_ref(&Interner), t2.assert_ty_ref(&Interner), depth)
289 })
288 } 290 }
289 291
290 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 292 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
@@ -299,7 +301,7 @@ impl InferenceTable {
299 let ty1 = self.resolve_ty_shallow(ty1); 301 let ty1 = self.resolve_ty_shallow(ty1);
300 let ty2 = self.resolve_ty_shallow(ty2); 302 let ty2 = self.resolve_ty_shallow(ty2);
301 if ty1.equals_ctor(&ty2) { 303 if ty1.equals_ctor(&ty2) {
302 match (ty1.interned(&Interner), ty2.interned(&Interner)) { 304 match (ty1.kind(&Interner), ty2.kind(&Interner)) {
303 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) 305 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2))
304 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) 306 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2))
305 | ( 307 | (
@@ -324,7 +326,7 @@ impl InferenceTable {
324 } 326 }
325 327
326 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 328 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
327 match (ty1.interned(&Interner), ty2.interned(&Interner)) { 329 match (ty1.kind(&Interner), ty2.kind(&Interner)) {
328 (TyKind::Unknown, _) | (_, TyKind::Unknown) => true, 330 (TyKind::Unknown, _) | (_, TyKind::Unknown) => true,
329 331
330 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, 332 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true,
@@ -453,7 +455,7 @@ impl InferenceTable {
453 if i > 0 { 455 if i > 0 {
454 cov_mark::hit!(type_var_resolves_to_int_var); 456 cov_mark::hit!(type_var_resolves_to_int_var);
455 } 457 }
456 match ty.interned(&Interner) { 458 match ty.kind(&Interner) {
457 TyKind::InferenceVar(tv, _) => { 459 TyKind::InferenceVar(tv, _) => {
458 let inner = tv.to_inner(); 460 let inner = tv.to_inner();
459 match self.var_unification_table.inlined_probe_value(inner).known() { 461 match self.var_unification_table.inlined_probe_value(inner).known() {
@@ -476,7 +478,7 @@ impl InferenceTable {
476 /// be resolved as far as possible, i.e. contain no type variables with 478 /// be resolved as far as possible, i.e. contain no type variables with
477 /// known type. 479 /// known type.
478 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 480 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
479 ty.fold(&mut |ty| match ty.interned(&Interner) { 481 ty.fold(&mut |ty| match ty.kind(&Interner) {
480 &TyKind::InferenceVar(tv, kind) => { 482 &TyKind::InferenceVar(tv, kind) => {
481 let inner = tv.to_inner(); 483 let inner = tv.to_inner();
482 if tv_stack.contains(&inner) { 484 if tv_stack.contains(&inner) {
@@ -503,7 +505,7 @@ impl InferenceTable {
503 /// Resolves the type completely; type variables without known type are 505 /// Resolves the type completely; type variables without known type are
504 /// replaced by TyKind::Unknown. 506 /// replaced by TyKind::Unknown.
505 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 507 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
506 ty.fold(&mut |ty| match ty.interned(&Interner) { 508 ty.fold(&mut |ty| match ty.kind(&Interner) {
507 &TyKind::InferenceVar(tv, kind) => { 509 &TyKind::InferenceVar(tv, kind) => {
508 let inner = tv.to_inner(); 510 let inner = tv.to_inner();
509 if tv_stack.contains(&inner) { 511 if tv_stack.contains(&inner) {
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 6f9c698e6..a8c87eadf 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -14,6 +14,8 @@ mod lower;
14pub(crate) mod infer; 14pub(crate) mod infer;
15pub(crate) mod utils; 15pub(crate) mod utils;
16mod chalk_cast; 16mod chalk_cast;
17mod chalk_ext;
18mod builder;
17 19
18pub mod display; 20pub mod display;
19pub mod db; 21pub mod db;
@@ -24,23 +26,27 @@ mod tests;
24#[cfg(test)] 26#[cfg(test)]
25mod test_db; 27mod test_db;
26 28
27use std::{iter, mem, ops::Deref, sync::Arc}; 29use std::{mem, sync::Arc};
30
31use chalk_ir::cast::{CastTo, Caster};
32use itertools::Itertools;
33use smallvec::SmallVec;
28 34
29use base_db::salsa; 35use base_db::salsa;
30use hir_def::{ 36use hir_def::{
31 builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId, 37 expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId, GenericDefId, HasModule,
32 GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, 38 LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId,
33}; 39};
34use itertools::Itertools;
35use smallvec::SmallVec;
36 40
37use crate::{ 41use crate::{
38 db::HirDatabase, 42 db::HirDatabase,
39 display::HirDisplay, 43 display::HirDisplay,
40 utils::{generics, make_mut_slice, Generics}, 44 utils::{generics, make_mut_slice},
41}; 45};
42 46
43pub use autoderef::autoderef; 47pub use autoderef::autoderef;
48pub use builder::TyBuilder;
49pub use chalk_ext::TyExt;
44pub use infer::{could_unify, InferenceResult, InferenceVar}; 50pub use infer::{could_unify, InferenceResult, InferenceVar};
45pub use lower::{ 51pub use lower::{
46 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, 52 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
@@ -109,7 +115,7 @@ impl ProjectionTy {
109 } 115 }
110 116
111 pub fn self_type_parameter(&self) -> &Ty { 117 pub fn self_type_parameter(&self) -> &Ty {
112 &self.substitution[0] 118 &self.substitution.interned(&Interner)[0].assert_ty_ref(&Interner)
113 } 119 }
114 120
115 fn trait_(&self, db: &dyn HirDatabase) -> TraitId { 121 fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
@@ -311,7 +317,7 @@ impl TyKind {
311} 317}
312 318
313impl Ty { 319impl Ty {
314 pub fn interned(&self, _interner: &Interner) -> &TyKind { 320 pub fn kind(&self, _interner: &Interner) -> &TyKind {
315 &self.0 321 &self.0
316 } 322 }
317 323
@@ -324,9 +330,72 @@ impl Ty {
324 } 330 }
325} 331}
326 332
333#[derive(Clone, PartialEq, Eq, Debug, Hash)]
334pub struct GenericArg {
335 interned: GenericArgData,
336}
337
338#[derive(Clone, PartialEq, Eq, Debug, Hash)]
339pub enum GenericArgData {
340 Ty(Ty),
341}
342
343impl GenericArg {
344 /// Constructs a generic argument using `GenericArgData`.
345 pub fn new(_interner: &Interner, data: GenericArgData) -> Self {
346 GenericArg { interned: data }
347 }
348
349 /// Gets the interned value.
350 pub fn interned(&self) -> &GenericArgData {
351 &self.interned
352 }
353
354 /// Asserts that this is a type argument.
355 pub fn assert_ty_ref(&self, interner: &Interner) -> &Ty {
356 self.ty(interner).unwrap()
357 }
358
359 /// Checks whether the generic argument is a type.
360 pub fn is_ty(&self, _interner: &Interner) -> bool {
361 match self.interned() {
362 GenericArgData::Ty(_) => true,
363 }
364 }
365
366 /// Returns the type if it is one, `None` otherwise.
367 pub fn ty(&self, _interner: &Interner) -> Option<&Ty> {
368 match self.interned() {
369 GenericArgData::Ty(t) => Some(t),
370 }
371 }
372}
373
374impl TypeWalk for GenericArg {
375 fn walk(&self, f: &mut impl FnMut(&Ty)) {
376 match &self.interned {
377 GenericArgData::Ty(ty) => {
378 ty.walk(f);
379 }
380 }
381 }
382
383 fn walk_mut_binders(
384 &mut self,
385 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
386 binders: DebruijnIndex,
387 ) {
388 match &mut self.interned {
389 GenericArgData::Ty(ty) => {
390 ty.walk_mut_binders(f, binders);
391 }
392 }
393 }
394}
395
327/// A list of substitutions for generic parameters. 396/// A list of substitutions for generic parameters.
328#[derive(Clone, PartialEq, Eq, Debug, Hash)] 397#[derive(Clone, PartialEq, Eq, Debug, Hash)]
329pub struct Substitution(SmallVec<[Ty; 2]>); 398pub struct Substitution(SmallVec<[GenericArg; 2]>);
330 399
331impl TypeWalk for Substitution { 400impl TypeWalk for Substitution {
332 fn walk(&self, f: &mut impl FnMut(&Ty)) { 401 fn walk(&self, f: &mut impl FnMut(&Ty)) {
@@ -347,18 +416,34 @@ impl TypeWalk for Substitution {
347} 416}
348 417
349impl Substitution { 418impl Substitution {
350 pub fn interned(&self, _: &Interner) -> &[Ty] { 419 pub fn interned(&self, _: &Interner) -> &[GenericArg] {
351 &self.0 420 &self.0
352 } 421 }
353 422
354 pub fn empty() -> Substitution { 423 pub fn len(&self, _: &Interner) -> usize {
424 self.0.len()
425 }
426
427 pub fn is_empty(&self, _: &Interner) -> bool {
428 self.0.is_empty()
429 }
430
431 pub fn at(&self, _: &Interner, i: usize) -> &GenericArg {
432 &self.0[i]
433 }
434
435 pub fn empty(_: &Interner) -> Substitution {
355 Substitution(SmallVec::new()) 436 Substitution(SmallVec::new())
356 } 437 }
357 438
439 pub fn iter(&self, _: &Interner) -> std::slice::Iter<'_, GenericArg> {
440 self.0.iter()
441 }
442
358 pub fn single(ty: Ty) -> Substitution { 443 pub fn single(ty: Ty) -> Substitution {
359 Substitution({ 444 Substitution({
360 let mut v = SmallVec::new(); 445 let mut v = SmallVec::new();
361 v.push(ty); 446 v.push(ty.cast(&Interner));
362 v 447 v
363 }) 448 })
364 } 449 }
@@ -371,60 +456,11 @@ impl Substitution {
371 Substitution(self.0[self.0.len() - std::cmp::min(self.0.len(), n)..].into()) 456 Substitution(self.0[self.0.len() - std::cmp::min(self.0.len(), n)..].into())
372 } 457 }
373 458
374 pub fn as_single(&self) -> &Ty { 459 pub fn from_iter(
375 if self.0.len() != 1 { 460 interner: &Interner,
376 panic!("expected substs of len 1, got {:?}", self); 461 elements: impl IntoIterator<Item = impl CastTo<GenericArg>>,
377 } 462 ) -> Self {
378 &self.0[0] 463 Substitution(elements.into_iter().casted(interner).collect())
379 }
380
381 pub fn from_iter(_interner: &Interner, elements: impl IntoIterator<Item = Ty>) -> Self {
382 Substitution(elements.into_iter().collect())
383 }
384
385 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
386 pub(crate) fn type_params_for_generics(
387 db: &dyn HirDatabase,
388 generic_params: &Generics,
389 ) -> Substitution {
390 Substitution(
391 generic_params
392 .iter()
393 .map(|(id, _)| TyKind::Placeholder(to_placeholder_idx(db, id)).intern(&Interner))
394 .collect(),
395 )
396 }
397
398 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
399 pub fn type_params(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substitution {
400 let params = generics(db.upcast(), def.into());
401 Substitution::type_params_for_generics(db, &params)
402 }
403
404 /// Return Substs that replace each parameter by a bound variable.
405 pub(crate) fn bound_vars(generic_params: &Generics, debruijn: DebruijnIndex) -> Substitution {
406 Substitution(
407 generic_params
408 .iter()
409 .enumerate()
410 .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner))
411 .collect(),
412 )
413 }
414
415 pub fn build_for_def(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder {
416 let def = def.into();
417 let params = generics(db.upcast(), def);
418 let param_count = params.len();
419 Substitution::builder(param_count)
420 }
421
422 pub(crate) fn build_for_generics(generic_params: &Generics) -> SubstsBuilder {
423 Substitution::builder(generic_params.len())
424 }
425
426 fn builder(param_count: usize) -> SubstsBuilder {
427 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count }
428 } 464 }
429} 465}
430 466
@@ -433,60 +469,6 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> {
433 generics(db.upcast(), id.parent).param_idx(id) 469 generics(db.upcast(), id.parent).param_idx(id)
434} 470}
435 471
436#[derive(Debug, Clone)]
437pub struct SubstsBuilder {
438 vec: Vec<Ty>,
439 param_count: usize,
440}
441
442impl SubstsBuilder {
443 pub fn build(self) -> Substitution {
444 assert_eq!(self.vec.len(), self.param_count);
445 Substitution(self.vec.into())
446 }
447
448 pub fn push(mut self, ty: Ty) -> Self {
449 self.vec.push(ty);
450 self
451 }
452
453 fn remaining(&self) -> usize {
454 self.param_count - self.vec.len()
455 }
456
457 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self {
458 self.fill(
459 (starting_from..)
460 .map(|idx| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)),
461 )
462 }
463
464 pub fn fill_with_unknown(self) -> Self {
465 self.fill(iter::repeat(TyKind::Unknown.intern(&Interner)))
466 }
467
468 pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self {
469 self.vec.extend(filler.take(self.remaining()));
470 assert_eq!(self.remaining(), 0);
471 self
472 }
473
474 pub fn use_parent_substs(mut self, parent_substs: &Substitution) -> Self {
475 assert!(self.vec.is_empty());
476 assert!(parent_substs.len() <= self.param_count);
477 self.vec.extend(parent_substs.iter().cloned());
478 self
479 }
480}
481
482impl Deref for Substitution {
483 type Target = [Ty];
484
485 fn deref(&self) -> &[Ty] {
486 &self.0
487 }
488}
489
490#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] 472#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
491pub struct Binders<T> { 473pub struct Binders<T> {
492 pub num_binders: usize, 474 pub num_binders: usize,
@@ -535,7 +517,7 @@ impl<T: Clone> Binders<&T> {
535impl<T: TypeWalk> Binders<T> { 517impl<T: TypeWalk> Binders<T> {
536 /// Substitutes all variables. 518 /// Substitutes all variables.
537 pub fn subst(self, subst: &Substitution) -> T { 519 pub fn subst(self, subst: &Substitution) -> T {
538 assert_eq!(subst.len(), self.num_binders); 520 assert_eq!(subst.len(&Interner), self.num_binders);
539 self.value.subst_bound_vars(subst) 521 self.value.subst_bound_vars(subst)
540 } 522 }
541} 523}
@@ -563,7 +545,7 @@ pub struct TraitRef {
563 545
564impl TraitRef { 546impl TraitRef {
565 pub fn self_type_parameter(&self) -> &Ty { 547 pub fn self_type_parameter(&self) -> &Ty {
566 &self.substitution[0] 548 &self.substitution.at(&Interner, 0).assert_ty_ref(&Interner)
567 } 549 }
568 550
569 pub fn hir_trait_id(&self) -> TraitId { 551 pub fn hir_trait_id(&self) -> TraitId {
@@ -692,23 +674,19 @@ impl CallableSig {
692 674
693 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { 675 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
694 CallableSig { 676 CallableSig {
695 // FIXME: what to do about lifetime params? 677 // FIXME: what to do about lifetime params? -> return PolyFnSig
696 params_and_return: fn_ptr 678 params_and_return: fn_ptr
697 .substs 679 .substs
698 .clone() 680 .clone()
699 .shift_bound_vars_out(DebruijnIndex::ONE) 681 .shift_bound_vars_out(DebruijnIndex::ONE)
700 .interned(&Interner) 682 .interned(&Interner)
701 .iter() 683 .iter()
702 .cloned() 684 .map(|arg| arg.assert_ty_ref(&Interner).clone())
703 .collect(), 685 .collect(),
704 is_varargs: fn_ptr.sig.variadic, 686 is_varargs: fn_ptr.sig.variadic,
705 } 687 }
706 } 688 }
707 689
708 pub fn from_substs(substs: &Substitution) -> CallableSig {
709 CallableSig { params_and_return: substs.iter().cloned().collect(), is_varargs: false }
710 }
711
712 pub fn params(&self) -> &[Ty] { 690 pub fn params(&self) -> &[Ty] {
713 &self.params_and_return[0..self.params_and_return.len() - 1] 691 &self.params_and_return[0..self.params_and_return.len() - 1]
714 } 692 }
@@ -737,49 +715,15 @@ impl TypeWalk for CallableSig {
737} 715}
738 716
739impl Ty { 717impl Ty {
740 pub fn unit() -> Self {
741 TyKind::Tuple(0, Substitution::empty()).intern(&Interner)
742 }
743
744 pub fn adt_ty(adt: hir_def::AdtId, substs: Substitution) -> Ty {
745 TyKind::Adt(AdtId(adt), substs).intern(&Interner)
746 }
747
748 pub fn fn_ptr(sig: CallableSig) -> Self {
749 TyKind::Function(FnPointer {
750 num_args: sig.params().len(),
751 sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs },
752 substs: Substitution::from_iter(&Interner, sig.params_and_return.iter().cloned()),
753 })
754 .intern(&Interner)
755 }
756
757 pub fn builtin(builtin: BuiltinType) -> Self {
758 match builtin {
759 BuiltinType::Char => TyKind::Scalar(Scalar::Char).intern(&Interner),
760 BuiltinType::Bool => TyKind::Scalar(Scalar::Bool).intern(&Interner),
761 BuiltinType::Str => TyKind::Str.intern(&Interner),
762 BuiltinType::Int(t) => {
763 TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))).intern(&Interner)
764 }
765 BuiltinType::Uint(t) => {
766 TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))).intern(&Interner)
767 }
768 BuiltinType::Float(t) => {
769 TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))).intern(&Interner)
770 }
771 }
772 }
773
774 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { 718 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
775 match self.interned(&Interner) { 719 match self.kind(&Interner) {
776 TyKind::Ref(mutability, ty) => Some((ty, *mutability)), 720 TyKind::Ref(mutability, ty) => Some((ty, *mutability)),
777 _ => None, 721 _ => None,
778 } 722 }
779 } 723 }
780 724
781 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { 725 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
782 match self.interned(&Interner) { 726 match self.kind(&Interner) {
783 TyKind::Ref(mutability, ty) => Some((ty, Rawness::Ref, *mutability)), 727 TyKind::Ref(mutability, ty) => Some((ty, Rawness::Ref, *mutability)),
784 TyKind::Raw(mutability, ty) => Some((ty, Rawness::RawPtr, *mutability)), 728 TyKind::Raw(mutability, ty) => Some((ty, Rawness::RawPtr, *mutability)),
785 _ => None, 729 _ => None,
@@ -789,7 +733,7 @@ impl Ty {
789 pub fn strip_references(&self) -> &Ty { 733 pub fn strip_references(&self) -> &Ty {
790 let mut t: &Ty = self; 734 let mut t: &Ty = self;
791 735
792 while let TyKind::Ref(_mutability, ty) = t.interned(&Interner) { 736 while let TyKind::Ref(_mutability, ty) = t.kind(&Interner) {
793 t = ty; 737 t = ty;
794 } 738 }
795 739
@@ -797,21 +741,21 @@ impl Ty {
797 } 741 }
798 742
799 pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)> { 743 pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)> {
800 match self.interned(&Interner) { 744 match self.kind(&Interner) {
801 TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)), 745 TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),
802 _ => None, 746 _ => None,
803 } 747 }
804 } 748 }
805 749
806 pub fn as_tuple(&self) -> Option<&Substitution> { 750 pub fn as_tuple(&self) -> Option<&Substitution> {
807 match self.interned(&Interner) { 751 match self.kind(&Interner) {
808 TyKind::Tuple(_, substs) => Some(substs), 752 TyKind::Tuple(_, substs) => Some(substs),
809 _ => None, 753 _ => None,
810 } 754 }
811 } 755 }
812 756
813 pub fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId> { 757 pub fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId> {
814 match *self.interned(&Interner) { 758 match *self.kind(&Interner) {
815 TyKind::Adt(AdtId(adt), ..) => Some(adt.into()), 759 TyKind::Adt(AdtId(adt), ..) => Some(adt.into()),
816 TyKind::FnDef(callable, ..) => { 760 TyKind::FnDef(callable, ..) => {
817 Some(db.lookup_intern_callable_def(callable.into()).into()) 761 Some(db.lookup_intern_callable_def(callable.into()).into())
@@ -823,15 +767,15 @@ impl Ty {
823 } 767 }
824 768
825 pub fn is_never(&self) -> bool { 769 pub fn is_never(&self) -> bool {
826 matches!(self.interned(&Interner), TyKind::Never) 770 matches!(self.kind(&Interner), TyKind::Never)
827 } 771 }
828 772
829 pub fn is_unknown(&self) -> bool { 773 pub fn is_unknown(&self) -> bool {
830 matches!(self.interned(&Interner), TyKind::Unknown) 774 matches!(self.kind(&Interner), TyKind::Unknown)
831 } 775 }
832 776
833 pub fn equals_ctor(&self, other: &Ty) -> bool { 777 pub fn equals_ctor(&self, other: &Ty) -> bool {
834 match (self.interned(&Interner), other.interned(&Interner)) { 778 match (self.kind(&Interner), other.kind(&Interner)) {
835 (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2, 779 (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2,
836 (TyKind::Slice(_), TyKind::Slice(_)) | (TyKind::Array(_), TyKind::Array(_)) => true, 780 (TyKind::Slice(_), TyKind::Slice(_)) | (TyKind::Array(_), TyKind::Array(_)) => true,
837 (TyKind::FnDef(def_id, ..), TyKind::FnDef(def_id2, ..)) => def_id == def_id2, 781 (TyKind::FnDef(def_id, ..), TyKind::FnDef(def_id2, ..)) => def_id == def_id2,
@@ -860,7 +804,7 @@ impl Ty {
860 804
861 /// If this is a `dyn Trait` type, this returns the `Trait` part. 805 /// If this is a `dyn Trait` type, this returns the `Trait` part.
862 fn dyn_trait_ref(&self) -> Option<&TraitRef> { 806 fn dyn_trait_ref(&self) -> Option<&TraitRef> {
863 match self.interned(&Interner) { 807 match self.kind(&Interner) {
864 TyKind::Dyn(dyn_ty) => { 808 TyKind::Dyn(dyn_ty) => {
865 dyn_ty.bounds.value.interned().get(0).and_then(|b| match b.skip_binders() { 809 dyn_ty.bounds.value.interned().get(0).and_then(|b| match b.skip_binders() {
866 WhereClause::Implemented(trait_ref) => Some(trait_ref), 810 WhereClause::Implemented(trait_ref) => Some(trait_ref),
@@ -877,7 +821,7 @@ impl Ty {
877 } 821 }
878 822
879 fn builtin_deref(&self) -> Option<Ty> { 823 fn builtin_deref(&self) -> Option<Ty> {
880 match self.interned(&Interner) { 824 match self.kind(&Interner) {
881 TyKind::Ref(.., ty) => Some(ty.clone()), 825 TyKind::Ref(.., ty) => Some(ty.clone()),
882 TyKind::Raw(.., ty) => Some(ty.clone()), 826 TyKind::Raw(.., ty) => Some(ty.clone()),
883 _ => None, 827 _ => None,
@@ -885,7 +829,7 @@ impl Ty {
885 } 829 }
886 830
887 pub fn callable_def(&self, db: &dyn HirDatabase) -> Option<CallableDefId> { 831 pub fn callable_def(&self, db: &dyn HirDatabase) -> Option<CallableDefId> {
888 match self.interned(&Interner) { 832 match self.kind(&Interner) {
889 &TyKind::FnDef(def, ..) => Some(db.lookup_intern_callable_def(def.into())), 833 &TyKind::FnDef(def, ..) => Some(db.lookup_intern_callable_def(def.into())),
890 _ => None, 834 _ => None,
891 } 835 }
@@ -900,7 +844,7 @@ impl Ty {
900 } 844 }
901 845
902 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> { 846 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
903 match self.interned(&Interner) { 847 match self.kind(&Interner) {
904 TyKind::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)), 848 TyKind::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
905 TyKind::FnDef(def, parameters) => { 849 TyKind::FnDef(def, parameters) => {
906 let callable_def = db.lookup_intern_callable_def((*def).into()); 850 let callable_def = db.lookup_intern_callable_def((*def).into());
@@ -908,7 +852,7 @@ impl Ty {
908 Some(sig.subst(&parameters)) 852 Some(sig.subst(&parameters))
909 } 853 }
910 TyKind::Closure(.., substs) => { 854 TyKind::Closure(.., substs) => {
911 let sig_param = &substs[0]; 855 let sig_param = substs.at(&Interner, 0).assert_ty_ref(&Interner);
912 sig_param.callable_sig(db) 856 sig_param.callable_sig(db)
913 } 857 }
914 _ => None, 858 _ => None,
@@ -918,7 +862,7 @@ impl Ty {
918 /// Returns the type parameters of this type if it has some (i.e. is an ADT 862 /// Returns the type parameters of this type if it has some (i.e. is an ADT
919 /// or function); so if `self` is `Option<u32>`, this returns the `u32`. 863 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
920 pub fn substs(&self) -> Option<&Substitution> { 864 pub fn substs(&self) -> Option<&Substitution> {
921 match self.interned(&Interner) { 865 match self.kind(&Interner) {
922 TyKind::Adt(_, substs) 866 TyKind::Adt(_, substs)
923 | TyKind::FnDef(_, substs) 867 | TyKind::FnDef(_, substs)
924 | TyKind::Function(FnPointer { substs, .. }) 868 | TyKind::Function(FnPointer { substs, .. })
@@ -944,7 +888,7 @@ impl Ty {
944 } 888 }
945 889
946 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> { 890 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> {
947 match self.interned(&Interner) { 891 match self.kind(&Interner) {
948 TyKind::OpaqueType(opaque_ty_id, ..) => { 892 TyKind::OpaqueType(opaque_ty_id, ..) => {
949 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { 893 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
950 ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => { 894 ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
@@ -960,7 +904,7 @@ impl Ty {
960 0, 904 0,
961 WhereClause::Implemented(TraitRef { 905 WhereClause::Implemented(TraitRef {
962 trait_id: to_chalk_trait_id(future_trait), 906 trait_id: to_chalk_trait_id(future_trait),
963 substitution: Substitution::empty(), 907 substitution: Substitution::empty(&Interner),
964 }), 908 }),
965 ); 909 );
966 Some(vec![impl_bound]) 910 Some(vec![impl_bound])
@@ -994,7 +938,7 @@ impl Ty {
994 let param_data = &generic_params.types[id.local_id]; 938 let param_data = &generic_params.types[id.local_id];
995 match param_data.provenance { 939 match param_data.provenance {
996 hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { 940 hir_def::generics::TypeParamProvenance::ArgumentImplTrait => {
997 let substs = Substitution::type_params(db, id.parent); 941 let substs = TyBuilder::type_params_subst(db, id.parent);
998 let predicates = db 942 let predicates = db
999 .generic_predicates(id.parent) 943 .generic_predicates(id.parent)
1000 .into_iter() 944 .into_iter()
@@ -1019,7 +963,7 @@ impl Ty {
1019 } 963 }
1020 964
1021 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { 965 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> {
1022 match self.interned(&Interner) { 966 match self.kind(&Interner) {
1023 TyKind::AssociatedType(id, ..) => { 967 TyKind::AssociatedType(id, ..) => {
1024 match from_assoc_type_id(*id).lookup(db.upcast()).container { 968 match from_assoc_type_id(*id).lookup(db.upcast()).container {
1025 AssocContainerId::TraitId(trait_id) => Some(trait_id), 969 AssocContainerId::TraitId(trait_id) => Some(trait_id),
@@ -1109,7 +1053,10 @@ pub trait TypeWalk {
1109 &mut |ty, binders| { 1053 &mut |ty, binders| {
1110 if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { 1054 if let &mut TyKind::BoundVar(bound) = ty.interned_mut() {
1111 if bound.debruijn >= binders { 1055 if bound.debruijn >= binders {
1112 *ty = substs.0[bound.index].clone().shift_bound_vars(binders); 1056 *ty = substs.0[bound.index]
1057 .assert_ty_ref(&Interner)
1058 .clone()
1059 .shift_bound_vars(binders);
1113 } 1060 }
1114 } 1061 }
1115 }, 1062 },
@@ -1124,7 +1071,7 @@ pub trait TypeWalk {
1124 Self: Sized, 1071 Self: Sized,
1125 { 1072 {
1126 self.fold_binders( 1073 self.fold_binders(
1127 &mut |ty, binders| match ty.interned(&Interner) { 1074 &mut |ty, binders| match ty.kind(&Interner) {
1128 TyKind::BoundVar(bound) if bound.debruijn >= binders => { 1075 TyKind::BoundVar(bound) if bound.debruijn >= binders => {
1129 TyKind::BoundVar(bound.shifted_in_from(n)).intern(&Interner) 1076 TyKind::BoundVar(bound.shifted_in_from(n)).intern(&Interner)
1130 } 1077 }
@@ -1140,7 +1087,7 @@ pub trait TypeWalk {
1140 Self: Sized + std::fmt::Debug, 1087 Self: Sized + std::fmt::Debug,
1141 { 1088 {
1142 self.fold_binders( 1089 self.fold_binders(
1143 &mut |ty, binders| match ty.interned(&Interner) { 1090 &mut |ty, binders| match ty.kind(&Interner) {
1144 TyKind::BoundVar(bound) if bound.debruijn >= binders => { 1091 TyKind::BoundVar(bound) if bound.debruijn >= binders => {
1145 TyKind::BoundVar(bound.shifted_out_to(n).unwrap_or(bound.clone())) 1092 TyKind::BoundVar(bound.shifted_out_to(n).unwrap_or(bound.clone()))
1146 .intern(&Interner) 1093 .intern(&Interner)
@@ -1154,14 +1101,14 @@ pub trait TypeWalk {
1154 1101
1155impl TypeWalk for Ty { 1102impl TypeWalk for Ty {
1156 fn walk(&self, f: &mut impl FnMut(&Ty)) { 1103 fn walk(&self, f: &mut impl FnMut(&Ty)) {
1157 match self.interned(&Interner) { 1104 match self.kind(&Interner) {
1158 TyKind::Alias(AliasTy::Projection(p_ty)) => { 1105 TyKind::Alias(AliasTy::Projection(p_ty)) => {
1159 for t in p_ty.substitution.iter() { 1106 for t in p_ty.substitution.iter(&Interner) {
1160 t.walk(f); 1107 t.walk(f);
1161 } 1108 }
1162 } 1109 }
1163 TyKind::Alias(AliasTy::Opaque(o_ty)) => { 1110 TyKind::Alias(AliasTy::Opaque(o_ty)) => {
1164 for t in o_ty.substitution.iter() { 1111 for t in o_ty.substitution.iter(&Interner) {
1165 t.walk(f); 1112 t.walk(f);
1166 } 1113 }
1167 } 1114 }
@@ -1175,7 +1122,7 @@ impl TypeWalk for Ty {
1175 } 1122 }
1176 _ => { 1123 _ => {
1177 if let Some(substs) = self.substs() { 1124 if let Some(substs) = self.substs() {
1178 for t in substs.iter() { 1125 for t in substs.iter(&Interner) {
1179 t.walk(f); 1126 t.walk(f);
1180 } 1127 }
1181 } 1128 }
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 14f34d73c..214655807 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -36,7 +36,7 @@ use crate::{
36 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig, 36 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
37 ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, 37 ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses,
38 ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty, 38 ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty,
39 TyKind, TypeWalk, WhereClause, 39 TyBuilder, TyKind, TypeWalk, WhereClause,
40}; 40};
41 41
42#[derive(Debug)] 42#[derive(Debug)]
@@ -178,9 +178,10 @@ impl<'a> TyLoweringContext<'a> {
178 } 178 }
179 TypeRef::Placeholder => TyKind::Unknown.intern(&Interner), 179 TypeRef::Placeholder => TyKind::Unknown.intern(&Interner),
180 TypeRef::Fn(params, is_varargs) => { 180 TypeRef::Fn(params, is_varargs) => {
181 let substs = Substitution(params.iter().map(|tr| self.lower_ty(tr)).collect()); 181 let substs =
182 Substitution::from_iter(&Interner, params.iter().map(|tr| self.lower_ty(tr)));
182 TyKind::Function(FnPointer { 183 TyKind::Function(FnPointer {
183 num_args: substs.len() - 1, 184 num_args: substs.len(&Interner) - 1,
184 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs }, 185 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
185 substs, 186 substs,
186 }) 187 })
@@ -233,7 +234,7 @@ impl<'a> TyLoweringContext<'a> {
233 let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx); 234 let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx);
234 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into(); 235 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
235 let generics = generics(self.db.upcast(), func.into()); 236 let generics = generics(self.db.upcast(), func.into());
236 let parameters = Substitution::bound_vars(&generics, self.in_binders); 237 let parameters = generics.bound_vars_subst(self.in_binders);
237 TyKind::Alias(AliasTy::Opaque(OpaqueTy { 238 TyKind::Alias(AliasTy::Opaque(OpaqueTy {
238 opaque_ty_id, 239 opaque_ty_id,
239 substitution: parameters, 240 substitution: parameters,
@@ -410,24 +411,16 @@ impl<'a> TyLoweringContext<'a> {
410 TypeNs::SelfType(impl_id) => { 411 TypeNs::SelfType(impl_id) => {
411 let generics = generics(self.db.upcast(), impl_id.into()); 412 let generics = generics(self.db.upcast(), impl_id.into());
412 let substs = match self.type_param_mode { 413 let substs = match self.type_param_mode {
413 TypeParamLoweringMode::Placeholder => { 414 TypeParamLoweringMode::Placeholder => generics.type_params_subst(self.db),
414 Substitution::type_params_for_generics(self.db, &generics) 415 TypeParamLoweringMode::Variable => generics.bound_vars_subst(self.in_binders),
415 }
416 TypeParamLoweringMode::Variable => {
417 Substitution::bound_vars(&generics, self.in_binders)
418 }
419 }; 416 };
420 self.db.impl_self_ty(impl_id).subst(&substs) 417 self.db.impl_self_ty(impl_id).subst(&substs)
421 } 418 }
422 TypeNs::AdtSelfType(adt) => { 419 TypeNs::AdtSelfType(adt) => {
423 let generics = generics(self.db.upcast(), adt.into()); 420 let generics = generics(self.db.upcast(), adt.into());
424 let substs = match self.type_param_mode { 421 let substs = match self.type_param_mode {
425 TypeParamLoweringMode::Placeholder => { 422 TypeParamLoweringMode::Placeholder => generics.type_params_subst(self.db),
426 Substitution::type_params_for_generics(self.db, &generics) 423 TypeParamLoweringMode::Variable => generics.bound_vars_subst(self.in_binders),
427 }
428 TypeParamLoweringMode::Variable => {
429 Substitution::bound_vars(&generics, self.in_binders)
430 }
431 }; 424 };
432 self.db.ty(adt.into()).subst(&substs) 425 self.db.ty(adt.into()).subst(&substs)
433 } 426 }
@@ -477,12 +470,13 @@ impl<'a> TyLoweringContext<'a> {
477 TypeParamLoweringMode::Placeholder => { 470 TypeParamLoweringMode::Placeholder => {
478 // if we're lowering to placeholders, we have to put 471 // if we're lowering to placeholders, we have to put
479 // them in now 472 // them in now
480 let s = Substitution::type_params( 473 let generics = generics(
481 self.db, 474 self.db.upcast(),
482 self.resolver.generic_def().expect( 475 self.resolver.generic_def().expect(
483 "there should be generics if there's a generic param", 476 "there should be generics if there's a generic param",
484 ), 477 ),
485 ); 478 );
479 let s = generics.type_params_subst(self.db);
486 t.substitution.clone().subst_bound_vars(&s) 480 t.substitution.clone().subst_bound_vars(&s)
487 } 481 }
488 TypeParamLoweringMode::Variable => t.substitution.clone(), 482 TypeParamLoweringMode::Variable => t.substitution.clone(),
@@ -625,7 +619,7 @@ impl<'a> TyLoweringContext<'a> {
625 619
626 for default_ty in defaults.iter().skip(substs.len()) { 620 for default_ty in defaults.iter().skip(substs.len()) {
627 // each default can depend on the previous parameters 621 // each default can depend on the previous parameters
628 let substs_so_far = Substitution(substs.clone().into()); 622 let substs_so_far = Substitution::from_iter(&Interner, substs.clone());
629 substs.push(default_ty.clone().subst(&substs_so_far)); 623 substs.push(default_ty.clone().subst(&substs_so_far));
630 } 624 }
631 } 625 }
@@ -638,7 +632,7 @@ impl<'a> TyLoweringContext<'a> {
638 } 632 }
639 assert_eq!(substs.len(), total_len); 633 assert_eq!(substs.len(), total_len);
640 634
641 Substitution(substs.into()) 635 Substitution::from_iter(&Interner, substs)
642 } 636 }
643 637
644 fn lower_trait_ref_from_path( 638 fn lower_trait_ref_from_path(
@@ -821,58 +815,54 @@ pub fn associated_type_shorthand_candidates<R>(
821 res: TypeNs, 815 res: TypeNs,
822 mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>, 816 mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
823) -> Option<R> { 817) -> Option<R> {
824 let traits_from_env: Vec<_> = match res { 818 let mut search = |t| {
825 TypeNs::SelfType(impl_id) => match db.impl_trait(impl_id) { 819 for t in all_super_trait_refs(db, t) {
826 None => vec![], 820 let data = db.trait_data(t.hir_trait_id());
827 // FIXME: how to correctly handle higher-ranked bounds here? 821
828 Some(trait_ref) => vec![trait_ref.value.shift_bound_vars_out(DebruijnIndex::ONE)], 822 for (name, assoc_id) in &data.items {
829 }, 823 if let AssocItemId::TypeAliasId(alias) = assoc_id {
824 if let Some(result) = cb(name, &t, *alias) {
825 return Some(result);
826 }
827 }
828 }
829 }
830 None
831 };
832
833 match res {
834 // FIXME: how to correctly handle higher-ranked bounds here?
835 TypeNs::SelfType(impl_id) => {
836 search(db.impl_trait(impl_id)?.value.shift_bound_vars_out(DebruijnIndex::ONE))
837 }
830 TypeNs::GenericParam(param_id) => { 838 TypeNs::GenericParam(param_id) => {
831 let predicates = db.generic_predicates_for_param(param_id); 839 let predicates = db.generic_predicates_for_param(param_id);
832 let mut traits_: Vec<_> = predicates 840 let res = predicates.iter().find_map(|pred| match &pred.value.value {
833 .iter() 841 // FIXME: how to correctly handle higher-ranked bounds here?
834 .filter_map(|pred| match &pred.value.value { 842 WhereClause::Implemented(tr) => {
835 // FIXME: how to correctly handle higher-ranked bounds here? 843 search(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE))
836 WhereClause::Implemented(tr) => { 844 }
837 Some(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE)) 845 _ => None,
838 } 846 });
839 _ => None, 847 if let res @ Some(_) = res {
840 }) 848 return res;
841 .collect(); 849 }
842 // Handle `Self::Type` referring to own associated type in trait definitions 850 // Handle `Self::Type` referring to own associated type in trait definitions
843 if let GenericDefId::TraitId(trait_id) = param_id.parent { 851 if let GenericDefId::TraitId(trait_id) = param_id.parent {
844 let generics = generics(db.upcast(), trait_id.into()); 852 let generics = generics(db.upcast(), trait_id.into());
845 if generics.params.types[param_id.local_id].provenance 853 if generics.params.types[param_id.local_id].provenance
846 == TypeParamProvenance::TraitSelf 854 == TypeParamProvenance::TraitSelf
847 { 855 {
848 let trait_ref = TraitRef { 856 let trait_ref = TyBuilder::trait_ref(db, trait_id)
849 trait_id: to_chalk_trait_id(trait_id), 857 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
850 substitution: Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST), 858 .build();
851 }; 859 return search(trait_ref);
852 traits_.push(trait_ref);
853 }
854 }
855 traits_
856 }
857 _ => vec![],
858 };
859
860 for t in traits_from_env.into_iter().flat_map(move |t| all_super_trait_refs(db, t)) {
861 let data = db.trait_data(t.hir_trait_id());
862
863 for (name, assoc_id) in &data.items {
864 match assoc_id {
865 AssocItemId::TypeAliasId(alias) => {
866 if let Some(result) = cb(name, &t, *alias) {
867 return Some(result);
868 }
869 } 860 }
870 AssocItemId::FunctionId(_) | AssocItemId::ConstId(_) => {}
871 } 861 }
862 None
872 } 863 }
864 _ => None,
873 } 865 }
874
875 None
876} 866}
877 867
878/// Build the type of all specific fields of a struct or enum variant. 868/// Build the type of all specific fields of a struct or enum variant.
@@ -974,7 +964,7 @@ pub(crate) fn trait_environment_query(
974 // function default implementations (and hypothetical code 964 // function default implementations (and hypothetical code
975 // inside consts or type aliases) 965 // inside consts or type aliases)
976 cov_mark::hit!(trait_self_implements_self); 966 cov_mark::hit!(trait_self_implements_self);
977 let substs = Substitution::type_params(db, trait_id); 967 let substs = TyBuilder::type_params_subst(db, trait_id);
978 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs }; 968 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
979 let pred = WhereClause::Implemented(trait_ref); 969 let pred = WhereClause::Implemented(trait_ref);
980 let program_clause: chalk_ir::ProgramClause<Interner> = pred.to_chalk(db).cast(&Interner); 970 let program_clause: chalk_ir::ProgramClause<Interner> = pred.to_chalk(db).cast(&Interner);
@@ -1056,16 +1046,16 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1056 let ret = (&ctx_ret).lower_ty(&data.ret_type); 1046 let ret = (&ctx_ret).lower_ty(&data.ret_type);
1057 let generics = generics(db.upcast(), def.into()); 1047 let generics = generics(db.upcast(), def.into());
1058 let num_binders = generics.len(); 1048 let num_binders = generics.len();
1059 Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs)) 1049 Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs()))
1060} 1050}
1061 1051
1062/// Build the declared type of a function. This should not need to look at the 1052/// Build the declared type of a function. This should not need to look at the
1063/// function body. 1053/// function body.
1064fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { 1054fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1065 let generics = generics(db.upcast(), def.into()); 1055 let generics = generics(db.upcast(), def.into());
1066 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); 1056 let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST);
1067 Binders::new( 1057 Binders::new(
1068 substs.len(), 1058 substs.len(&Interner),
1069 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner), 1059 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner),
1070 ) 1060 )
1071} 1061}
@@ -1108,9 +1098,9 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T
1108 return type_for_adt(db, def.into()); 1098 return type_for_adt(db, def.into());
1109 } 1099 }
1110 let generics = generics(db.upcast(), def.into()); 1100 let generics = generics(db.upcast(), def.into());
1111 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); 1101 let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST);
1112 Binders::new( 1102 Binders::new(
1113 substs.len(), 1103 substs.len(&Interner),
1114 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner), 1104 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner),
1115 ) 1105 )
1116} 1106}
@@ -1135,17 +1125,18 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
1135 return type_for_adt(db, def.parent.into()); 1125 return type_for_adt(db, def.parent.into());
1136 } 1126 }
1137 let generics = generics(db.upcast(), def.parent.into()); 1127 let generics = generics(db.upcast(), def.parent.into());
1138 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); 1128 let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST);
1139 Binders::new( 1129 Binders::new(
1140 substs.len(), 1130 substs.len(&Interner),
1141 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner), 1131 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner),
1142 ) 1132 )
1143} 1133}
1144 1134
1145fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { 1135fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1146 let generics = generics(db.upcast(), adt.into()); 1136 let b = TyBuilder::adt(db, adt);
1147 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); 1137 let num_binders = b.remaining();
1148 Binders::new(substs.len(), Ty::adt_ty(adt, substs)) 1138 let ty = b.fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build();
1139 Binders::new(num_binders, ty)
1149} 1140}
1150 1141
1151fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { 1142fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
@@ -1157,7 +1148,7 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1157 Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner)) 1148 Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner))
1158 } else { 1149 } else {
1159 let type_ref = &db.type_alias_data(t).type_ref; 1150 let type_ref = &db.type_alias_data(t).type_ref;
1160 let inner = ctx.lower_ty(type_ref.as_ref().unwrap_or(&TypeRef::Error)); 1151 let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error));
1161 Binders::new(generics.len(), inner) 1152 Binders::new(generics.len(), inner)
1162 } 1153 }
1163} 1154}
@@ -1217,7 +1208,7 @@ impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for V
1217/// namespace. 1208/// namespace.
1218pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> { 1209pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> {
1219 match def { 1210 match def {
1220 TyDefId::BuiltinType(it) => Binders::new(0, Ty::builtin(it)), 1211 TyDefId::BuiltinType(it) => Binders::new(0, TyBuilder::builtin(it)),
1221 TyDefId::AdtId(it) => type_for_adt(db, it), 1212 TyDefId::AdtId(it) => type_for_adt(db, it),
1222 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), 1213 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
1223 } 1214 }
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index bf7d5eded..a76586f0c 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -19,10 +19,9 @@ use crate::{
19 db::HirDatabase, 19 db::HirDatabase,
20 from_foreign_def_id, 20 from_foreign_def_id,
21 primitive::{self, FloatTy, IntTy, UintTy}, 21 primitive::{self, FloatTy, IntTy, UintTy},
22 to_chalk_trait_id,
23 utils::all_super_traits, 22 utils::all_super_traits,
24 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, 23 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId,
25 InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, 24 InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, Ty, TyBuilder, TyKind,
26 TypeWalk, 25 TypeWalk,
27}; 26};
28 27
@@ -47,7 +46,7 @@ impl TyFingerprint {
47 /// have impls: if we have some `struct S`, we can have an `impl S`, but not 46 /// have impls: if we have some `struct S`, we can have an `impl S`, but not
48 /// `impl &S`. Hence, this will return `None` for reference types and such. 47 /// `impl &S`. Hence, this will return `None` for reference types and such.
49 pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> { 48 pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> {
50 let fp = match *ty.interned(&Interner) { 49 let fp = match *ty.kind(&Interner) {
51 TyKind::Str => TyFingerprint::Str, 50 TyKind::Str => TyFingerprint::Str,
52 TyKind::Never => TyFingerprint::Never, 51 TyKind::Never => TyFingerprint::Never,
53 TyKind::Slice(..) => TyFingerprint::Slice, 52 TyKind::Slice(..) => TyFingerprint::Slice,
@@ -243,7 +242,7 @@ impl Ty {
243 242
244 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); 243 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect());
245 244
246 let lang_item_targets = match self.interned(&Interner) { 245 let lang_item_targets = match self.kind(&Interner) {
247 TyKind::Adt(AdtId(def_id), _) => { 246 TyKind::Adt(AdtId(def_id), _) => {
248 return mod_to_crate_ids(def_id.module(db.upcast())); 247 return mod_to_crate_ids(def_id.module(db.upcast()));
249 } 248 }
@@ -563,7 +562,7 @@ fn iterate_trait_method_candidates(
563 // if ty is `dyn Trait`, the trait doesn't need to be in scope 562 // if ty is `dyn Trait`, the trait doesn't need to be in scope
564 let inherent_trait = 563 let inherent_trait =
565 self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); 564 self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
566 let env_traits = if let TyKind::Placeholder(_) = self_ty.value.interned(&Interner) { 565 let env_traits = if let TyKind::Placeholder(_) = self_ty.value.kind(&Interner) {
567 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope 566 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
568 env.traits_in_scope_from_clauses(&self_ty.value) 567 env.traits_in_scope_from_clauses(&self_ty.value)
569 .flat_map(|t| all_super_traits(db.upcast(), t)) 568 .flat_map(|t| all_super_traits(db.upcast(), t))
@@ -675,7 +674,7 @@ fn is_valid_candidate(
675 } 674 }
676 } 675 }
677 if let Some(receiver_ty) = receiver_ty { 676 if let Some(receiver_ty) = receiver_ty {
678 if !data.has_self_param { 677 if !data.has_self_param() {
679 return false; 678 return false;
680 } 679 }
681 let transformed_receiver_ty = match transform_receiver_ty(db, m, self_ty) { 680 let transformed_receiver_ty = match transform_receiver_ty(db, m, self_ty) {
@@ -710,7 +709,7 @@ pub(crate) fn inherent_impl_substs(
710) -> Option<Substitution> { 709) -> Option<Substitution> {
711 // we create a var for each type parameter of the impl; we need to keep in 710 // we create a var for each type parameter of the impl; we need to keep in
712 // mind here that `self_ty` might have vars of its own 711 // mind here that `self_ty` might have vars of its own
713 let vars = Substitution::build_for_def(db, impl_id) 712 let vars = TyBuilder::subst_for_def(db, impl_id)
714 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner)) 713 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner))
715 .build(); 714 .build();
716 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); 715 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars);
@@ -720,7 +719,7 @@ pub(crate) fn inherent_impl_substs(
720 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), 719 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
721 UniverseIndex::ROOT, 720 UniverseIndex::ROOT,
722 )) 721 ))
723 .take(vars.len()), 722 .take(vars.len(&Interner)),
724 ); 723 );
725 let tys = Canonical { 724 let tys = Canonical {
726 binders: CanonicalVarKinds::from_iter(&Interner, kinds), 725 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
@@ -732,7 +731,8 @@ pub(crate) fn inherent_impl_substs(
732 // Unknown. I think this can only really happen if self_ty contained 731 // Unknown. I think this can only really happen if self_ty contained
733 // Unknown, and in that case we want the result to contain Unknown in those 732 // Unknown, and in that case we want the result to contain Unknown in those
734 // places again. 733 // places again.
735 substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.binders.len(&Interner))) 734 substs
735 .map(|s| fallback_bound_vars(s.suffix(vars.len(&Interner)), self_ty.binders.len(&Interner)))
736} 736}
737 737
738/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past 738/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
@@ -740,7 +740,7 @@ pub(crate) fn inherent_impl_substs(
740fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { 740fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution {
741 s.fold_binders( 741 s.fold_binders(
742 &mut |ty, binders| { 742 &mut |ty, binders| {
743 if let TyKind::BoundVar(bound) = ty.interned(&Interner) { 743 if let TyKind::BoundVar(bound) = ty.kind(&Interner) {
744 if bound.index >= num_vars_to_keep && bound.debruijn >= binders { 744 if bound.index >= num_vars_to_keep && bound.debruijn >= binders {
745 TyKind::Unknown.intern(&Interner) 745 TyKind::Unknown.intern(&Interner)
746 } else { 746 } else {
@@ -760,13 +760,13 @@ fn transform_receiver_ty(
760 self_ty: &Canonical<Ty>, 760 self_ty: &Canonical<Ty>,
761) -> Option<Ty> { 761) -> Option<Ty> {
762 let substs = match function_id.lookup(db.upcast()).container { 762 let substs = match function_id.lookup(db.upcast()).container {
763 AssocContainerId::TraitId(_) => Substitution::build_for_def(db, function_id) 763 AssocContainerId::TraitId(_) => TyBuilder::subst_for_def(db, function_id)
764 .push(self_ty.value.clone()) 764 .push(self_ty.value.clone())
765 .fill_with_unknown() 765 .fill_with_unknown()
766 .build(), 766 .build(),
767 AssocContainerId::ImplId(impl_id) => { 767 AssocContainerId::ImplId(impl_id) => {
768 let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?; 768 let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?;
769 Substitution::build_for_def(db, function_id) 769 TyBuilder::subst_for_def(db, function_id)
770 .use_parent_substs(&impl_substs) 770 .use_parent_substs(&impl_substs)
771 .fill_with_unknown() 771 .fill_with_unknown()
772 .build() 772 .build()
@@ -812,7 +812,7 @@ fn generic_implements_goal(
812 self_ty: Canonical<Ty>, 812 self_ty: Canonical<Ty>,
813) -> Canonical<InEnvironment<super::DomainGoal>> { 813) -> Canonical<InEnvironment<super::DomainGoal>> {
814 let mut kinds = self_ty.binders.interned().to_vec(); 814 let mut kinds = self_ty.binders.interned().to_vec();
815 let substs = super::Substitution::build_for_def(db, trait_) 815 let trait_ref = TyBuilder::trait_ref(db, trait_)
816 .push(self_ty.value) 816 .push(self_ty.value)
817 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) 817 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
818 .build(); 818 .build();
@@ -821,9 +821,8 @@ fn generic_implements_goal(
821 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), 821 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
822 UniverseIndex::ROOT, 822 UniverseIndex::ROOT,
823 )) 823 ))
824 .take(substs.len() - 1), 824 .take(trait_ref.substitution.len(&Interner) - 1),
825 ); 825 );
826 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
827 let obligation = trait_ref.cast(&Interner); 826 let obligation = trait_ref.cast(&Interner);
828 Canonical { 827 Canonical {
829 binders: CanonicalVarKinds::from_iter(&Interner, kinds), 828 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
@@ -838,9 +837,7 @@ fn autoderef_method_receiver(
838) -> Vec<Canonical<Ty>> { 837) -> Vec<Canonical<Ty>> {
839 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); 838 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect();
840 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) 839 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
841 if let Some(TyKind::Array(parameters)) = 840 if let Some(TyKind::Array(parameters)) = deref_chain.last().map(|ty| ty.value.kind(&Interner)) {
842 deref_chain.last().map(|ty| ty.value.interned(&Interner))
843 {
844 let kinds = deref_chain.last().unwrap().binders.clone(); 841 let kinds = deref_chain.last().unwrap().binders.clone();
845 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); 842 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner);
846 deref_chain.push(Canonical { value: unsized_ty, binders: kinds }) 843 deref_chain.push(Canonical { value: unsized_ty, binders: kinds })
diff --git a/crates/hir_ty/src/op.rs b/crates/hir_ty/src/op.rs
index 527c5cbbd..90dd31a35 100644
--- a/crates/hir_ty/src/op.rs
+++ b/crates/hir_ty/src/op.rs
@@ -2,14 +2,14 @@
2use chalk_ir::TyVariableKind; 2use chalk_ir::TyVariableKind;
3use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; 3use hir_def::expr::{ArithOp, BinaryOp, CmpOp};
4 4
5use crate::{Interner, Scalar, Ty, TyKind}; 5use crate::{Interner, Scalar, Ty, TyBuilder, TyKind};
6 6
7pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { 7pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
8 match op { 8 match op {
9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => TyKind::Scalar(Scalar::Bool).intern(&Interner), 9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
10 BinaryOp::Assignment { .. } => Ty::unit(), 10 BinaryOp::Assignment { .. } => TyBuilder::unit(),
11 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => { 11 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => {
12 match lhs_ty.interned(&Interner) { 12 match lhs_ty.kind(&Interner) {
13 TyKind::Scalar(Scalar::Int(_)) 13 TyKind::Scalar(Scalar::Int(_))
14 | TyKind::Scalar(Scalar::Uint(_)) 14 | TyKind::Scalar(Scalar::Uint(_))
15 | TyKind::Scalar(Scalar::Float(_)) => lhs_ty, 15 | TyKind::Scalar(Scalar::Float(_)) => lhs_ty,
@@ -18,7 +18,7 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
18 _ => TyKind::Unknown.intern(&Interner), 18 _ => TyKind::Unknown.intern(&Interner),
19 } 19 }
20 } 20 }
21 BinaryOp::ArithOp(_) => match rhs_ty.interned(&Interner) { 21 BinaryOp::ArithOp(_) => match rhs_ty.kind(&Interner) {
22 TyKind::Scalar(Scalar::Int(_)) 22 TyKind::Scalar(Scalar::Int(_))
23 | TyKind::Scalar(Scalar::Uint(_)) 23 | TyKind::Scalar(Scalar::Uint(_))
24 | TyKind::Scalar(Scalar::Float(_)) => rhs_ty, 24 | TyKind::Scalar(Scalar::Float(_)) => rhs_ty,
@@ -33,7 +33,7 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
33 match op { 33 match op {
34 BinaryOp::LogicOp(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), 34 BinaryOp::LogicOp(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
35 BinaryOp::Assignment { op: None } => lhs_ty, 35 BinaryOp::Assignment { op: None } => lhs_ty,
36 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty.interned(&Interner) { 36 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty.kind(&Interner) {
37 TyKind::Scalar(_) | TyKind::Str => lhs_ty, 37 TyKind::Scalar(_) | TyKind::Str => lhs_ty,
38 TyKind::InferenceVar(_, TyVariableKind::Integer) 38 TyKind::InferenceVar(_, TyVariableKind::Integer)
39 | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty, 39 | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
@@ -44,7 +44,7 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
44 } 44 }
45 BinaryOp::CmpOp(CmpOp::Ord { .. }) 45 BinaryOp::CmpOp(CmpOp::Ord { .. })
46 | BinaryOp::Assignment { op: Some(_) } 46 | BinaryOp::Assignment { op: Some(_) }
47 | BinaryOp::ArithOp(_) => match lhs_ty.interned(&Interner) { 47 | BinaryOp::ArithOp(_) => match lhs_ty.kind(&Interner) {
48 TyKind::Scalar(Scalar::Int(_)) 48 TyKind::Scalar(Scalar::Int(_))
49 | TyKind::Scalar(Scalar::Uint(_)) 49 | TyKind::Scalar(Scalar::Uint(_))
50 | TyKind::Scalar(Scalar::Float(_)) => lhs_ty, 50 | TyKind::Scalar(Scalar::Float(_)) => lhs_ty,
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs
index ad283c1e0..ccfb88c52 100644
--- a/crates/hir_ty/src/tests.rs
+++ b/crates/hir_ty/src/tests.rs
@@ -288,7 +288,7 @@ fn visit_module(
288 } 288 }
289 289
290 fn visit_body(db: &TestDB, body: &Body, cb: &mut dyn FnMut(DefWithBodyId)) { 290 fn visit_body(db: &TestDB, body: &Body, cb: &mut dyn FnMut(DefWithBodyId)) {
291 for def_map in body.block_scopes.iter().filter_map(|block| db.block_def_map(*block)) { 291 for (_, def_map) in body.blocks(db) {
292 for (mod_id, _) in def_map.modules() { 292 for (mod_id, _) in def_map.modules() {
293 visit_module(db, &def_map, mod_id, cb); 293 visit_module(db, &def_map, mod_id, cb);
294 } 294 }
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index ccee0e5ad..e5e8cff33 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -138,7 +138,7 @@ pub(crate) fn trait_solve_query(
138 .. 138 ..
139 })) = &goal.value.goal 139 })) = &goal.value.goal
140 { 140 {
141 if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) { 141 if let TyKind::BoundVar(_) = projection_ty.self_type_parameter().kind(&Interner) {
142 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible 142 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible
143 return Some(Solution::Ambig(Guidance::Unknown)); 143 return Some(Solution::Ambig(Guidance::Unknown));
144 } 144 }
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 011bef6f6..541e6082f 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -3,7 +3,7 @@ use std::sync::Arc;
3 3
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg}; 6use chalk_ir::{fold::shift::Shift, CanonicalVarKinds};
7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; 7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
8 8
9use base_db::{salsa::InternKey, CrateId}; 9use base_db::{salsa::InternKey, CrateId};
@@ -22,7 +22,7 @@ use crate::{
22 to_assoc_type_id, to_chalk_trait_id, 22 to_assoc_type_id, to_chalk_trait_id,
23 utils::generics, 23 utils::generics,
24 AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, ProjectionTy, Substitution, 24 AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, ProjectionTy, Substitution,
25 TraitRef, Ty, TyKind, WhereClause, 25 TraitRef, Ty, TyBuilder, TyKind, WhereClause,
26}; 26};
27use mapping::{ 27use mapping::{
28 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, 28 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
@@ -80,7 +80,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
80 fn impls_for_trait( 80 fn impls_for_trait(
81 &self, 81 &self,
82 trait_id: TraitId, 82 trait_id: TraitId,
83 parameters: &[GenericArg<Interner>], 83 parameters: &[chalk_ir::GenericArg<Interner>],
84 binders: &CanonicalVarKinds<Interner>, 84 binders: &CanonicalVarKinds<Interner>,
85 ) -> Vec<ImplId> { 85 ) -> Vec<ImplId> {
86 debug!("impls_for_trait {:?}", trait_id); 86 debug!("impls_for_trait {:?}", trait_id);
@@ -92,7 +92,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
92 ty: &Ty, 92 ty: &Ty,
93 binders: &CanonicalVarKinds<Interner>, 93 binders: &CanonicalVarKinds<Interner>,
94 ) -> Option<chalk_ir::TyVariableKind> { 94 ) -> Option<chalk_ir::TyVariableKind> {
95 if let TyKind::BoundVar(bv) = ty.interned(&Interner) { 95 if let TyKind::BoundVar(bv) = ty.kind(&Interner) {
96 let binders = binders.as_slice(&Interner); 96 let binders = binders.as_slice(&Interner);
97 if bv.debruijn == DebruijnIndex::INNERMOST { 97 if bv.debruijn == DebruijnIndex::INNERMOST {
98 if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind { 98 if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind {
@@ -300,7 +300,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
300 _closure_id: chalk_ir::ClosureId<Interner>, 300 _closure_id: chalk_ir::ClosureId<Interner>,
301 _substs: &chalk_ir::Substitution<Interner>, 301 _substs: &chalk_ir::Substitution<Interner>,
302 ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> { 302 ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> {
303 let ty = Ty::unit().to_chalk(self.db); 303 let ty = TyBuilder::unit().to_chalk(self.db);
304 make_binders(ty, 0) 304 make_binders(ty, 0)
305 } 305 }
306 fn closure_fn_substitution( 306 fn closure_fn_substitution(
@@ -308,7 +308,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
308 _closure_id: chalk_ir::ClosureId<Interner>, 308 _closure_id: chalk_ir::ClosureId<Interner>,
309 _substs: &chalk_ir::Substitution<Interner>, 309 _substs: &chalk_ir::Substitution<Interner>,
310 ) -> chalk_ir::Substitution<Interner> { 310 ) -> chalk_ir::Substitution<Interner> {
311 Substitution::empty().to_chalk(self.db) 311 Substitution::empty(&Interner).to_chalk(self.db)
312 } 312 }
313 313
314 fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String { 314 fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String {
@@ -387,7 +387,7 @@ pub(crate) fn associated_ty_data_query(
387 // Lower bounds -- we could/should maybe move this to a separate query in `lower` 387 // Lower bounds -- we could/should maybe move this to a separate query in `lower`
388 let type_alias_data = db.type_alias_data(type_alias); 388 let type_alias_data = db.type_alias_data(type_alias);
389 let generic_params = generics(db.upcast(), type_alias.into()); 389 let generic_params = generics(db.upcast(), type_alias.into());
390 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 390 let bound_vars = generic_params.bound_vars_subst(DebruijnIndex::INNERMOST);
391 let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast()); 391 let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast());
392 let ctx = crate::TyLoweringContext::new(db, &resolver) 392 let ctx = crate::TyLoweringContext::new(db, &resolver)
393 .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable); 393 .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable);
@@ -421,7 +421,7 @@ pub(crate) fn trait_datum_query(
421 let trait_data = db.trait_data(trait_); 421 let trait_data = db.trait_data(trait_);
422 debug!("trait {:?} = {:?}", trait_id, trait_data.name); 422 debug!("trait {:?} = {:?}", trait_id, trait_data.name);
423 let generic_params = generics(db.upcast(), trait_.into()); 423 let generic_params = generics(db.upcast(), trait_.into());
424 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 424 let bound_vars = generic_params.bound_vars_subst(DebruijnIndex::INNERMOST);
425 let flags = rust_ir::TraitFlags { 425 let flags = rust_ir::TraitFlags {
426 auto: trait_data.is_auto, 426 auto: trait_data.is_auto,
427 upstream: trait_.lookup(db.upcast()).container.krate() != krate, 427 upstream: trait_.lookup(db.upcast()).container.krate() != krate,
@@ -439,7 +439,7 @@ pub(crate) fn trait_datum_query(
439 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name)); 439 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name));
440 let trait_datum = TraitDatum { 440 let trait_datum = TraitDatum {
441 id: trait_id, 441 id: trait_id,
442 binders: make_binders(trait_datum_bound, bound_vars.len()), 442 binders: make_binders(trait_datum_bound, bound_vars.len(&Interner)),
443 flags, 443 flags,
444 associated_ty_ids, 444 associated_ty_ids,
445 well_known, 445 well_known,
@@ -490,7 +490,7 @@ pub(crate) fn struct_datum_query(
490 let upstream = adt_id.module(db.upcast()).krate() != krate; 490 let upstream = adt_id.module(db.upcast()).krate() != krate;
491 let where_clauses = { 491 let where_clauses = {
492 let generic_params = generics(db.upcast(), adt_id.into()); 492 let generic_params = generics(db.upcast(), adt_id.into());
493 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 493 let bound_vars = generic_params.bound_vars_subst(DebruijnIndex::INNERMOST);
494 convert_where_clauses(db, adt_id.into(), &bound_vars) 494 convert_where_clauses(db, adt_id.into(), &bound_vars)
495 }; 495 };
496 let flags = rust_ir::AdtFlags { 496 let flags = rust_ir::AdtFlags {
@@ -539,7 +539,7 @@ fn impl_def_datum(
539 let impl_data = db.impl_data(impl_id); 539 let impl_data = db.impl_data(impl_id);
540 540
541 let generic_params = generics(db.upcast(), impl_id.into()); 541 let generic_params = generics(db.upcast(), impl_id.into());
542 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 542 let bound_vars = generic_params.bound_vars_subst(DebruijnIndex::INNERMOST);
543 let trait_ = trait_ref.hir_trait_id(); 543 let trait_ = trait_ref.hir_trait_id();
544 let impl_type = if impl_id.lookup(db.upcast()).container.krate() == krate { 544 let impl_type = if impl_id.lookup(db.upcast()).container.krate() == krate {
545 rust_ir::ImplType::Local 545 rust_ir::ImplType::Local
@@ -577,7 +577,7 @@ fn impl_def_datum(
577 .collect(); 577 .collect();
578 debug!("impl_datum: {:?}", impl_datum_bound); 578 debug!("impl_datum: {:?}", impl_datum_bound);
579 let impl_datum = ImplDatum { 579 let impl_datum = ImplDatum {
580 binders: make_binders(impl_datum_bound, bound_vars.len()), 580 binders: make_binders(impl_datum_bound, bound_vars.len(&Interner)),
581 impl_type, 581 impl_type,
582 polarity, 582 polarity,
583 associated_ty_value_ids, 583 associated_ty_value_ids,
@@ -629,7 +629,7 @@ pub(crate) fn fn_def_datum_query(
629 let callable_def: CallableDefId = from_chalk(db, fn_def_id); 629 let callable_def: CallableDefId = from_chalk(db, fn_def_id);
630 let generic_params = generics(db.upcast(), callable_def.into()); 630 let generic_params = generics(db.upcast(), callable_def.into());
631 let sig = db.callable_item_signature(callable_def); 631 let sig = db.callable_item_signature(callable_def);
632 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 632 let bound_vars = generic_params.bound_vars_subst(DebruijnIndex::INNERMOST);
633 let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars); 633 let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars);
634 let bound = rust_ir::FnDefDatumBound { 634 let bound = rust_ir::FnDefDatumBound {
635 // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway 635 // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index aef6b8a15..452b357e8 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -13,7 +13,7 @@ use crate::{
13 db::HirDatabase, 13 db::HirDatabase,
14 primitive::UintTy, 14 primitive::UintTy,
15 traits::{Canonical, DomainGoal}, 15 traits::{Canonical, DomainGoal},
16 AliasTy, CallableDefId, FnPointer, InEnvironment, OpaqueTy, ProjectionTy, 16 AliasTy, CallableDefId, FnPointer, GenericArg, InEnvironment, OpaqueTy, ProjectionTy,
17 QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TypeWalk, WhereClause, 17 QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TypeWalk, WhereClause,
18}; 18};
19 19
@@ -137,7 +137,7 @@ impl ToChalk for Ty {
137 db, 137 db,
138 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), 138 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"),
139 ); 139 );
140 TyKind::Function(FnPointer { num_args: (substs.len() - 1), sig, substs }) 140 TyKind::Function(FnPointer { num_args: (substs.len(&Interner) - 1), sig, substs })
141 } 141 }
142 chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx), 142 chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx),
143 chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Unknown, 143 chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Unknown,
@@ -216,24 +216,39 @@ fn array_to_chalk(db: &dyn HirDatabase, ty: Ty) -> chalk_ir::Ty<Interner> {
216 chalk_ir::TyKind::Array(arg, const_).intern(&Interner) 216 chalk_ir::TyKind::Array(arg, const_).intern(&Interner)
217} 217}
218 218
219impl ToChalk for GenericArg {
220 type Chalk = chalk_ir::GenericArg<Interner>;
221
222 fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk {
223 match self.interned {
224 crate::GenericArgData::Ty(ty) => ty.to_chalk(db).cast(&Interner),
225 }
226 }
227
228 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
229 match chalk.interned() {
230 chalk_ir::GenericArgData::Ty(ty) => Ty::from_chalk(db, ty.clone()).cast(&Interner),
231 chalk_ir::GenericArgData::Lifetime(_) => unimplemented!(),
232 chalk_ir::GenericArgData::Const(_) => unimplemented!(),
233 }
234 }
235}
236
219impl ToChalk for Substitution { 237impl ToChalk for Substitution {
220 type Chalk = chalk_ir::Substitution<Interner>; 238 type Chalk = chalk_ir::Substitution<Interner>;
221 239
222 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> { 240 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
223 chalk_ir::Substitution::from_iter(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db))) 241 chalk_ir::Substitution::from_iter(
242 &Interner,
243 self.iter(&Interner).map(|ty| ty.clone().to_chalk(db)),
244 )
224 } 245 }
225 246
226 fn from_chalk( 247 fn from_chalk(
227 db: &dyn HirDatabase, 248 db: &dyn HirDatabase,
228 parameters: chalk_ir::Substitution<Interner>, 249 parameters: chalk_ir::Substitution<Interner>,
229 ) -> Substitution { 250 ) -> Substitution {
230 let tys = parameters 251 let tys = parameters.iter(&Interner).map(|p| from_chalk(db, p.clone())).collect();
231 .iter(&Interner)
232 .map(|p| match p.ty(&Interner) {
233 Some(ty) => from_chalk(db, ty.clone()),
234 None => unimplemented!(),
235 })
236 .collect();
237 Substitution(tys) 252 Substitution(tys)
238 } 253 }
239} 254}
@@ -531,7 +546,7 @@ pub(super) fn generic_predicate_to_inline_bound(
531 // have the expected self type 546 // have the expected self type
532 return None; 547 return None;
533 } 548 }
534 let args_no_self = trait_ref.substitution[1..] 549 let args_no_self = trait_ref.substitution.interned(&Interner)[1..]
535 .iter() 550 .iter()
536 .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) 551 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
537 .collect(); 552 .collect();
@@ -543,7 +558,7 @@ pub(super) fn generic_predicate_to_inline_bound(
543 return None; 558 return None;
544 } 559 }
545 let trait_ = projection_ty.trait_(db); 560 let trait_ = projection_ty.trait_(db);
546 let args_no_self = projection_ty.substitution[1..] 561 let args_no_self = projection_ty.substitution.interned(&Interner)[1..]
547 .iter() 562 .iter()
548 .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) 563 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
549 .collect(); 564 .collect();
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index 42d7af146..b23e91b1b 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -2,7 +2,7 @@
2//! query, but can't be computed directly from `*Data` (ie, which need a `db`). 2//! query, but can't be computed directly from `*Data` (ie, which need a `db`).
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use chalk_ir::DebruijnIndex; 5use chalk_ir::{BoundVar, DebruijnIndex};
6use hir_def::{ 6use hir_def::{
7 adt::VariantData, 7 adt::VariantData,
8 db::DefDatabase, 8 db::DefDatabase,
@@ -16,7 +16,7 @@ use hir_def::{
16}; 16};
17use hir_expand::name::{name, Name}; 17use hir_expand::name::{name, Name};
18 18
19use crate::{db::HirDatabase, TraitRef, TypeWalk, WhereClause}; 19use crate::{db::HirDatabase, Interner, Substitution, TraitRef, TyKind, TypeWalk, WhereClause};
20 20
21fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> { 21fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
22 let resolver = trait_.resolver(db); 22 let resolver = trait_.resolver(db);
@@ -249,6 +249,26 @@ impl Generics {
249 self.parent_generics.as_ref().and_then(|g| g.find_param(param)) 249 self.parent_generics.as_ref().and_then(|g| g.find_param(param))
250 } 250 }
251 } 251 }
252
253 /// Returns a Substitution that replaces each parameter by a bound variable.
254 pub(crate) fn bound_vars_subst(&self, debruijn: DebruijnIndex) -> Substitution {
255 Substitution::from_iter(
256 &Interner,
257 self.iter()
258 .enumerate()
259 .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)),
260 )
261 }
262
263 /// Returns a Substitution that replaces each parameter by itself (i.e. `Ty::Param`).
264 pub(crate) fn type_params_subst(&self, db: &dyn HirDatabase) -> Substitution {
265 Substitution::from_iter(
266 &Interner,
267 self.iter().map(|(id, _)| {
268 TyKind::Placeholder(crate::to_placeholder_idx(db, id)).intern(&Interner)
269 }),
270 )
271 }
252} 272}
253 273
254fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Option<GenericDefId> { 274fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Option<GenericDefId> {