aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src')
-rw-r--r--crates/hir_ty/src/autoderef.rs49
-rw-r--r--crates/hir_ty/src/builder.rs220
-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/db.rs2
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs5
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs13
-rw-r--r--crates/hir_ty/src/diagnostics/match_check.rs47
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs8
-rw-r--r--crates/hir_ty/src/display.rs142
-rw-r--r--crates/hir_ty/src/infer.rs63
-rw-r--r--crates/hir_ty/src/infer/coerce.rs39
-rw-r--r--crates/hir_ty/src/infer/expr.rs158
-rw-r--r--crates/hir_ty/src/infer/pat.rs56
-rw-r--r--crates/hir_ty/src/infer/path.rs40
-rw-r--r--crates/hir_ty/src/infer/unify.rs103
-rw-r--r--crates/hir_ty/src/lib.rs893
-rw-r--r--crates/hir_ty/src/lower.rs287
-rw-r--r--crates/hir_ty/src/method_resolution.rs51
-rw-r--r--crates/hir_ty/src/op.rs22
-rw-r--r--crates/hir_ty/src/tests.rs2
-rw-r--r--crates/hir_ty/src/tests/macros.rs109
-rw-r--r--crates/hir_ty/src/tests/traits.rs43
-rw-r--r--crates/hir_ty/src/traits.rs90
-rw-r--r--crates/hir_ty/src/traits/chalk.rs75
-rw-r--r--crates/hir_ty/src/traits/chalk/interner.rs43
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs94
-rw-r--r--crates/hir_ty/src/types.rs475
-rw-r--r--crates/hir_ty/src/utils.rs48
-rw-r--r--crates/hir_ty/src/walk.rs383
30 files changed, 2032 insertions, 1563 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index dc5fc759a..7ca4af80e 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -12,12 +12,8 @@ use hir_expand::name::name;
12use log::{info, warn}; 12use log::{info, warn};
13 13
14use crate::{ 14use crate::{
15 db::HirDatabase, 15 db::HirDatabase, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex,
16 to_assoc_type_id, to_chalk_trait_id, 16 InEnvironment, Interner, Solution, Ty, TyBuilder, TyKind,
17 traits::{InEnvironment, Solution},
18 utils::generics,
19 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner,
20 ProjectionTy, Substitution, TraitRef, Ty, TyKind,
21}; 17};
22 18
23const AUTODEREF_RECURSION_LIMIT: usize = 10; 19const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -57,21 +53,20 @@ fn deref_by_trait(
57 }; 53 };
58 let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?; 54 let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?;
59 55
60 let generic_params = generics(db.upcast(), target.into()); 56 let projection = {
61 if generic_params.len() != 1 { 57 let b = TyBuilder::assoc_type_projection(db, target);
62 // the Target type + Deref trait should only have one generic parameter, 58 if b.remaining() != 1 {
63 // namely Deref's Self type 59 // the Target type + Deref trait should only have one generic parameter,
64 return None; 60 // namely Deref's Self type
65 } 61 return None;
62 }
63 b.push(ty.goal.value.clone()).build()
64 };
66 65
67 // FIXME make the Canonical / bound var handling nicer 66 // FIXME make the Canonical / bound var handling nicer
68 67
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 68 // Check that the type implements Deref at all
73 let trait_ref = 69 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 { 70 let implements_goal = Canonical {
76 binders: ty.goal.binders.clone(), 71 binders: ty.goal.binders.clone(),
77 value: InEnvironment { 72 value: InEnvironment {
@@ -84,11 +79,8 @@ fn deref_by_trait(
84 } 79 }
85 80
86 // Now do the assoc type projection 81 // Now do the assoc type projection
87 let projection = AliasEq { 82 let alias_eq = AliasEq {
88 alias: AliasTy::Projection(ProjectionTy { 83 alias: AliasTy::Projection(projection),
89 associated_ty_id: to_assoc_type_id(target),
90 substitution: parameters,
91 }),
92 ty: TyKind::BoundVar(BoundVar::new( 84 ty: TyKind::BoundVar(BoundVar::new(
93 DebruijnIndex::INNERMOST, 85 DebruijnIndex::INNERMOST,
94 ty.goal.binders.len(&Interner), 86 ty.goal.binders.len(&Interner),
@@ -96,9 +88,7 @@ fn deref_by_trait(
96 .intern(&Interner), 88 .intern(&Interner),
97 }; 89 };
98 90
99 let obligation = projection.cast(&Interner); 91 let in_env = InEnvironment { goal: alias_eq.cast(&Interner), environment: ty.environment };
100
101 let in_env = InEnvironment { goal: obligation, environment: ty.environment };
102 92
103 let canonical = Canonical { 93 let canonical = Canonical {
104 value: in_env, 94 value: in_env,
@@ -131,7 +121,7 @@ fn deref_by_trait(
131 // new variables in that case 121 // new variables in that case
132 122
133 for i in 1..vars.0.binders.len(&Interner) { 123 for i in 1..vars.0.binders.len(&Interner) {
134 if vars.0.value[i - 1].interned(&Interner) 124 if vars.0.value.at(&Interner, i - 1).assert_ty_ref(&Interner).kind(&Interner)
135 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 125 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
136 { 126 {
137 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution); 127 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
@@ -139,7 +129,12 @@ fn deref_by_trait(
139 } 129 }
140 } 130 }
141 Some(Canonical { 131 Some(Canonical {
142 value: vars.0.value[vars.0.value.len() - 1].clone(), 132 value: vars
133 .0
134 .value
135 .at(&Interner, vars.0.value.len(&Interner) - 1)
136 .assert_ty_ref(&Interner)
137 .clone(),
143 binders: vars.0.binders.clone(), 138 binders: vars.0.binders.clone(),
144 }) 139 })
145 } 140 }
diff --git a/crates/hir_ty/src/builder.rs b/crates/hir_ty/src/builder.rs
new file mode 100644
index 000000000..9b2c6975a
--- /dev/null
+++ b/crates/hir_ty/src/builder.rs
@@ -0,0 +1,220 @@
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::intern(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::Error.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::intern(self.vec.clone());
142 self.vec
143 .push(default_ty.clone().substitute(&Interner, &subst_so_far).cast(&Interner));
144 }
145 }
146 self
147 }
148
149 pub fn build(self) -> Ty {
150 let (adt, subst) = self.build_internal();
151 TyKind::Adt(AdtId(adt), subst).intern(&Interner)
152 }
153}
154
155pub struct Tuple(usize);
156impl TyBuilder<Tuple> {
157 pub fn tuple(size: usize) -> TyBuilder<Tuple> {
158 TyBuilder::new(Tuple(size), size)
159 }
160
161 pub fn build(self) -> Ty {
162 let (Tuple(size), subst) = self.build_internal();
163 TyKind::Tuple(size, subst).intern(&Interner)
164 }
165}
166
167impl TyBuilder<TraitId> {
168 pub fn trait_ref(db: &dyn HirDatabase, trait_id: TraitId) -> TyBuilder<TraitId> {
169 let generics = generics(db.upcast(), trait_id.into());
170 let param_count = generics.len();
171 TyBuilder::new(trait_id, param_count)
172 }
173
174 pub fn build(self) -> TraitRef {
175 let (trait_id, substitution) = self.build_internal();
176 TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution }
177 }
178}
179
180impl TyBuilder<TypeAliasId> {
181 pub fn assoc_type_projection(
182 db: &dyn HirDatabase,
183 type_alias: TypeAliasId,
184 ) -> TyBuilder<TypeAliasId> {
185 let generics = generics(db.upcast(), type_alias.into());
186 let param_count = generics.len();
187 TyBuilder::new(type_alias, param_count)
188 }
189
190 pub fn build(self) -> ProjectionTy {
191 let (type_alias, substitution) = self.build_internal();
192 ProjectionTy { associated_ty_id: to_assoc_type_id(type_alias), substitution }
193 }
194}
195
196impl<T: TypeWalk + HasInterner<Interner = Interner>> TyBuilder<Binders<T>> {
197 fn subst_binders(b: Binders<T>) -> Self {
198 let param_count = b.binders.len(&Interner);
199 TyBuilder::new(b, param_count)
200 }
201
202 pub fn build(self) -> T {
203 let (b, subst) = self.build_internal();
204 b.substitute(&Interner, &subst)
205 }
206}
207
208impl TyBuilder<Binders<Ty>> {
209 pub fn def_ty(db: &dyn HirDatabase, def: TyDefId) -> TyBuilder<Binders<Ty>> {
210 TyBuilder::subst_binders(db.ty(def.into()))
211 }
212
213 pub fn impl_self_ty(db: &dyn HirDatabase, def: hir_def::ImplId) -> TyBuilder<Binders<Ty>> {
214 TyBuilder::subst_binders(db.impl_self_ty(def))
215 }
216
217 pub fn value_ty(db: &dyn HirDatabase, def: ValueTyDefId) -> TyBuilder<Binders<Ty>> {
218 TyBuilder::subst_binders(db.value_ty(def))
219 }
220}
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/db.rs b/crates/hir_ty/src/db.rs
index 58e4247c6..4300680d9 100644
--- a/crates/hir_ty/src/db.rs
+++ b/crates/hir_ty/src/db.rs
@@ -123,7 +123,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
123 &self, 123 &self,
124 krate: CrateId, 124 krate: CrateId,
125 goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>, 125 goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>,
126 ) -> Option<crate::traits::Solution>; 126 ) -> Option<crate::Solution>;
127 127
128 #[salsa::invoke(crate::traits::chalk::program_clauses_for_chalk_env_query)] 128 #[salsa::invoke(crate::traits::chalk::program_clauses_for_chalk_env_query)]
129 fn program_clauses_for_chalk_env( 129 fn program_clauses_for_chalk_env(
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..db278d0db 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::{
@@ -245,7 +245,8 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
245 Some(callee) => callee, 245 Some(callee) => callee,
246 None => return, 246 None => return,
247 }; 247 };
248 let sig = db.callable_item_signature(callee.into()).value; 248 let sig =
249 db.callable_item_signature(callee.into()).into_value_and_skipped_binders().0;
249 250
250 (sig, args) 251 (sig, args)
251 } 252 }
@@ -378,7 +379,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
378 _ => return, 379 _ => return,
379 }; 380 };
380 381
381 let (params, required) = match mismatch.expected.interned(&Interner) { 382 let (params, required) = match mismatch.expected.kind(&Interner) {
382 TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters) 383 TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters)
383 if *enum_id == core_result_enum => 384 if *enum_id == core_result_enum =>
384 { 385 {
@@ -392,7 +393,9 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
392 _ => return, 393 _ => return,
393 }; 394 };
394 395
395 if params.len() > 0 && params[0] == mismatch.actual { 396 if params.len(&Interner) > 0
397 && params.at(&Interner, 0).ty(&Interner) == Some(&mismatch.actual)
398 {
396 let (_, source_map) = db.body_with_source_map(self.owner); 399 let (_, source_map) = db.body_with_source_map(self.owner);
397 400
398 if let Ok(source_ptr) = source_map.expr_syntax(id) { 401 if let Ok(source_ptr) = source_map.expr_syntax(id) {
@@ -421,7 +424,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
421 None => return, 424 None => return,
422 }; 425 };
423 426
424 if mismatch.actual != Ty::unit() || mismatch.expected != *possible_tail_ty { 427 if !mismatch.actual.is_unit() || mismatch.expected != *possible_tail_ty {
425 return; 428 return;
426 } 429 }
427 430
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs
index 5a5cdcbf3..34291578a 100644
--- a/crates/hir_ty/src/diagnostics/match_check.rs
+++ b/crates/hir_ty/src/diagnostics/match_check.rs
@@ -539,7 +539,7 @@ impl Matrix {
539 if let Some(Pat::Or(pat_ids)) = row.get_head().map(|pat_id| pat_id.as_pat(cx)) { 539 if let Some(Pat::Or(pat_ids)) = row.get_head().map(|pat_id| pat_id.as_pat(cx)) {
540 // Or patterns are expanded here 540 // Or patterns are expanded here
541 for pat_id in pat_ids { 541 for pat_id in pat_ids {
542 self.0.push(PatStack::from_pattern(pat_id)); 542 self.0.push(row.replace_head_with([pat_id].iter()));
543 } 543 }
544 } else { 544 } else {
545 self.0.push(row); 545 self.0.push(row);
@@ -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] {
@@ -1085,6 +1088,20 @@ fn main() {
1085 } 1088 }
1086 1089
1087 #[test] 1090 #[test]
1091 fn or_pattern_no_diagnostic() {
1092 check_diagnostics(
1093 r#"
1094enum Either {A, B}
1095
1096fn main() {
1097 match (Either::A, Either::B) {
1098 (Either::A | Either::B, _) => (),
1099 }
1100}"#,
1101 )
1102 }
1103
1104 #[test]
1088 fn mismatched_types() { 1105 fn mismatched_types() {
1089 // Match statements with arms that don't match the 1106 // Match statements with arms that don't match the
1090 // expression pattern do not fire this diagnostic. 1107 // expression pattern do not fire this diagnostic.
@@ -1336,30 +1353,6 @@ fn bang(never: !) {
1336 } 1353 }
1337 1354
1338 #[test] 1355 #[test]
1339 fn or_pattern_panic() {
1340 check_diagnostics(
1341 r#"
1342pub enum Category { Infinity, Zero }
1343
1344fn panic(a: Category, b: Category) {
1345 match (a, b) {
1346 (Category::Zero | Category::Infinity, _) => (),
1347 (_, Category::Zero | Category::Infinity) => (),
1348 }
1349
1350 // FIXME: This is a false positive, but the code used to cause a panic in the match checker,
1351 // so this acts as a regression test for that.
1352 match (a, b) {
1353 //^^^^^^ Missing match arm
1354 (Category::Infinity, Category::Infinity) | (Category::Zero, Category::Zero) => (),
1355 (Category::Infinity | Category::Zero, _) => (),
1356 }
1357}
1358"#,
1359 );
1360 }
1361
1362 #[test]
1363 fn unknown_type() { 1356 fn unknown_type() {
1364 check_diagnostics( 1357 check_diagnostics(
1365 r#" 1358 r#"
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..f31e6b108 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(&Interner).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()[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 }
@@ -344,8 +352,8 @@ impl HirDisplay for Ty {
344 let data = (*datas) 352 let data = (*datas)
345 .as_ref() 353 .as_ref()
346 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 354 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
347 let bounds = data.subst(parameters); 355 let bounds = data.substitute(&Interner, parameters);
348 bounds.value 356 bounds.into_value_and_skipped_binders().0
349 } else { 357 } else {
350 Vec::new() 358 Vec::new()
351 } 359 }
@@ -373,13 +381,13 @@ 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, "(")?;
382 f.write_joined(&*substs.0, ", ")?; 390 f.write_joined(&*substs.interned(), ", ")?;
383 write!(f, ")")?; 391 write!(f, ")")?;
384 } 392 }
385 } 393 }
@@ -389,7 +397,7 @@ impl HirDisplay for Ty {
389 } 397 }
390 TyKind::FnDef(def, parameters) => { 398 TyKind::FnDef(def, parameters) => {
391 let def = from_chalk(f.db, *def); 399 let def = from_chalk(f.db, *def);
392 let sig = f.db.callable_item_signature(def).subst(parameters); 400 let sig = f.db.callable_item_signature(def).substitute(&Interner, parameters);
393 match def { 401 match def {
394 CallableDefId::FunctionId(ff) => { 402 CallableDefId::FunctionId(ff) => {
395 write!(f, "fn {}", f.db.function_data(ff).name)? 403 write!(f, "fn {}", f.db.function_data(ff).name)?
@@ -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();
@@ -407,7 +415,7 @@ impl HirDisplay for Ty {
407 // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? 415 // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
408 if total_len > 0 { 416 if total_len > 0 {
409 write!(f, "<")?; 417 write!(f, "<")?;
410 f.write_joined(&parameters.0[..total_len], ", ")?; 418 f.write_joined(&parameters.interned()[..total_len], ", ")?;
411 write!(f, ">")?; 419 write!(f, ">")?;
412 } 420 }
413 } 421 }
@@ -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 {
@@ -460,30 +468,33 @@ impl HirDisplay for Ty {
460 .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) 468 .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
461 .filter(|defaults| !defaults.is_empty()) 469 .filter(|defaults| !defaults.is_empty())
462 { 470 {
463 None => parameters.0.as_ref(), 471 None => parameters.interned().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),
469 (&TyKind::Unknown, _) | (_, None) => { 477 default_parameters.get(i),
478 ) {
479 (&TyKind::Error, _) | (_, None) => {
470 default_from = i + 1; 480 default_from = i + 1;
471 } 481 }
472 (_, Some(default_parameter)) => { 482 (_, Some(default_parameter)) => {
473 let actual_default = default_parameter 483 let actual_default = default_parameter
474 .clone() 484 .clone()
475 .subst(&parameters.prefix(i)); 485 .substitute(&Interner, &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 }
480 } 491 }
481 } 492 }
482 &parameters.0[0..default_from] 493 &parameters.interned()[0..default_from]
483 } 494 }
484 } 495 }
485 } else { 496 } else {
486 parameters.0.as_ref() 497 parameters.interned().as_ref()
487 }; 498 };
488 if !parameters_to_write.is_empty() { 499 if !parameters_to_write.is_empty() {
489 write!(f, "<")?; 500 write!(f, "<")?;
@@ -504,9 +515,9 @@ 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.interned(), ", ")?;
510 write!(f, ">")?; 521 write!(f, ">")?;
511 } 522 }
512 } else { 523 } else {
@@ -518,7 +529,7 @@ impl HirDisplay for Ty {
518 projection_ty.hir_fmt(f)?; 529 projection_ty.hir_fmt(f)?;
519 } 530 }
520 } 531 }
521 TyKind::ForeignType(type_alias) => { 532 TyKind::Foreign(type_alias) => {
522 let type_alias = f.db.type_alias_data(from_foreign_def_id(*type_alias)); 533 let type_alias = f.db.type_alias_data(from_foreign_def_id(*type_alias));
523 write!(f, "{}", type_alias.name)?; 534 write!(f, "{}", type_alias.name)?;
524 } 535 }
@@ -531,13 +542,13 @@ impl HirDisplay for Ty {
531 let data = (*datas) 542 let data = (*datas)
532 .as_ref() 543 .as_ref()
533 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 544 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
534 let bounds = data.subst(&parameters); 545 let bounds = data.substitute(&Interner, &parameters);
535 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 546 write_bounds_like_dyn_trait_with_prefix("impl", bounds.skip_binders(), f)?;
536 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution 547 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
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,21 +591,22 @@ 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 =
585 .db 596 f.db.generic_predicates(id.parent)
586 .generic_predicates(id.parent) 597 .into_iter()
587 .into_iter() 598 .map(|pred| pred.clone().substitute(&Interner, &substs))
588 .map(|pred| pred.clone().subst(&substs)) 599 .filter(|wc| match &wc.skip_binders() {
589 .filter(|wc| match &wc.skip_binders() { 600 WhereClause::Implemented(tr) => {
590 WhereClause::Implemented(tr) => tr.self_type_parameter() == self, 601 tr.self_type_parameter(&Interner) == self
591 WhereClause::AliasEq(AliasEq { 602 }
592 alias: AliasTy::Projection(proj), 603 WhereClause::AliasEq(AliasEq {
593 ty: _, 604 alias: AliasTy::Projection(proj),
594 }) => proj.self_type_parameter() == self, 605 ty: _,
595 _ => false, 606 }) => proj.self_type_parameter(&Interner) == self,
596 }) 607 _ => false,
597 .collect::<Vec<_>>(); 608 })
609 .collect::<Vec<_>>();
598 write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?; 610 write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?;
599 } 611 }
600 } 612 }
@@ -617,15 +629,15 @@ impl HirDisplay for Ty {
617 let data = (*datas) 629 let data = (*datas)
618 .as_ref() 630 .as_ref()
619 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 631 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
620 let bounds = data.subst(&opaque_ty.substitution); 632 let bounds = data.substitute(&Interner, &opaque_ty.substitution);
621 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 633 write_bounds_like_dyn_trait_with_prefix("impl", bounds.skip_binders(), f)?;
622 } 634 }
623 ImplTraitId::AsyncBlockTypeImplTrait(..) => { 635 ImplTraitId::AsyncBlockTypeImplTrait(..) => {
624 write!(f, "{{async block}}")?; 636 write!(f, "{{async block}}")?;
625 } 637 }
626 }; 638 };
627 } 639 }
628 TyKind::Unknown => { 640 TyKind::Error => {
629 if f.display_target.is_source_code() { 641 if f.display_target.is_source_code() {
630 return Err(HirDisplayError::DisplaySourceCodeError( 642 return Err(HirDisplayError::DisplaySourceCodeError(
631 DisplaySourceCodeError::UnknownType, 643 DisplaySourceCodeError::UnknownType,
@@ -652,7 +664,7 @@ impl HirDisplay for CallableSig {
652 } 664 }
653 write!(f, ")")?; 665 write!(f, ")")?;
654 let ret = self.ret(); 666 let ret = self.ret();
655 if *ret != Ty::unit() { 667 if !ret.is_unit() {
656 let ret_display = 668 let ret_display =
657 ret.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); 669 ret.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
658 write!(f, " -> {}", ret_display)?; 670 write!(f, " -> {}", ret_display)?;
@@ -716,11 +728,13 @@ fn write_bounds_like_dyn_trait(
716 // existential) here, which is the only thing that's 728 // existential) here, which is the only thing that's
717 // possible in actual Rust, and hence don't print it 729 // possible in actual Rust, and hence don't print it
718 write!(f, "{}", f.db.trait_data(trait_).name)?; 730 write!(f, "{}", f.db.trait_data(trait_).name)?;
719 if let [_, params @ ..] = &*trait_ref.substitution.0 { 731 if let [_, params @ ..] = &*trait_ref.substitution.interned() {
720 if is_fn_trait { 732 if is_fn_trait {
721 if let Some(args) = params.first().and_then(|it| it.as_tuple()) { 733 if let Some(args) =
734 params.first().and_then(|it| it.assert_ty_ref(&Interner).as_tuple())
735 {
722 write!(f, "(")?; 736 write!(f, "(")?;
723 f.write_joined(&*args.0, ", ")?; 737 f.write_joined(&*args.interned(), ", ")?;
724 write!(f, ")")?; 738 write!(f, ")")?;
725 } 739 }
726 } else if !params.is_empty() { 740 } else if !params.is_empty() {
@@ -767,16 +781,16 @@ impl TraitRef {
767 return write!(f, "{}", TYPE_HINT_TRUNCATION); 781 return write!(f, "{}", TYPE_HINT_TRUNCATION);
768 } 782 }
769 783
770 self.substitution[0].hir_fmt(f)?; 784 self.self_type_parameter(&Interner).hir_fmt(f)?;
771 if use_as { 785 if use_as {
772 write!(f, " as ")?; 786 write!(f, " as ")?;
773 } else { 787 } else {
774 write!(f, ": ")?; 788 write!(f, ": ")?;
775 } 789 }
776 write!(f, "{}", f.db.trait_data(self.hir_trait_id()).name)?; 790 write!(f, "{}", f.db.trait_data(self.hir_trait_id()).name)?;
777 if self.substitution.len() > 1 { 791 if self.substitution.len(&Interner) > 1 {
778 write!(f, "<")?; 792 write!(f, "<")?;
779 f.write_joined(&self.substitution[1..], ", ")?; 793 f.write_joined(&self.substitution.interned()[1..], ", ")?;
780 write!(f, ">")?; 794 write!(f, ">")?;
781 } 795 }
782 Ok(()) 796 Ok(())
@@ -1016,11 +1030,11 @@ impl HirDisplay for Path {
1016 } 1030 }
1017} 1031}
1018 1032
1019impl HirDisplay for GenericArg { 1033impl HirDisplay for hir_def::path::GenericArg {
1020 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 1034 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
1021 match self { 1035 match self {
1022 GenericArg::Type(ty) => ty.hir_fmt(f), 1036 hir_def::path::GenericArg::Type(ty) => ty.hir_fmt(f),
1023 GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name), 1037 hir_def::path::GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name),
1024 } 1038 }
1025 } 1039 }
1026} 1040}
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index e4407ff50..1c3faf5cb 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -37,12 +37,12 @@ use stdx::impl_from;
37use syntax::SmolStr; 37use syntax::SmolStr;
38 38
39use super::{ 39use super::{
40 traits::{DomainGoal, Guidance, Solution}, 40 DomainGoal, Guidance, InEnvironment, ProjectionTy, Solution, TraitEnvironment, TraitRef, Ty,
41 InEnvironment, ProjectionTy, Substitution, TraitEnvironment, TraitRef, Ty, TypeWalk, 41 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.
@@ -120,7 +120,7 @@ struct InternedStandardTypes {
120 120
121impl Default for InternedStandardTypes { 121impl Default for InternedStandardTypes {
122 fn default() -> Self { 122 fn default() -> Self {
123 InternedStandardTypes { unknown: TyKind::Unknown.intern(&Interner) } 123 InternedStandardTypes { unknown: TyKind::Error.intern(&Interner) }
124 } 124 }
125} 125}
126 126
@@ -210,6 +210,7 @@ struct InferenceContext<'a> {
210 table: unify::InferenceTable, 210 table: unify::InferenceTable,
211 trait_env: Arc<TraitEnvironment>, 211 trait_env: Arc<TraitEnvironment>,
212 obligations: Vec<DomainGoal>, 212 obligations: Vec<DomainGoal>,
213 last_obligations_check: Option<u32>,
213 result: InferenceResult, 214 result: InferenceResult,
214 /// The return type of the function being inferred, or the closure if we're 215 /// The return type of the function being inferred, or the closure if we're
215 /// currently within one. 216 /// currently within one.
@@ -245,7 +246,8 @@ impl<'a> InferenceContext<'a> {
245 result: InferenceResult::default(), 246 result: InferenceResult::default(),
246 table: unify::InferenceTable::new(), 247 table: unify::InferenceTable::new(),
247 obligations: Vec::default(), 248 obligations: Vec::default(),
248 return_ty: TyKind::Unknown.intern(&Interner), // set in collect_fn_signature 249 last_obligations_check: None,
250 return_ty: TyKind::Error.intern(&Interner), // set in collect_fn_signature
249 trait_env: owner 251 trait_env: owner
250 .as_generic_def_id() 252 .as_generic_def_id()
251 .map_or_else(Default::default, |d| db.trait_environment(d)), 253 .map_or_else(Default::default, |d| db.trait_environment(d)),
@@ -259,7 +261,7 @@ impl<'a> InferenceContext<'a> {
259 } 261 }
260 262
261 fn err_ty(&self) -> Ty { 263 fn err_ty(&self) -> Ty {
262 TyKind::Unknown.intern(&Interner) 264 TyKind::Error.intern(&Interner)
263 } 265 }
264 266
265 fn resolve_all(mut self) -> InferenceResult { 267 fn resolve_all(mut self) -> InferenceResult {
@@ -323,8 +325,8 @@ impl<'a> InferenceContext<'a> {
323 325
324 /// 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.
325 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { 327 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
326 match ty.interned(&Interner) { 328 match ty.kind(&Interner) {
327 TyKind::Unknown => self.table.new_type_var(), 329 TyKind::Error => self.table.new_type_var(),
328 _ => ty, 330 _ => ty,
329 } 331 }
330 } 332 }
@@ -334,6 +336,13 @@ impl<'a> InferenceContext<'a> {
334 } 336 }
335 337
336 fn resolve_obligations_as_possible(&mut self) { 338 fn resolve_obligations_as_possible(&mut self) {
339 if self.last_obligations_check == Some(self.table.revision) {
340 // no change
341 return;
342 }
343 let _span = profile::span("resolve_obligations_as_possible");
344
345 self.last_obligations_check = Some(self.table.revision);
337 let obligations = mem::replace(&mut self.obligations, Vec::new()); 346 let obligations = mem::replace(&mut self.obligations, Vec::new());
338 for obligation in obligations { 347 for obligation in obligations {
339 let in_env = InEnvironment::new(self.trait_env.env.clone(), obligation.clone()); 348 let in_env = InEnvironment::new(self.trait_env.env.clone(), obligation.clone());
@@ -360,6 +369,11 @@ impl<'a> InferenceContext<'a> {
360 } 369 }
361 } 370 }
362 371
372 fn push_obligation(&mut self, o: DomainGoal) {
373 self.obligations.push(o);
374 self.last_obligations_check = None;
375 }
376
363 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { 377 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
364 self.table.unify(ty1, ty2) 378 self.table.unify(ty1, ty2)
365 } 379 }
@@ -395,21 +409,19 @@ impl<'a> InferenceContext<'a> {
395 _ => panic!("resolve_associated_type called with non-associated type"), 409 _ => panic!("resolve_associated_type called with non-associated type"),
396 }; 410 };
397 let ty = self.table.new_type_var(); 411 let ty = self.table.new_type_var();
398 let substs = Substitution::build_for_def(self.db, res_assoc_ty) 412 let trait_ref = TyBuilder::trait_ref(self.db, trait_)
399 .push(inner_ty) 413 .push(inner_ty)
400 .fill(params.iter().cloned()) 414 .fill(params.iter().cloned())
401 .build(); 415 .build();
402 let trait_ref =
403 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs.clone() };
404 let alias_eq = AliasEq { 416 let alias_eq = AliasEq {
405 alias: AliasTy::Projection(ProjectionTy { 417 alias: AliasTy::Projection(ProjectionTy {
406 associated_ty_id: to_assoc_type_id(res_assoc_ty), 418 associated_ty_id: to_assoc_type_id(res_assoc_ty),
407 substitution: substs, 419 substitution: trait_ref.substitution.clone(),
408 }), 420 }),
409 ty: ty.clone(), 421 ty: ty.clone(),
410 }; 422 };
411 self.obligations.push(trait_ref.cast(&Interner)); 423 self.push_obligation(trait_ref.cast(&Interner));
412 self.obligations.push(alias_eq.cast(&Interner)); 424 self.push_obligation(alias_eq.cast(&Interner));
413 self.resolve_ty_as_possible(ty) 425 self.resolve_ty_as_possible(ty)
414 } 426 }
415 None => self.err_ty(), 427 None => self.err_ty(),
@@ -424,7 +436,7 @@ impl<'a> InferenceContext<'a> {
424 /// to do it as well. 436 /// to do it as well.
425 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 437 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
426 let ty = self.resolve_ty_as_possible(ty); 438 let ty = self.resolve_ty_as_possible(ty);
427 ty.fold(&mut |ty| match ty.interned(&Interner) { 439 ty.fold(&mut |ty| match ty.kind(&Interner) {
428 TyKind::Alias(AliasTy::Projection(proj_ty)) => { 440 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
429 self.normalize_projection_ty(proj_ty.clone()) 441 self.normalize_projection_ty(proj_ty.clone())
430 } 442 }
@@ -436,7 +448,7 @@ impl<'a> InferenceContext<'a> {
436 let var = self.table.new_type_var(); 448 let var = self.table.new_type_var();
437 let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() }; 449 let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() };
438 let obligation = alias_eq.cast(&Interner); 450 let obligation = alias_eq.cast(&Interner);
439 self.obligations.push(obligation); 451 self.push_obligation(obligation);
440 var 452 var
441 } 453 }
442 454
@@ -458,25 +470,25 @@ impl<'a> InferenceContext<'a> {
458 TypeNs::AdtId(AdtId::StructId(strukt)) => { 470 TypeNs::AdtId(AdtId::StructId(strukt)) => {
459 let substs = ctx.substs_from_path(path, strukt.into(), true); 471 let substs = ctx.substs_from_path(path, strukt.into(), true);
460 let ty = self.db.ty(strukt.into()); 472 let ty = self.db.ty(strukt.into());
461 let ty = self.insert_type_vars(ty.subst(&substs)); 473 let ty = self.insert_type_vars(ty.substitute(&Interner, &substs));
462 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) 474 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
463 } 475 }
464 TypeNs::AdtId(AdtId::UnionId(u)) => { 476 TypeNs::AdtId(AdtId::UnionId(u)) => {
465 let substs = ctx.substs_from_path(path, u.into(), true); 477 let substs = ctx.substs_from_path(path, u.into(), true);
466 let ty = self.db.ty(u.into()); 478 let ty = self.db.ty(u.into());
467 let ty = self.insert_type_vars(ty.subst(&substs)); 479 let ty = self.insert_type_vars(ty.substitute(&Interner, &substs));
468 forbid_unresolved_segments((ty, Some(u.into())), unresolved) 480 forbid_unresolved_segments((ty, Some(u.into())), unresolved)
469 } 481 }
470 TypeNs::EnumVariantId(var) => { 482 TypeNs::EnumVariantId(var) => {
471 let substs = ctx.substs_from_path(path, var.into(), true); 483 let substs = ctx.substs_from_path(path, var.into(), true);
472 let ty = self.db.ty(var.parent.into()); 484 let ty = self.db.ty(var.parent.into());
473 let ty = self.insert_type_vars(ty.subst(&substs)); 485 let ty = self.insert_type_vars(ty.substitute(&Interner, &substs));
474 forbid_unresolved_segments((ty, Some(var.into())), unresolved) 486 forbid_unresolved_segments((ty, Some(var.into())), unresolved)
475 } 487 }
476 TypeNs::SelfType(impl_id) => { 488 TypeNs::SelfType(impl_id) => {
477 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 489 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
478 let substs = Substitution::type_params_for_generics(self.db, &generics); 490 let substs = generics.type_params_subst(self.db);
479 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 491 let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs);
480 match unresolved { 492 match unresolved {
481 None => { 493 None => {
482 let variant = ty_variant(&ty); 494 let variant = ty_variant(&ty);
@@ -502,10 +514,9 @@ impl<'a> InferenceContext<'a> {
502 } 514 }
503 } 515 }
504 TypeNs::TypeAliasId(it) => { 516 TypeNs::TypeAliasId(it) => {
505 let substs = Substitution::build_for_def(self.db, it) 517 let ty = TyBuilder::def_ty(self.db, it.into())
506 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 518 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
507 .build(); 519 .build();
508 let ty = self.db.ty(it.into()).subst(&substs);
509 let variant = ty_variant(&ty); 520 let variant = ty_variant(&ty);
510 forbid_unresolved_segments((ty, variant), unresolved) 521 forbid_unresolved_segments((ty, variant), unresolved)
511 } 522 }
@@ -531,7 +542,7 @@ impl<'a> InferenceContext<'a> {
531 result 542 result
532 } else { 543 } else {
533 // FIXME diagnostic 544 // FIXME diagnostic
534 (TyKind::Unknown.intern(&Interner), None) 545 (TyKind::Error.intern(&Interner), None)
535 } 546 }
536 } 547 }
537 548
@@ -744,7 +755,7 @@ impl Expectation {
744 fn none() -> Self { 755 fn none() -> Self {
745 Expectation { 756 Expectation {
746 // FIXME 757 // FIXME
747 ty: TyKind::Unknown.intern(&Interner), 758 ty: TyKind::Error.intern(&Interner),
748 rvalue_hint: false, 759 rvalue_hint: false,
749 } 760 }
750 } 761 }
@@ -752,7 +763,7 @@ impl Expectation {
752 fn coercion_target(&self) -> Ty { 763 fn coercion_target(&self) -> Ty {
753 if self.rvalue_hint { 764 if self.rvalue_hint {
754 // FIXME 765 // FIXME
755 TyKind::Unknown.intern(&Interner) 766 TyKind::Error.intern(&Interner)
756 } else { 767 } else {
757 self.ty.clone() 768 self.ty.clone()
758 } 769 }
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 9c62932b1..32c273afc 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, Interner, Solution, 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 e6ede05ca..6966d26e7 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},
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, InEnvironment, Interner, Rawness, Scalar,
26 Substitution, TraitRef, Ty, TyKind, 26 Substitution, 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.obligations.push(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
@@ -119,6 +114,8 @@ impl<'a> InferenceContext<'a> {
119 } 114 }
120 115
121 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 116 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
117 self.db.check_canceled();
118
122 let body = Arc::clone(&self.body); // avoid borrow checker problem 119 let body = Arc::clone(&self.body); // avoid borrow checker problem
123 let ty = match &body[tgt_expr] { 120 let ty = match &body[tgt_expr] {
124 Expr::Missing => self.err_ty(), 121 Expr::Missing => self.err_ty(),
@@ -136,7 +133,7 @@ impl<'a> InferenceContext<'a> {
136 both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); 133 both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe);
137 let else_ty = match else_branch { 134 let else_ty = match else_branch {
138 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), 135 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected),
139 None => Ty::unit(), 136 None => TyBuilder::unit(),
140 }; 137 };
141 both_arms_diverge &= self.diverges; 138 both_arms_diverge &= self.diverges;
142 139
@@ -191,7 +188,7 @@ impl<'a> InferenceContext<'a> {
191 break_ty: self.table.new_type_var(), 188 break_ty: self.table.new_type_var(),
192 label: label.map(|label| self.body[label].name.clone()), 189 label: label.map(|label| self.body[label].name.clone()),
193 }); 190 });
194 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 191 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
195 192
196 let ctxt = self.breakables.pop().expect("breakable stack broken"); 193 let ctxt = self.breakables.pop().expect("breakable stack broken");
197 if ctxt.may_break { 194 if ctxt.may_break {
@@ -215,11 +212,11 @@ impl<'a> InferenceContext<'a> {
215 *condition, 212 *condition,
216 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), 213 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
217 ); 214 );
218 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 215 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
219 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 216 let _ctxt = self.breakables.pop().expect("breakable stack broken");
220 // 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
221 self.diverges = Diverges::Maybe; 218 self.diverges = Diverges::Maybe;
222 Ty::unit() 219 TyBuilder::unit()
223 } 220 }
224 Expr::For { iterable, body, pat, label } => { 221 Expr::For { iterable, body, pat, label } => {
225 let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); 222 let iterable_ty = self.infer_expr(*iterable, &Expectation::none());
@@ -234,11 +231,11 @@ impl<'a> InferenceContext<'a> {
234 231
235 self.infer_pat(*pat, &pat_ty, BindingMode::default()); 232 self.infer_pat(*pat, &pat_ty, BindingMode::default());
236 233
237 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 234 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
238 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 235 let _ctxt = self.breakables.pop().expect("breakable stack broken");
239 // 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
240 self.diverges = Diverges::Maybe; 237 self.diverges = Diverges::Maybe;
241 Ty::unit() 238 TyBuilder::unit()
242 } 239 }
243 Expr::Lambda { body, args, ret_type, arg_types } => { 240 Expr::Lambda { body, args, ret_type, arg_types } => {
244 assert_eq!(args.len(), arg_types.len()); 241 assert_eq!(args.len(), arg_types.len());
@@ -264,7 +261,7 @@ impl<'a> InferenceContext<'a> {
264 let sig_ty = TyKind::Function(FnPointer { 261 let sig_ty = TyKind::Function(FnPointer {
265 num_args: sig_tys.len() - 1, 262 num_args: sig_tys.len() - 1,
266 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, 263 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
267 substs: Substitution(sig_tys.clone().into()), 264 substs: Substitution::from_iter(&Interner, sig_tys.clone()),
268 }) 265 })
269 .intern(&Interner); 266 .intern(&Interner);
270 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();
@@ -358,7 +355,7 @@ impl<'a> InferenceContext<'a> {
358 let val_ty = if let Some(expr) = expr { 355 let val_ty = if let Some(expr) = expr {
359 self.infer_expr(*expr, &Expectation::none()) 356 self.infer_expr(*expr, &Expectation::none())
360 } else { 357 } else {
361 Ty::unit() 358 TyBuilder::unit()
362 }; 359 };
363 360
364 let last_ty = 361 let last_ty =
@@ -384,7 +381,7 @@ impl<'a> InferenceContext<'a> {
384 if let Some(expr) = expr { 381 if let Some(expr) = expr {
385 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()));
386 } else { 383 } else {
387 let unit = Ty::unit(); 384 let unit = TyBuilder::unit();
388 self.coerce(&unit, &self.return_ty.clone()); 385 self.coerce(&unit, &self.return_ty.clone());
389 } 386 }
390 TyKind::Never.intern(&Interner) 387 TyKind::Never.intern(&Interner)
@@ -404,7 +401,7 @@ impl<'a> InferenceContext<'a> {
404 401
405 self.unify(&ty, &expected.ty); 402 self.unify(&ty, &expected.ty);
406 403
407 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 404 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
408 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();
409 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));
410 for field in fields.iter() { 407 for field in fields.iter() {
@@ -422,7 +419,7 @@ impl<'a> InferenceContext<'a> {
422 self.result.record_field_resolutions.insert(field.expr, field_def); 419 self.result.record_field_resolutions.insert(field.expr, field_def);
423 } 420 }
424 let field_ty = field_def.map_or(self.err_ty(), |it| { 421 let field_ty = field_def.map_or(self.err_ty(), |it| {
425 field_types[it.local_id].clone().subst(&substs) 422 field_types[it.local_id].clone().substitute(&Interner, &substs)
426 }); 423 });
427 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 424 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
428 } 425 }
@@ -453,10 +450,10 @@ impl<'a> InferenceContext<'a> {
453 }) 450 })
454 .unwrap_or(true) 451 .unwrap_or(true)
455 }; 452 };
456 match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { 453 match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) {
457 TyKind::Tuple(_, substs) => { 454 TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| {
458 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) 455 substs.interned().get(idx).map(|a| a.assert_ty_ref(&Interner)).cloned()
459 } 456 }),
460 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { 457 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
461 let local_id = self.db.struct_data(*s).variant_data.field(name)?; 458 let local_id = self.db.struct_data(*s).variant_data.field(name)?;
462 let field = FieldId { parent: (*s).into(), local_id }; 459 let field = FieldId { parent: (*s).into(), local_id };
@@ -465,7 +462,7 @@ impl<'a> InferenceContext<'a> {
465 Some( 462 Some(
466 self.db.field_types((*s).into())[field.local_id] 463 self.db.field_types((*s).into())[field.local_id]
467 .clone() 464 .clone()
468 .subst(&parameters), 465 .substitute(&Interner, &parameters),
469 ) 466 )
470 } else { 467 } else {
471 None 468 None
@@ -479,7 +476,7 @@ impl<'a> InferenceContext<'a> {
479 Some( 476 Some(
480 self.db.field_types((*u).into())[field.local_id] 477 self.db.field_types((*u).into())[field.local_id]
481 .clone() 478 .clone()
482 .subst(&parameters), 479 .substitute(&Interner, &parameters),
483 ) 480 )
484 } else { 481 } else {
485 None 482 None
@@ -533,17 +530,10 @@ impl<'a> InferenceContext<'a> {
533 Expr::Box { expr } => { 530 Expr::Box { expr } => {
534 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 531 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
535 if let Some(box_) = self.resolve_boxed_box() { 532 if let Some(box_) = self.resolve_boxed_box() {
536 let mut sb = 533 TyBuilder::adt(self.db, box_)
537 Substitution::build_for_generics(&generics(self.db.upcast(), box_.into())); 534 .push(inner_ty)
538 sb = sb.push(inner_ty); 535 .fill_with_defaults(self.db, || self.table.new_type_var())
539 match self.db.generic_defaults(box_.into()).get(1) { 536 .build()
540 Some(alloc_ty) if !alloc_ty.value.is_unknown() && sb.remaining() > 0 => {
541 sb = sb.push(alloc_ty.value.clone());
542 }
543 _ => (),
544 }
545 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
546 Ty::adt_ty(box_, sb.build())
547 } else { 537 } else {
548 self.err_ty() 538 self.err_ty()
549 } 539 }
@@ -571,7 +561,7 @@ impl<'a> InferenceContext<'a> {
571 None => self.err_ty(), 561 None => self.err_ty(),
572 }, 562 },
573 UnaryOp::Neg => { 563 UnaryOp::Neg => {
574 match inner_ty.interned(&Interner) { 564 match inner_ty.kind(&Interner) {
575 // Fast path for builtins 565 // Fast path for builtins
576 TyKind::Scalar(Scalar::Int(_)) 566 TyKind::Scalar(Scalar::Int(_))
577 | TyKind::Scalar(Scalar::Uint(_)) 567 | TyKind::Scalar(Scalar::Uint(_))
@@ -584,7 +574,7 @@ impl<'a> InferenceContext<'a> {
584 } 574 }
585 } 575 }
586 UnaryOp::Not => { 576 UnaryOp::Not => {
587 match inner_ty.interned(&Interner) { 577 match inner_ty.kind(&Interner) {
588 // Fast path for builtins 578 // Fast path for builtins
589 TyKind::Scalar(Scalar::Bool) 579 TyKind::Scalar(Scalar::Bool)
590 | TyKind::Scalar(Scalar::Int(_)) 580 | TyKind::Scalar(Scalar::Int(_))
@@ -633,31 +623,31 @@ impl<'a> InferenceContext<'a> {
633 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 623 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
634 match (range_type, lhs_ty, rhs_ty) { 624 match (range_type, lhs_ty, rhs_ty) {
635 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 625 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
636 Some(adt) => Ty::adt_ty(adt, Substitution::empty()), 626 Some(adt) => TyBuilder::adt(self.db, adt).build(),
637 None => self.err_ty(), 627 None => self.err_ty(),
638 }, 628 },
639 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 629 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
640 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 630 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
641 None => self.err_ty(), 631 None => self.err_ty(),
642 }, 632 },
643 (RangeOp::Inclusive, None, Some(ty)) => { 633 (RangeOp::Inclusive, None, Some(ty)) => {
644 match self.resolve_range_to_inclusive() { 634 match self.resolve_range_to_inclusive() {
645 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 635 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
646 None => self.err_ty(), 636 None => self.err_ty(),
647 } 637 }
648 } 638 }
649 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 639 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
650 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 640 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
651 None => self.err_ty(), 641 None => self.err_ty(),
652 }, 642 },
653 (RangeOp::Inclusive, Some(_), Some(ty)) => { 643 (RangeOp::Inclusive, Some(_), Some(ty)) => {
654 match self.resolve_range_inclusive() { 644 match self.resolve_range_inclusive() {
655 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 645 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
656 None => self.err_ty(), 646 None => self.err_ty(),
657 } 647 }
658 } 648 }
659 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 649 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
660 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 650 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
661 None => self.err_ty(), 651 None => self.err_ty(),
662 }, 652 },
663 (RangeOp::Inclusive, _, None) => self.err_ty(), 653 (RangeOp::Inclusive, _, None) => self.err_ty(),
@@ -690,10 +680,10 @@ impl<'a> InferenceContext<'a> {
690 } 680 }
691 } 681 }
692 Expr::Tuple { exprs } => { 682 Expr::Tuple { exprs } => {
693 let mut tys = match expected.ty.interned(&Interner) { 683 let mut tys = match expected.ty.kind(&Interner) {
694 TyKind::Tuple(_, substs) => substs 684 TyKind::Tuple(_, substs) => substs
695 .iter() 685 .iter(&Interner)
696 .cloned() 686 .map(|a| a.assert_ty_ref(&Interner).clone())
697 .chain(repeat_with(|| self.table.new_type_var())) 687 .chain(repeat_with(|| self.table.new_type_var()))
698 .take(exprs.len()) 688 .take(exprs.len())
699 .collect::<Vec<_>>(), 689 .collect::<Vec<_>>(),
@@ -704,10 +694,10 @@ impl<'a> InferenceContext<'a> {
704 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 694 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
705 } 695 }
706 696
707 TyKind::Tuple(tys.len(), Substitution(tys.into())).intern(&Interner) 697 TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner)
708 } 698 }
709 Expr::Array(array) => { 699 Expr::Array(array) => {
710 let elem_ty = match expected.ty.interned(&Interner) { 700 let elem_ty = match expected.ty.kind(&Interner) {
711 TyKind::Array(st) | TyKind::Slice(st) => st.clone(), 701 TyKind::Array(st) | TyKind::Slice(st) => st.clone(),
712 _ => self.table.new_type_var(), 702 _ => self.table.new_type_var(),
713 }; 703 };
@@ -822,8 +812,8 @@ impl<'a> InferenceContext<'a> {
822 // we don't even make an attempt at coercion 812 // we don't even make an attempt at coercion
823 self.table.new_maybe_never_var() 813 self.table.new_maybe_never_var()
824 } else { 814 } else {
825 self.coerce(&Ty::unit(), &expected.coercion_target()); 815 self.coerce(&TyBuilder::unit(), &expected.coercion_target());
826 Ty::unit() 816 TyBuilder::unit()
827 } 817 }
828 }; 818 };
829 ty 819 ty
@@ -859,10 +849,10 @@ impl<'a> InferenceContext<'a> {
859 self.write_method_resolution(tgt_expr, func); 849 self.write_method_resolution(tgt_expr, func);
860 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) 850 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into())))
861 } 851 }
862 None => (receiver_ty, Binders::new(0, self.err_ty()), None), 852 None => (receiver_ty, Binders::empty(&Interner, self.err_ty()), None),
863 }; 853 };
864 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); 854 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty);
865 let method_ty = method_ty.subst(&substs); 855 let method_ty = method_ty.substitute(&Interner, &substs);
866 let method_ty = self.insert_type_vars(method_ty); 856 let method_ty = self.insert_type_vars(method_ty);
867 self.register_obligations_for_call(&method_ty); 857 self.register_obligations_for_call(&method_ty);
868 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) { 858 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) {
@@ -951,18 +941,20 @@ impl<'a> InferenceContext<'a> {
951 substs.push(self.err_ty()); 941 substs.push(self.err_ty());
952 } 942 }
953 assert_eq!(substs.len(), total_len); 943 assert_eq!(substs.len(), total_len);
954 Substitution(substs.into()) 944 Substitution::from_iter(&Interner, substs)
955 } 945 }
956 946
957 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 947 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
958 if let TyKind::FnDef(fn_def, parameters) = callable_ty.interned(&Interner) { 948 if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(&Interner) {
959 let def: CallableDefId = from_chalk(self.db, *fn_def); 949 let def: CallableDefId = from_chalk(self.db, *fn_def);
960 let generic_predicates = self.db.generic_predicates(def.into()); 950 let generic_predicates = self.db.generic_predicates(def.into());
961 for predicate in generic_predicates.iter() { 951 for predicate in generic_predicates.iter() {
962 let (predicate, binders) = 952 let (predicate, binders) = predicate
963 predicate.clone().subst(parameters).into_value_and_skipped_binders(); 953 .clone()
964 always!(binders == 0); // quantified where clauses not yet handled 954 .substitute(&Interner, parameters)
965 self.obligations.push(predicate.cast(&Interner)); 955 .into_value_and_skipped_binders();
956 always!(binders.len(&Interner) == 0); // quantified where clauses not yet handled
957 self.push_obligation(predicate.cast(&Interner));
966 } 958 }
967 // add obligation for trait implementation, if this is a trait method 959 // add obligation for trait implementation, if this is a trait method
968 match def { 960 match def {
@@ -972,7 +964,7 @@ impl<'a> InferenceContext<'a> {
972 // construct a TraitRef 964 // construct a TraitRef
973 let substs = 965 let substs =
974 parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); 966 parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
975 self.obligations.push( 967 self.push_obligation(
976 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs } 968 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }
977 .cast(&Interner), 969 .cast(&Interner),
978 ); 970 );
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 474363709..252ae914a 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 {
@@ -50,7 +49,9 @@ impl<'a> InferenceContext<'a> {
50 let expected_ty = var_data 49 let expected_ty = var_data
51 .as_ref() 50 .as_ref()
52 .and_then(|d| d.field(&Name::new_tuple_field(i))) 51 .and_then(|d| d.field(&Name::new_tuple_field(i)))
53 .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs)); 52 .map_or(self.err_ty(), |field| {
53 field_tys[field].clone().substitute(&Interner, &substs)
54 });
54 let expected_ty = self.normalize_associated_types_in(expected_ty); 55 let expected_ty = self.normalize_associated_types_in(expected_ty);
55 self.infer_pat(subpat, &expected_ty, default_bm); 56 self.infer_pat(subpat, &expected_ty, default_bm);
56 } 57 }
@@ -74,7 +75,7 @@ impl<'a> InferenceContext<'a> {
74 75
75 self.unify(&ty, expected); 76 self.unify(&ty, expected);
76 77
77 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 78 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner));
78 79
79 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 80 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
80 for subpat in subpats { 81 for subpat in subpats {
@@ -84,8 +85,9 @@ impl<'a> InferenceContext<'a> {
84 self.result.record_pat_field_resolutions.insert(subpat.pat, field_def); 85 self.result.record_pat_field_resolutions.insert(subpat.pat, field_def);
85 } 86 }
86 87
87 let expected_ty = matching_field 88 let expected_ty = matching_field.map_or(self.err_ty(), |field| {
88 .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs)); 89 field_tys[field].clone().substitute(&Interner, &substs)
90 });
89 let expected_ty = self.normalize_associated_types_in(expected_ty); 91 let expected_ty = self.normalize_associated_types_in(expected_ty);
90 self.infer_pat(subpat.pat, &expected_ty, default_bm); 92 self.infer_pat(subpat.pat, &expected_ty, default_bm);
91 } 93 }
@@ -124,7 +126,7 @@ impl<'a> InferenceContext<'a> {
124 let ty = match &body[pat] { 126 let ty = match &body[pat] {
125 &Pat::Tuple { ref args, ellipsis } => { 127 &Pat::Tuple { ref args, ellipsis } => {
126 let expectations = match expected.as_tuple() { 128 let expectations = match expected.as_tuple() {
127 Some(parameters) => &*parameters.0, 129 Some(parameters) => &*parameters.interned(),
128 _ => &[], 130 _ => &[],
129 }; 131 };
130 132
@@ -134,7 +136,8 @@ impl<'a> InferenceContext<'a> {
134 }; 136 };
135 let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); 137 let n_uncovered_patterns = expectations.len().saturating_sub(args.len());
136 let err_ty = self.err_ty(); 138 let err_ty = self.err_ty();
137 let mut expectations_iter = expectations.iter().chain(repeat(&err_ty)); 139 let mut expectations_iter =
140 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); 141 let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm);
139 142
140 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); 143 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len());
@@ -142,7 +145,8 @@ impl<'a> InferenceContext<'a> {
142 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); 145 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
143 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 146 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
144 147
145 TyKind::Tuple(inner_tys.len(), Substitution(inner_tys.into())).intern(&Interner) 148 TyKind::Tuple(inner_tys.len(), Substitution::from_iter(&Interner, inner_tys))
149 .intern(&Interner)
146 } 150 }
147 Pat::Or(ref pats) => { 151 Pat::Or(ref pats) => {
148 if let Some((first_pat, rest)) = pats.split_first() { 152 if let Some((first_pat, rest)) = pats.split_first() {
@@ -209,7 +213,7 @@ impl<'a> InferenceContext<'a> {
209 return inner_ty; 213 return inner_ty;
210 } 214 }
211 Pat::Slice { prefix, slice, suffix } => { 215 Pat::Slice { prefix, slice, suffix } => {
212 let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.interned(&Interner) { 216 let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.kind(&Interner) {
213 TyKind::Array(st) => (TyKind::Array, st.clone()), 217 TyKind::Array(st) => (TyKind::Array, st.clone()),
214 TyKind::Slice(st) => (TyKind::Slice, st.clone()), 218 TyKind::Slice(st) => (TyKind::Slice, st.clone()),
215 _ => (TyKind::Slice, self.err_ty()), 219 _ => (TyKind::Slice, self.err_ty()),
@@ -236,30 +240,20 @@ impl<'a> InferenceContext<'a> {
236 Pat::Box { inner } => match self.resolve_boxed_box() { 240 Pat::Box { inner } => match self.resolve_boxed_box() {
237 Some(box_adt) => { 241 Some(box_adt) => {
238 let (inner_ty, alloc_ty) = match expected.as_adt() { 242 let (inner_ty, alloc_ty) = match expected.as_adt() {
239 Some((adt, subst)) if adt == box_adt => { 243 Some((adt, subst)) if adt == box_adt => (
240 (subst[0].clone(), subst.get(1).cloned()) 244 subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(),
241 } 245 subst.interned().get(1).and_then(|a| a.ty(&Interner).cloned()),
246 ),
242 _ => (self.result.standard_types.unknown.clone(), None), 247 _ => (self.result.standard_types.unknown.clone(), None),
243 }; 248 };
244 249
245 let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm); 250 let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm);
246 let mut sb = Substitution::build_for_generics(&generics( 251 let mut b = TyBuilder::adt(self.db, box_adt).push(inner_ty);
247 self.db.upcast(), 252
248 box_adt.into(), 253 if let Some(alloc_ty) = alloc_ty {
249 )); 254 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 } 255 }
262 Ty::adt_ty(box_adt, sb.build()) 256 b.fill_with_defaults(self.db, || self.table.new_type_var()).build()
263 } 257 }
264 None => self.err_ty(), 258 None => self.err_ty(),
265 }, 259 },
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index cefa38509..14f705173 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,10 +80,10 @@ 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).substitute(&Interner, &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()).substitute(&Interner, &substs);
89 return Some(ty); 87 return Some(ty);
90 } else { 88 } else {
91 // FIXME: diagnostic, invalid Self reference 89 // FIXME: diagnostic, invalid Self reference
@@ -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()[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::Error = 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::Error = ty.kind(&Interner) {
216 return None; 211 return None;
217 } 212 }
218 213
@@ -245,27 +240,22 @@ 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 =
247 self.db.impl_self_ty(impl_id).substitute(&Interner, &impl_substs);
252 self.unify(&impl_self_ty, &ty); 248 self.unify(&impl_self_ty, &ty);
253 Some(impl_substs) 249 Some(impl_substs)
254 } 250 }
255 AssocContainerId::TraitId(trait_) => { 251 AssocContainerId::TraitId(trait_) => {
256 // we're picking this method 252 // we're picking this method
257 let trait_substs = Substitution::build_for_def(self.db, trait_) 253 let trait_ref = TyBuilder::trait_ref(self.db, trait_)
258 .push(ty.clone()) 254 .push(ty.clone())
259 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 255 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
260 .build(); 256 .build();
261 self.obligations.push( 257 self.push_obligation(trait_ref.clone().cast(&Interner));
262 TraitRef { 258 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 } 259 }
270 AssocContainerId::ModuleId(_) => None, 260 AssocContainerId::ModuleId(_) => None,
271 }; 261 };
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 6e7b0f5a6..c90a16720 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) {
@@ -108,19 +108,22 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
108} 108}
109 109
110impl<T> Canonicalized<T> { 110impl<T> Canonicalized<T> {
111 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { 111 pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty {
112 ty.walk_mut_binders( 112 ty.fold_binders(
113 &mut |ty, binders| { 113 &mut |ty, binders| {
114 if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { 114 if let TyKind::BoundVar(bound) = ty.kind(&Interner) {
115 if bound.debruijn >= binders { 115 if bound.debruijn >= binders {
116 let (v, k) = self.free_vars[bound.index]; 116 let (v, k) = self.free_vars[bound.index];
117 *ty = TyKind::InferenceVar(v, k).intern(&Interner); 117 TyKind::InferenceVar(v, k).intern(&Interner)
118 } else {
119 ty
118 } 120 }
121 } else {
122 ty
119 } 123 }
120 }, 124 },
121 DebruijnIndex::INNERMOST, 125 DebruijnIndex::INNERMOST,
122 ); 126 )
123 ty
124 } 127 }
125 128
126 pub(super) fn apply_solution( 129 pub(super) fn apply_solution(
@@ -129,29 +132,28 @@ impl<T> Canonicalized<T> {
129 solution: Canonical<Substitution>, 132 solution: Canonical<Substitution>,
130 ) { 133 ) {
131 // the solution may contain new variables, which we need to convert to new inference vars 134 // the solution may contain new variables, which we need to convert to new inference vars
132 let new_vars = Substitution( 135 let new_vars = Substitution::from_iter(
133 solution 136 &Interner,
134 .binders 137 solution.binders.iter(&Interner).map(|k| match k.kind {
135 .iter(&Interner) 138 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(),
136 .map(|k| match k.kind { 139 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(),
137 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(), 140 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(),
138 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(), 141 // HACK: Chalk can sometimes return new lifetime variables. We
139 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(), 142 // want to just skip them, but to not mess up the indices of
140 // HACK: Chalk can sometimes return new lifetime variables. We 143 // 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 144 // their place instead. This should not matter (we never see the
142 // other variables, we'll just create a new type variable in 145 // actual *uses* of the lifetime variable).
143 // their place instead. This should not matter (we never see the 146 VariableKind::Lifetime => ctx.table.new_type_var(),
144 // actual *uses* of the lifetime variable). 147 _ => panic!("const variable in solution"),
145 VariableKind::Lifetime => ctx.table.new_type_var(), 148 }),
146 _ => panic!("const variable in solution"),
147 })
148 .collect(),
149 ); 149 );
150 for (i, ty) in solution.value.into_iter().enumerate() { 150 for (i, ty) in solution.value.iter(&Interner).enumerate() {
151 let (v, k) = self.free_vars[i]; 151 let (v, k) = self.free_vars[i];
152 // eagerly replace projections in the type; we may be getting types 152 // eagerly replace projections in the type; we may be getting types
153 // e.g. from where clauses where this hasn't happened yet 153 // 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)); 154 let ty = ctx.normalize_associated_types_in(
155 new_vars.apply(ty.assert_ty_ref(&Interner).clone(), &Interner),
156 );
155 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); 157 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty);
156 } 158 }
157 } 159 }
@@ -163,22 +165,23 @@ pub fn could_unify(t1: &Ty, t2: &Ty) -> bool {
163 165
164pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { 166pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
165 let mut table = InferenceTable::new(); 167 let mut table = InferenceTable::new();
166 let vars = Substitution( 168 let vars = Substitution::from_iter(
169 &Interner,
167 tys.binders 170 tys.binders
168 .iter(&Interner) 171 .iter(&Interner)
169 // we always use type vars here because we want everything to 172 // we always use type vars here because we want everything to
170 // fallback to Unknown in the end (kind of hacky, as below) 173 // fallback to Unknown in the end (kind of hacky, as below)
171 .map(|_| table.new_type_var()) 174 .map(|_| table.new_type_var()),
172 .collect(),
173 ); 175 );
174 let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars); 176 let ty1_with_vars = vars.apply(tys.value.0.clone(), &Interner);
175 let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars); 177 let ty2_with_vars = vars.apply(tys.value.1.clone(), &Interner);
176 if !table.unify(&ty1_with_vars, &ty2_with_vars) { 178 if !table.unify(&ty1_with_vars, &ty2_with_vars) {
177 return None; 179 return None;
178 } 180 }
179 // default any type vars that weren't unified back to their original bound vars 181 // default any type vars that weren't unified back to their original bound vars
180 // (kind of hacky) 182 // (kind of hacky)
181 for (i, var) in vars.iter().enumerate() { 183 for (i, var) in vars.iter(&Interner).enumerate() {
184 let var = var.assert_ty_ref(&Interner);
182 if &*table.resolve_ty_shallow(var) == var { 185 if &*table.resolve_ty_shallow(var) == var {
183 table.unify( 186 table.unify(
184 var, 187 var,
@@ -186,11 +189,11 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
186 ); 189 );
187 } 190 }
188 } 191 }
189 Some( 192 Some(Substitution::from_iter(
190 Substitution::builder(tys.binders.len(&Interner)) 193 &Interner,
191 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) 194 vars.iter(&Interner)
192 .build(), 195 .map(|v| table.resolve_ty_completely(v.assert_ty_ref(&Interner).clone())),
193 ) 196 ))
194} 197}
195 198
196#[derive(Clone, Debug)] 199#[derive(Clone, Debug)]
@@ -214,7 +217,7 @@ impl TypeVariableTable {
214 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { 217 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
215 match kind { 218 match kind {
216 _ if self.inner[iv.to_inner().0 as usize].diverging => TyKind::Never, 219 _ if self.inner[iv.to_inner().0 as usize].diverging => TyKind::Never,
217 TyVariableKind::General => TyKind::Unknown, 220 TyVariableKind::General => TyKind::Error,
218 TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)), 221 TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)),
219 TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)), 222 TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)),
220 } 223 }
@@ -231,6 +234,7 @@ pub(crate) struct TypeVariableData {
231pub(crate) struct InferenceTable { 234pub(crate) struct InferenceTable {
232 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>, 235 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>,
233 pub(super) type_variable_table: TypeVariableTable, 236 pub(super) type_variable_table: TypeVariableTable,
237 pub(super) revision: u32,
234} 238}
235 239
236impl InferenceTable { 240impl InferenceTable {
@@ -238,6 +242,7 @@ impl InferenceTable {
238 InferenceTable { 242 InferenceTable {
239 var_unification_table: InPlaceUnificationTable::new(), 243 var_unification_table: InPlaceUnificationTable::new(),
240 type_variable_table: TypeVariableTable { inner: Vec::new() }, 244 type_variable_table: TypeVariableTable { inner: Vec::new() },
245 revision: 0,
241 } 246 }
242 } 247 }
243 248
@@ -282,7 +287,9 @@ impl InferenceTable {
282 substs2: &Substitution, 287 substs2: &Substitution,
283 depth: usize, 288 depth: usize,
284 ) -> bool { 289 ) -> bool {
285 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) 290 substs1.iter(&Interner).zip(substs2.iter(&Interner)).all(|(t1, t2)| {
291 self.unify_inner(t1.assert_ty_ref(&Interner), t2.assert_ty_ref(&Interner), depth)
292 })
286 } 293 }
287 294
288 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 295 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
@@ -297,7 +304,7 @@ impl InferenceTable {
297 let ty1 = self.resolve_ty_shallow(ty1); 304 let ty1 = self.resolve_ty_shallow(ty1);
298 let ty2 = self.resolve_ty_shallow(ty2); 305 let ty2 = self.resolve_ty_shallow(ty2);
299 if ty1.equals_ctor(&ty2) { 306 if ty1.equals_ctor(&ty2) {
300 match (ty1.interned(&Interner), ty2.interned(&Interner)) { 307 match (ty1.kind(&Interner), ty2.kind(&Interner)) {
301 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) 308 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2))
302 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) 309 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2))
303 | ( 310 | (
@@ -322,8 +329,8 @@ impl InferenceTable {
322 } 329 }
323 330
324 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 331 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
325 match (ty1.interned(&Interner), ty2.interned(&Interner)) { 332 match (ty1.kind(&Interner), ty2.kind(&Interner)) {
326 (TyKind::Unknown, _) | (_, TyKind::Unknown) => true, 333 (TyKind::Error, _) | (_, TyKind::Error) => true,
327 334
328 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, 335 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true,
329 336
@@ -360,7 +367,10 @@ impl InferenceTable {
360 == self.type_variable_table.is_diverging(*tv2) => 367 == self.type_variable_table.is_diverging(*tv2) =>
361 { 368 {
362 // both type vars are unknown since we tried to resolve them 369 // both type vars are unknown since we tried to resolve them
363 self.var_unification_table.union(tv1.to_inner(), tv2.to_inner()); 370 if !self.var_unification_table.unioned(tv1.to_inner(), tv2.to_inner()) {
371 self.var_unification_table.union(tv1.to_inner(), tv2.to_inner());
372 self.revision += 1;
373 }
364 true 374 true
365 } 375 }
366 376
@@ -398,6 +408,7 @@ impl InferenceTable {
398 tv.to_inner(), 408 tv.to_inner(),
399 TypeVarValue::Known(other.clone().intern(&Interner)), 409 TypeVarValue::Known(other.clone().intern(&Interner)),
400 ); 410 );
411 self.revision += 1;
401 true 412 true
402 } 413 }
403 414
@@ -447,7 +458,7 @@ impl InferenceTable {
447 if i > 0 { 458 if i > 0 {
448 cov_mark::hit!(type_var_resolves_to_int_var); 459 cov_mark::hit!(type_var_resolves_to_int_var);
449 } 460 }
450 match ty.interned(&Interner) { 461 match ty.kind(&Interner) {
451 TyKind::InferenceVar(tv, _) => { 462 TyKind::InferenceVar(tv, _) => {
452 let inner = tv.to_inner(); 463 let inner = tv.to_inner();
453 match self.var_unification_table.inlined_probe_value(inner).known() { 464 match self.var_unification_table.inlined_probe_value(inner).known() {
@@ -470,7 +481,7 @@ impl InferenceTable {
470 /// be resolved as far as possible, i.e. contain no type variables with 481 /// be resolved as far as possible, i.e. contain no type variables with
471 /// known type. 482 /// known type.
472 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 483 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
473 ty.fold(&mut |ty| match ty.interned(&Interner) { 484 ty.fold(&mut |ty| match ty.kind(&Interner) {
474 &TyKind::InferenceVar(tv, kind) => { 485 &TyKind::InferenceVar(tv, kind) => {
475 let inner = tv.to_inner(); 486 let inner = tv.to_inner();
476 if tv_stack.contains(&inner) { 487 if tv_stack.contains(&inner) {
@@ -497,7 +508,7 @@ impl InferenceTable {
497 /// Resolves the type completely; type variables without known type are 508 /// Resolves the type completely; type variables without known type are
498 /// replaced by TyKind::Unknown. 509 /// replaced by TyKind::Unknown.
499 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 510 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
500 ty.fold(&mut |ty| match ty.interned(&Interner) { 511 ty.fold(&mut |ty| match ty.kind(&Interner) {
501 &TyKind::InferenceVar(tv, kind) => { 512 &TyKind::InferenceVar(tv, kind) => {
502 let inner = tv.to_inner(); 513 let inner = tv.to_inner();
503 if tv_stack.contains(&inner) { 514 if tv_stack.contains(&inner) {
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 6f9c698e6..daf379ef8 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -14,6 +14,10 @@ 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;
19mod walk;
20mod types;
17 21
18pub mod display; 22pub mod display;
19pub mod db; 23pub mod db;
@@ -24,29 +28,30 @@ mod tests;
24#[cfg(test)] 28#[cfg(test)]
25mod test_db; 29mod test_db;
26 30
27use std::{iter, mem, ops::Deref, sync::Arc}; 31use std::sync::Arc;
28 32
29use base_db::salsa;
30use hir_def::{
31 builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId,
32 GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId,
33};
34use itertools::Itertools; 33use itertools::Itertools;
35use smallvec::SmallVec; 34use smallvec::SmallVec;
36 35
37use crate::{ 36use base_db::salsa;
38 db::HirDatabase, 37use hir_def::{
39 display::HirDisplay, 38 expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId, GenericDefId, HasModule, Lookup,
40 utils::{generics, make_mut_slice, Generics}, 39 TraitId, TypeAliasId, TypeParamId,
41}; 40};
42 41
42use crate::{db::HirDatabase, display::HirDisplay, utils::generics};
43
43pub use autoderef::autoderef; 44pub use autoderef::autoderef;
45pub use builder::TyBuilder;
46pub use chalk_ext::TyExt;
44pub use infer::{could_unify, InferenceResult, InferenceVar}; 47pub use infer::{could_unify, InferenceResult, InferenceVar};
45pub use lower::{ 48pub use lower::{
46 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, 49 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
47 TyDefId, TyLoweringContext, ValueTyDefId, 50 TyDefId, TyLoweringContext, ValueTyDefId,
48}; 51};
49pub use traits::{AliasEq, DomainGoal, InEnvironment, TraitEnvironment}; 52pub use traits::TraitEnvironment;
53pub use types::*;
54pub use walk::TypeWalk;
50 55
51pub use chalk_ir::{ 56pub use chalk_ir::{
52 cast::Cast, AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind, 57 cast::Cast, AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind,
@@ -61,45 +66,12 @@ pub type ClosureId = chalk_ir::ClosureId<Interner>;
61pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; 66pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
62pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; 67pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
63 68
69pub type VariableKind = chalk_ir::VariableKind<Interner>;
70pub type VariableKinds = chalk_ir::VariableKinds<Interner>;
64pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; 71pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;
65 72
66pub type ChalkTraitId = chalk_ir::TraitId<Interner>; 73pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
67 74
68#[derive(Clone, PartialEq, Eq, Debug, Hash)]
69pub enum Lifetime {
70 Parameter(LifetimeParamId),
71 Static,
72}
73
74#[derive(Clone, PartialEq, Eq, Debug, Hash)]
75pub struct OpaqueTy {
76 pub opaque_ty_id: OpaqueTyId,
77 pub substitution: Substitution,
78}
79
80impl TypeWalk for OpaqueTy {
81 fn walk(&self, f: &mut impl FnMut(&Ty)) {
82 self.substitution.walk(f);
83 }
84
85 fn walk_mut_binders(
86 &mut self,
87 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
88 binders: DebruijnIndex,
89 ) {
90 self.substitution.walk_mut_binders(f, binders);
91 }
92}
93
94/// A "projection" type corresponds to an (unnormalized)
95/// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
96/// trait and all its parameters are fully known.
97#[derive(Clone, PartialEq, Eq, Debug, Hash)]
98pub struct ProjectionTy {
99 pub associated_ty_id: AssocTypeId,
100 pub substitution: Substitution,
101}
102
103impl ProjectionTy { 75impl ProjectionTy {
104 pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef { 76 pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
105 TraitRef { 77 TraitRef {
@@ -108,8 +80,8 @@ impl ProjectionTy {
108 } 80 }
109 } 81 }
110 82
111 pub fn self_type_parameter(&self) -> &Ty { 83 pub fn self_type_parameter(&self, interner: &Interner) -> &Ty {
112 &self.substitution[0] 84 &self.substitution.interned()[0].assert_ty_ref(interner)
113 } 85 }
114 86
115 fn trait_(&self, db: &dyn HirDatabase) -> TraitId { 87 fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
@@ -120,312 +92,26 @@ impl ProjectionTy {
120 } 92 }
121} 93}
122 94
123impl TypeWalk for ProjectionTy {
124 fn walk(&self, f: &mut impl FnMut(&Ty)) {
125 self.substitution.walk(f);
126 }
127
128 fn walk_mut_binders(
129 &mut self,
130 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
131 binders: DebruijnIndex,
132 ) {
133 self.substitution.walk_mut_binders(f, binders);
134 }
135}
136
137#[derive(Clone, PartialEq, Eq, Debug, Hash)]
138pub struct DynTy {
139 /// The unknown self type.
140 pub bounds: Binders<QuantifiedWhereClauses>,
141}
142
143pub type FnSig = chalk_ir::FnSig<Interner>; 95pub type FnSig = chalk_ir::FnSig<Interner>;
144 96
145#[derive(Clone, PartialEq, Eq, Debug, Hash)]
146pub struct FnPointer {
147 pub num_args: usize,
148 pub sig: FnSig,
149 pub substs: Substitution,
150}
151
152#[derive(Clone, PartialEq, Eq, Debug, Hash)]
153pub enum AliasTy {
154 /// A "projection" type corresponds to an (unnormalized)
155 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
156 /// trait and all its parameters are fully known.
157 Projection(ProjectionTy),
158 /// An opaque type (`impl Trait`).
159 ///
160 /// This is currently only used for return type impl trait; each instance of
161 /// `impl Trait` in a return type gets its own ID.
162 Opaque(OpaqueTy),
163}
164
165impl TypeWalk for AliasTy {
166 fn walk(&self, f: &mut impl FnMut(&Ty)) {
167 match self {
168 AliasTy::Projection(it) => it.walk(f),
169 AliasTy::Opaque(it) => it.walk(f),
170 }
171 }
172
173 fn walk_mut_binders(
174 &mut self,
175 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
176 binders: DebruijnIndex,
177 ) {
178 match self {
179 AliasTy::Projection(it) => it.walk_mut_binders(f, binders),
180 AliasTy::Opaque(it) => it.walk_mut_binders(f, binders),
181 }
182 }
183}
184/// A type.
185///
186/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
187/// the same thing (but in a different way).
188///
189/// This should be cheap to clone.
190#[derive(Clone, PartialEq, Eq, Debug, Hash)]
191pub enum TyKind {
192 /// Structures, enumerations and unions.
193 Adt(AdtId<Interner>, Substitution),
194
195 /// Represents an associated item like `Iterator::Item`. This is used
196 /// when we have tried to normalize a projection like `T::Item` but
197 /// couldn't find a better representation. In that case, we generate
198 /// an **application type** like `(Iterator::Item)<T>`.
199 AssociatedType(AssocTypeId, Substitution),
200
201 /// a scalar type like `bool` or `u32`
202 Scalar(Scalar),
203
204 /// A tuple type. For example, `(i32, bool)`.
205 Tuple(usize, Substitution),
206
207 /// An array with the given length. Written as `[T; n]`.
208 Array(Ty),
209
210 /// The pointee of an array slice. Written as `[T]`.
211 Slice(Ty),
212
213 /// A raw pointer. Written as `*mut T` or `*const T`
214 Raw(Mutability, Ty),
215
216 /// A reference; a pointer with an associated lifetime. Written as
217 /// `&'a mut T` or `&'a T`.
218 Ref(Mutability, Ty),
219
220 /// This represents a placeholder for an opaque type in situations where we
221 /// don't know the hidden type (i.e. currently almost always). This is
222 /// analogous to the `AssociatedType` type constructor.
223 /// It is also used as the type of async block, with one type parameter
224 /// representing the Future::Output type.
225 OpaqueType(OpaqueTyId, Substitution),
226
227 /// The anonymous type of a function declaration/definition. Each
228 /// function has a unique type, which is output (for a function
229 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
230 ///
231 /// This includes tuple struct / enum variant constructors as well.
232 ///
233 /// For example the type of `bar` here:
234 ///
235 /// ```
236 /// fn foo() -> i32 { 1 }
237 /// let bar = foo; // bar: fn() -> i32 {foo}
238 /// ```
239 FnDef(FnDefId, Substitution),
240
241 /// The pointee of a string slice. Written as `str`.
242 Str,
243
244 /// The never type `!`.
245 Never,
246
247 /// The type of a specific closure.
248 ///
249 /// The closure signature is stored in a `FnPtr` type in the first type
250 /// parameter.
251 Closure(ClosureId, Substitution),
252
253 /// Represents a foreign type declared in external blocks.
254 ForeignType(ForeignDefId),
255
256 /// A pointer to a function. Written as `fn() -> i32`.
257 ///
258 /// For example the type of `bar` here:
259 ///
260 /// ```
261 /// fn foo() -> i32 { 1 }
262 /// let bar: fn() -> i32 = foo;
263 /// ```
264 Function(FnPointer),
265
266 /// An "alias" type represents some form of type alias, such as:
267 /// - An associated type projection like `<T as Iterator>::Item`
268 /// - `impl Trait` types
269 /// - Named type aliases like `type Foo<X> = Vec<X>`
270 Alias(AliasTy),
271
272 /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T)
273 /// {}` when we're type-checking the body of that function. In this
274 /// situation, we know this stands for *some* type, but don't know the exact
275 /// type.
276 Placeholder(PlaceholderIndex),
277
278 /// A bound type variable. This is used in various places: when representing
279 /// some polymorphic type like the type of function `fn f<T>`, the type
280 /// parameters get turned into variables; during trait resolution, inference
281 /// variables get turned into bound variables and back; and in `Dyn` the
282 /// `Self` type is represented with a bound variable as well.
283 BoundVar(BoundVar),
284
285 /// A type variable used during type checking.
286 InferenceVar(InferenceVar, TyVariableKind),
287
288 /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust).
289 ///
290 /// The predicates are quantified over the `Self` type, i.e. `Ty::Bound(0)`
291 /// represents the `Self` type inside the bounds. This is currently
292 /// implicit; Chalk has the `Binders` struct to make it explicit, but it
293 /// didn't seem worth the overhead yet.
294 Dyn(DynTy),
295
296 /// A placeholder for a type which could not be computed; this is propagated
297 /// to avoid useless error messages. Doubles as a placeholder where type
298 /// variables are inserted before type checking, since we want to try to
299 /// infer a better type here anyway -- for the IDE use case, we want to try
300 /// to infer as much as possible even in the presence of type errors.
301 Unknown,
302}
303
304#[derive(Clone, PartialEq, Eq, Debug, Hash)]
305pub struct Ty(Arc<TyKind>);
306
307impl TyKind {
308 pub fn intern(self, _interner: &Interner) -> Ty {
309 Ty(Arc::new(self))
310 }
311}
312
313impl Ty {
314 pub fn interned(&self, _interner: &Interner) -> &TyKind {
315 &self.0
316 }
317
318 pub fn interned_mut(&mut self) -> &mut TyKind {
319 Arc::make_mut(&mut self.0)
320 }
321
322 pub fn into_inner(self) -> TyKind {
323 Arc::try_unwrap(self.0).unwrap_or_else(|a| (*a).clone())
324 }
325}
326
327/// A list of substitutions for generic parameters.
328#[derive(Clone, PartialEq, Eq, Debug, Hash)]
329pub struct Substitution(SmallVec<[Ty; 2]>);
330
331impl TypeWalk for Substitution {
332 fn walk(&self, f: &mut impl FnMut(&Ty)) {
333 for t in self.0.iter() {
334 t.walk(f);
335 }
336 }
337
338 fn walk_mut_binders(
339 &mut self,
340 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
341 binders: DebruijnIndex,
342 ) {
343 for t in &mut self.0 {
344 t.walk_mut_binders(f, binders);
345 }
346 }
347}
348
349impl Substitution { 97impl Substitution {
350 pub fn interned(&self, _: &Interner) -> &[Ty] {
351 &self.0
352 }
353
354 pub fn empty() -> Substitution {
355 Substitution(SmallVec::new())
356 }
357
358 pub fn single(ty: Ty) -> Substitution { 98 pub fn single(ty: Ty) -> Substitution {
359 Substitution({ 99 Substitution::intern({
360 let mut v = SmallVec::new(); 100 let mut v = SmallVec::new();
361 v.push(ty); 101 v.push(ty.cast(&Interner));
362 v 102 v
363 }) 103 })
364 } 104 }
365 105
366 pub fn prefix(&self, n: usize) -> Substitution { 106 pub fn prefix(&self, n: usize) -> Substitution {
367 Substitution(self.0[..std::cmp::min(self.0.len(), n)].into()) 107 Substitution::intern(self.interned()[..std::cmp::min(self.len(&Interner), n)].into())
368 } 108 }
369 109
370 pub fn suffix(&self, n: usize) -> Substitution { 110 pub fn suffix(&self, n: usize) -> Substitution {
371 Substitution(self.0[self.0.len() - std::cmp::min(self.0.len(), n)..].into()) 111 Substitution::intern(
372 } 112 self.interned()[self.len(&Interner) - std::cmp::min(self.len(&Interner), n)..].into(),
373
374 pub fn as_single(&self) -> &Ty {
375 if self.0.len() != 1 {
376 panic!("expected substs of len 1, got {:?}", self);
377 }
378 &self.0[0]
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 ) 113 )
413 } 114 }
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 }
429} 115}
430 116
431/// Return an index of a parameter in the generic type parameter list by it's id. 117/// Return an index of a parameter in the generic type parameter list by it's id.
@@ -433,137 +119,38 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> {
433 generics(db.upcast(), id.parent).param_idx(id) 119 generics(db.upcast(), id.parent).param_idx(id)
434} 120}
435 121
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)]
491pub struct Binders<T> {
492 pub num_binders: usize,
493 pub value: T,
494}
495
496impl<T> Binders<T> { 122impl<T> Binders<T> {
497 pub fn new(num_binders: usize, value: T) -> Self {
498 Self { num_binders, value }
499 }
500
501 pub fn wrap_empty(value: T) -> Self 123 pub fn wrap_empty(value: T) -> Self
502 where 124 where
503 T: TypeWalk, 125 T: TypeWalk,
504 { 126 {
505 Self { num_binders: 0, value: value.shift_bound_vars(DebruijnIndex::ONE) } 127 Binders::empty(&Interner, value.shifted_in_from(DebruijnIndex::ONE))
506 }
507
508 pub fn as_ref(&self) -> Binders<&T> {
509 Binders { num_binders: self.num_binders, value: &self.value }
510 }
511
512 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binders<U> {
513 Binders { num_binders: self.num_binders, value: f(self.value) }
514 }
515
516 pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> {
517 Some(Binders { num_binders: self.num_binders, value: f(self.value)? })
518 }
519
520 pub fn skip_binders(&self) -> &T {
521 &self.value
522 }
523
524 pub fn into_value_and_skipped_binders(self) -> (T, usize) {
525 (self.value, self.num_binders)
526 }
527}
528
529impl<T: Clone> Binders<&T> {
530 pub fn cloned(&self) -> Binders<T> {
531 Binders { num_binders: self.num_binders, value: self.value.clone() }
532 } 128 }
533} 129}
534 130
535impl<T: TypeWalk> Binders<T> { 131impl<T: TypeWalk> Binders<T> {
536 /// Substitutes all variables. 132 /// Substitutes all variables.
537 pub fn subst(self, subst: &Substitution) -> T { 133 pub fn substitute(self, interner: &Interner, subst: &Substitution) -> T {
538 assert_eq!(subst.len(), self.num_binders); 134 let (value, binders) = self.into_value_and_skipped_binders();
539 self.value.subst_bound_vars(subst) 135 assert_eq!(subst.len(interner), binders.len(interner));
540 } 136 value.subst_bound_vars(subst)
541}
542
543impl<T: TypeWalk> TypeWalk for Binders<T> {
544 fn walk(&self, f: &mut impl FnMut(&Ty)) {
545 self.value.walk(f);
546