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.rs105
-rw-r--r--crates/hir_ty/src/builder.rs223
-rw-r--r--crates/hir_ty/src/chalk_cast.rs53
-rw-r--r--crates/hir_ty/src/chalk_db.rs (renamed from crates/hir_ty/src/traits/chalk.rs)276
-rw-r--r--crates/hir_ty/src/chalk_ext.rs305
-rw-r--r--crates/hir_ty/src/db.rs87
-rw-r--r--crates/hir_ty/src/diagnostics.rs2
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs174
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs24
-rw-r--r--crates/hir_ty/src/diagnostics/match_check.rs49
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs12
-rw-r--r--crates/hir_ty/src/display.rs321
-rw-r--r--crates/hir_ty/src/infer.rs198
-rw-r--r--crates/hir_ty/src/infer/coerce.rs64
-rw-r--r--crates/hir_ty/src/infer/expr.rs221
-rw-r--r--crates/hir_ty/src/infer/pat.rs92
-rw-r--r--crates/hir_ty/src/infer/path.rs39
-rw-r--r--crates/hir_ty/src/infer/unify.rs266
-rw-r--r--crates/hir_ty/src/interner.rs (renamed from crates/hir_ty/src/traits/chalk/interner.rs)170
-rw-r--r--crates/hir_ty/src/lib.rs1347
-rw-r--r--crates/hir_ty/src/lower.rs340
-rw-r--r--crates/hir_ty/src/mapping.rs154
-rw-r--r--crates/hir_ty/src/method_resolution.rs316
-rw-r--r--crates/hir_ty/src/op.rs74
-rw-r--r--crates/hir_ty/src/primitive.rs5
-rw-r--r--crates/hir_ty/src/tests.rs2
-rw-r--r--crates/hir_ty/src/tests/macros.rs28
-rw-r--r--crates/hir_ty/src/tests/method_resolution.rs22
-rw-r--r--crates/hir_ty/src/tests/patterns.rs28
-rw-r--r--crates/hir_ty/src/tests/regression.rs38
-rw-r--r--crates/hir_ty/src/tests/simple.rs51
-rw-r--r--crates/hir_ty/src/tests/traits.rs1504
-rw-r--r--crates/hir_ty/src/tls.rs (renamed from crates/hir_ty/src/traits/chalk/tls.rs)14
-rw-r--r--crates/hir_ty/src/traits.rs140
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs560
-rw-r--r--crates/hir_ty/src/utils.rs73
-rw-r--r--crates/hir_ty/src/walk.rs150
37 files changed, 3676 insertions, 3851 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index dc5fc759a..2c07494a9 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -6,18 +6,15 @@
6use std::iter::successors; 6use std::iter::successors;
7 7
8use base_db::CrateId; 8use base_db::CrateId;
9use chalk_ir::cast::Cast; 9use chalk_ir::{cast::Cast, fold::Fold, interner::HasInterner, VariableKind};
10use hir_def::lang_item::LangItemTarget; 10use hir_def::lang_item::LangItemTarget;
11use hir_expand::name::name; 11use hir_expand::name::name;
12use log::{info, warn}; 12use log::{info, warn};
13 13
14use crate::{ 14use crate::{
15 db::HirDatabase, 15 db::HirDatabase, static_lifetime, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds,
16 to_assoc_type_id, to_chalk_trait_id, 16 DebruijnIndex, InEnvironment, Interner, ProjectionTyExt, Solution, Substitution, Ty, TyBuilder,
17 traits::{InEnvironment, Solution}, 17 TyKind,
18 utils::generics,
19 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner,
20 ProjectionTy, Substitution, TraitRef, Ty, TyKind,
21}; 18};
22 19
23const AUTODEREF_RECURSION_LIMIT: usize = 10; 20const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -39,39 +36,48 @@ pub(crate) fn deref(
39 krate: CrateId, 36 krate: CrateId,
40 ty: InEnvironment<&Canonical<Ty>>, 37 ty: InEnvironment<&Canonical<Ty>>,
41) -> Option<Canonical<Ty>> { 38) -> Option<Canonical<Ty>> {
42 if let Some(derefed) = ty.goal.value.builtin_deref() { 39 let _p = profile::span("deref");
40 if let Some(derefed) = builtin_deref(&ty.goal.value) {
43 Some(Canonical { value: derefed, binders: ty.goal.binders.clone() }) 41 Some(Canonical { value: derefed, binders: ty.goal.binders.clone() })
44 } else { 42 } else {
45 deref_by_trait(db, krate, ty) 43 deref_by_trait(db, krate, ty)
46 } 44 }
47} 45}
48 46
47fn builtin_deref(ty: &Ty) -> Option<Ty> {
48 match ty.kind(&Interner) {
49 TyKind::Ref(.., ty) => Some(ty.clone()),
50 TyKind::Raw(.., ty) => Some(ty.clone()),
51 _ => None,
52 }
53}
54
49fn deref_by_trait( 55fn deref_by_trait(
50 db: &dyn HirDatabase, 56 db: &dyn HirDatabase,
51 krate: CrateId, 57 krate: CrateId,
52 ty: InEnvironment<&Canonical<Ty>>, 58 ty: InEnvironment<&Canonical<Ty>>,
53) -> Option<Canonical<Ty>> { 59) -> Option<Canonical<Ty>> {
60 let _p = profile::span("deref_by_trait");
54 let deref_trait = match db.lang_item(krate, "deref".into())? { 61 let deref_trait = match db.lang_item(krate, "deref".into())? {
55 LangItemTarget::TraitId(it) => it, 62 LangItemTarget::TraitId(it) => it,
56 _ => return None, 63 _ => return None,
57 }; 64 };
58 let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?; 65 let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?;
59 66
60 let generic_params = generics(db.upcast(), target.into()); 67 let projection = {
61 if generic_params.len() != 1 { 68 let b = TyBuilder::assoc_type_projection(db, target);
62 // the Target type + Deref trait should only have one generic parameter, 69 if b.remaining() != 1 {
63 // namely Deref's Self type 70 // the Target type + Deref trait should only have one generic parameter,
64 return None; 71 // namely Deref's Self type
65 } 72 return None;
73 }
74 b.push(ty.goal.value.clone()).build()
75 };
66 76
67 // FIXME make the Canonical / bound var handling nicer 77 // FIXME make the Canonical / bound var handling nicer
68 78
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 79 // Check that the type implements Deref at all
73 let trait_ref = 80 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 { 81 let implements_goal = Canonical {
76 binders: ty.goal.binders.clone(), 82 binders: ty.goal.binders.clone(),
77 value: InEnvironment { 83 value: InEnvironment {
@@ -84,11 +90,8 @@ fn deref_by_trait(
84 } 90 }
85 91
86 // Now do the assoc type projection 92 // Now do the assoc type projection
87 let projection = AliasEq { 93 let alias_eq = AliasEq {
88 alias: AliasTy::Projection(ProjectionTy { 94 alias: AliasTy::Projection(projection),
89 associated_ty_id: to_assoc_type_id(target),
90 substitution: parameters,
91 }),
92 ty: TyKind::BoundVar(BoundVar::new( 95 ty: TyKind::BoundVar(BoundVar::new(
93 DebruijnIndex::INNERMOST, 96 DebruijnIndex::INNERMOST,
94 ty.goal.binders.len(&Interner), 97 ty.goal.binders.len(&Interner),
@@ -96,16 +99,14 @@ fn deref_by_trait(
96 .intern(&Interner), 99 .intern(&Interner),
97 }; 100 };
98 101
99 let obligation = projection.cast(&Interner); 102 let in_env = InEnvironment { goal: alias_eq.cast(&Interner), environment: ty.environment };
100
101 let in_env = InEnvironment { goal: obligation, environment: ty.environment };
102 103
103 let canonical = Canonical { 104 let canonical = Canonical {
104 value: in_env, 105 value: in_env,
105 binders: CanonicalVarKinds::from_iter( 106 binders: CanonicalVarKinds::from_iter(
106 &Interner, 107 &Interner,
107 ty.goal.binders.iter(&Interner).cloned().chain(Some(chalk_ir::WithKind::new( 108 ty.goal.binders.iter(&Interner).cloned().chain(Some(chalk_ir::WithKind::new(
108 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), 109 VariableKind::Ty(chalk_ir::TyVariableKind::General),
109 chalk_ir::UniverseIndex::ROOT, 110 chalk_ir::UniverseIndex::ROOT,
110 ))), 111 ))),
111 ), 112 ),
@@ -130,18 +131,25 @@ fn deref_by_trait(
130 // assumptions will be broken. We would need to properly introduce 131 // assumptions will be broken. We would need to properly introduce
131 // new variables in that case 132 // new variables in that case
132 133
133 for i in 1..vars.0.binders.len(&Interner) { 134 for i in 1..vars.binders.len(&Interner) {
134 if vars.0.value[i - 1].interned(&Interner) 135 if vars.value.subst.at(&Interner, i - 1).assert_ty_ref(&Interner).kind(&Interner)
135 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 136 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
136 { 137 {
137 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution); 138 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
138 return None; 139 return None;
139 } 140 }
140 } 141 }
141 Some(Canonical { 142 // FIXME: we remove lifetime variables here since they can confuse
142 value: vars.0.value[vars.0.value.len() - 1].clone(), 143 // the method resolution code later
143 binders: vars.0.binders.clone(), 144 Some(fixup_lifetime_variables(Canonical {
144 }) 145 value: vars
146 .value
147 .subst
148 .at(&Interner, vars.value.subst.len(&Interner) - 1)
149 .assert_ty_ref(&Interner)
150 .clone(),
151 binders: vars.binders.clone(),
152 }))
145 } 153 }
146 Solution::Ambig(_) => { 154 Solution::Ambig(_) => {
147 info!("Ambiguous solution for derefing {:?}: {:?}", ty.goal, solution); 155 info!("Ambiguous solution for derefing {:?}: {:?}", ty.goal, solution);
@@ -149,3 +157,32 @@ fn deref_by_trait(
149 } 157 }
150 } 158 }
151} 159}
160
161fn fixup_lifetime_variables<T: Fold<Interner, Result = T> + HasInterner<Interner = Interner>>(
162 c: Canonical<T>,
163) -> Canonical<T> {
164 // Removes lifetime variables from the Canonical, replacing them by static lifetimes.
165 let mut i = 0;
166 let subst = Substitution::from_iter(
167 &Interner,
168 c.binders.iter(&Interner).map(|vk| match vk.kind {
169 VariableKind::Ty(_) => {
170 let index = i;
171 i += 1;
172 BoundVar::new(DebruijnIndex::INNERMOST, index).to_ty(&Interner).cast(&Interner)
173 }
174 VariableKind::Lifetime => static_lifetime().cast(&Interner),
175 VariableKind::Const(_) => unimplemented!(),
176 }),
177 );
178 let binders = CanonicalVarKinds::from_iter(
179 &Interner,
180 c.binders.iter(&Interner).filter(|vk| match vk.kind {
181 VariableKind::Ty(_) => true,
182 VariableKind::Lifetime => false,
183 VariableKind::Const(_) => true,
184 }),
185 );
186 let value = subst.apply(c.value, &Interner);
187 Canonical { binders, value }
188}
diff --git a/crates/hir_ty/src/builder.rs b/crates/hir_ty/src/builder.rs
new file mode 100644
index 000000000..e25ef866d
--- /dev/null
+++ b/crates/hir_ty/src/builder.rs
@@ -0,0 +1,223 @@
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 fold::Fold,
8 interner::HasInterner,
9 AdtId, BoundVar, DebruijnIndex, Safety, Scalar,
10};
11use hir_def::{builtin_type::BuiltinType, GenericDefId, TraitId, TypeAliasId};
12use smallvec::SmallVec;
13
14use crate::{
15 db::HirDatabase, primitive, to_assoc_type_id, to_chalk_trait_id, utils::generics, Binders,
16 CallableSig, FnPointer, FnSig, FnSubst, GenericArg, Interner, ProjectionTy, Substitution,
17 TraitRef, Ty, TyDefId, TyExt, TyKind, ValueTyDefId,
18};
19
20/// This is a builder for `Ty` or anything that needs a `Substitution`.
21pub struct TyBuilder<D> {
22 /// The `data` field is used to keep track of what we're building (e.g. an
23 /// ADT, a `TraitRef`, ...).
24 data: D,
25 vec: SmallVec<[GenericArg; 2]>,
26 param_count: usize,
27}
28
29impl<D> TyBuilder<D> {
30 fn new(data: D, param_count: usize) -> TyBuilder<D> {
31 TyBuilder { data, param_count, vec: SmallVec::with_capacity(param_count) }
32 }
33
34 fn build_internal(self) -> (D, Substitution) {
35 assert_eq!(self.vec.len(), self.param_count);
36 let subst = Substitution::from_iter(&Interner, 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_binders: 0,
82 sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs },
83 substitution: FnSubst(Substitution::from_iter(
84 &Interner,
85 sig.params_and_return.iter().cloned(),
86 )),
87 })
88 .intern(&Interner)
89 }
90
91 pub fn builtin(builtin: BuiltinType) -> Ty {
92 match builtin {
93 BuiltinType::Char => TyKind::Scalar(Scalar::Char).intern(&Interner),
94 BuiltinType::Bool => TyKind::Scalar(Scalar::Bool).intern(&Interner),
95 BuiltinType::Str => TyKind::Str.intern(&Interner),
96 BuiltinType::Int(t) => {
97 TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))).intern(&Interner)
98 }
99 BuiltinType::Uint(t) => {
100 TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))).intern(&Interner)
101 }
102 BuiltinType::Float(t) => {
103 TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))).intern(&Interner)
104 }
105 }
106 }
107
108 pub fn type_params_subst(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substitution {
109 let params = generics(db.upcast(), def.into());
110 params.type_params_subst(db)
111 }
112
113 pub fn subst_for_def(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> TyBuilder<()> {
114 let def = def.into();
115 let params = generics(db.upcast(), def);
116 let param_count = params.len();
117 TyBuilder::new((), param_count)
118 }
119
120 pub fn build(self) -> Substitution {
121 let ((), subst) = self.build_internal();
122 subst
123 }
124}
125
126impl TyBuilder<hir_def::AdtId> {
127 pub fn adt(db: &dyn HirDatabase, adt: hir_def::AdtId) -> TyBuilder<hir_def::AdtId> {
128 let generics = generics(db.upcast(), adt.into());
129 let param_count = generics.len();
130 TyBuilder::new(adt, param_count)
131 }
132
133 pub fn fill_with_defaults(
134 mut self,
135 db: &dyn HirDatabase,
136 mut fallback: impl FnMut() -> Ty,
137 ) -> Self {
138 let defaults = db.generic_defaults(self.data.into());
139 for default_ty in defaults.iter().skip(self.vec.len()) {
140 if default_ty.skip_binders().is_unknown() {
141 self.vec.push(fallback().cast(&Interner));
142 } else {
143 // each default can depend on the previous parameters
144 let subst_so_far = Substitution::from_iter(&Interner, self.vec.clone());
145 self.vec
146 .push(default_ty.clone().substitute(&Interner, &subst_so_far).cast(&Interner));
147 }
148 }
149 self
150 }
151
152 pub fn build(self) -> Ty {
153 let (adt, subst) = self.build_internal();
154 TyKind::Adt(AdtId(adt), subst).intern(&Interner)
155 }
156}
157
158pub struct Tuple(usize);
159impl TyBuilder<Tuple> {
160 pub fn tuple(size: usize) -> TyBuilder<Tuple> {
161 TyBuilder::new(Tuple(size), size)
162 }
163
164 pub fn build(self) -> Ty {
165 let (Tuple(size), subst) = self.build_internal();
166 TyKind::Tuple(size, subst).intern(&Interner)
167 }
168}
169
170impl TyBuilder<TraitId> {
171 pub fn trait_ref(db: &dyn HirDatabase, trait_id: TraitId) -> TyBuilder<TraitId> {
172 let generics = generics(db.upcast(), trait_id.into());
173 let param_count = generics.len();
174 TyBuilder::new(trait_id, param_count)
175 }
176
177 pub fn build(self) -> TraitRef {
178 let (trait_id, substitution) = self.build_internal();
179 TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution }
180 }
181}
182
183impl TyBuilder<TypeAliasId> {
184 pub fn assoc_type_projection(
185 db: &dyn HirDatabase,
186 type_alias: TypeAliasId,
187 ) -> TyBuilder<TypeAliasId> {
188 let generics = generics(db.upcast(), type_alias.into());
189 let param_count = generics.len();
190 TyBuilder::new(type_alias, param_count)
191 }
192
193 pub fn build(self) -> ProjectionTy {
194 let (type_alias, substitution) = self.build_internal();
195 ProjectionTy { associated_ty_id: to_assoc_type_id(type_alias), substitution }
196 }
197}
198
199impl<T: HasInterner<Interner = Interner> + Fold<Interner>> TyBuilder<Binders<T>> {
200 fn subst_binders(b: Binders<T>) -> Self {
201 let param_count = b.binders.len(&Interner);
202 TyBuilder::new(b, param_count)
203 }
204
205 pub fn build(self) -> <T as Fold<Interner>>::Result {
206 let (b, subst) = self.build_internal();
207 b.substitute(&Interner, &subst)
208 }
209}
210
211impl TyBuilder<Binders<Ty>> {
212 pub fn def_ty(db: &dyn HirDatabase, def: TyDefId) -> TyBuilder<Binders<Ty>> {
213 TyBuilder::subst_binders(db.ty(def.into()))
214 }
215
216 pub fn impl_self_ty(db: &dyn HirDatabase, def: hir_def::ImplId) -> TyBuilder<Binders<Ty>> {
217 TyBuilder::subst_binders(db.impl_self_ty(def))
218 }
219
220 pub fn value_ty(db: &dyn HirDatabase, def: ValueTyDefId) -> TyBuilder<Binders<Ty>> {
221 TyBuilder::subst_binders(db.value_ty(def))
222 }
223}
diff --git a/crates/hir_ty/src/chalk_cast.rs b/crates/hir_ty/src/chalk_cast.rs
deleted file mode 100644
index bf884ae15..000000000
--- a/crates/hir_ty/src/chalk_cast.rs
+++ /dev/null
@@ -1,53 +0,0 @@
1//! Implementations of the Chalk `Cast` trait for our types.
2
3use chalk_ir::{
4 cast::{Cast, CastTo},
5 interner::HasInterner,
6};
7
8use crate::{AliasEq, DomainGoal, Interner, TraitRef, WhereClause};
9
10macro_rules! has_interner {
11 ($t:ty) => {
12 impl HasInterner for $t {
13 type Interner = crate::Interner;
14 }
15 };
16}
17
18has_interner!(WhereClause);
19has_interner!(DomainGoal);
20
21impl CastTo<WhereClause> for TraitRef {
22 fn cast_to(self, _interner: &Interner) -> WhereClause {
23 WhereClause::Implemented(self)
24 }
25}
26
27impl CastTo<WhereClause> for AliasEq {
28 fn cast_to(self, _interner: &Interner) -> WhereClause {
29 WhereClause::AliasEq(self)
30 }
31}
32
33impl CastTo<DomainGoal> for WhereClause {
34 fn cast_to(self, _interner: &Interner) -> DomainGoal {
35 DomainGoal::Holds(self)
36 }
37}
38
39macro_rules! transitive_impl {
40 ($a:ty, $b:ty, $c:ty) => {
41 impl CastTo<$c> for $a {
42 fn cast_to(self, interner: &Interner) -> $c {
43 self.cast::<$b>(interner).cast(interner)
44 }
45 }
46 };
47}
48
49// In Chalk, these can be done as blanket impls, but that doesn't work here
50// because of coherence
51
52transitive_impl!(TraitRef, WhereClause, DomainGoal);
53transitive_impl!(AliasEq, WhereClause, DomainGoal);
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/chalk_db.rs
index 011bef6f6..8f054d06b 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/chalk_db.rs
@@ -1,52 +1,47 @@
1//! Conversion code from/to Chalk. 1//! The implementation of `RustIrDatabase` for Chalk, which provides information
2//! about the code that Chalk needs.
2use std::sync::Arc; 3use std::sync::Arc;
3 4
4use log::debug; 5use log::debug;
5 6
6use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg}; 7use chalk_ir::{cast::Cast, fold::shift::Shift, CanonicalVarKinds};
7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; 8use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
8 9
9use base_db::{salsa::InternKey, CrateId}; 10use base_db::CrateId;
10use hir_def::{ 11use hir_def::{
11 lang_item::{lang_attr, LangItemTarget}, 12 lang_item::{lang_attr, LangItemTarget},
12 AssocContainerId, AssocItemId, HasModule, Lookup, TypeAliasId, 13 AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId,
13}; 14};
14use hir_expand::name::name; 15use hir_expand::name::name;
15 16
16use super::ChalkContext;
17use crate::{ 17use crate::{
18 db::HirDatabase, 18 db::HirDatabase,
19 display::HirDisplay, 19 display::HirDisplay,
20 from_assoc_type_id, 20 from_assoc_type_id, from_chalk_trait_id, make_only_type_binders,
21 mapping::{from_chalk, ToChalk, TypeAliasAsValue},
21 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, 22 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
22 to_assoc_type_id, to_chalk_trait_id, 23 to_assoc_type_id, to_chalk_trait_id,
24 traits::ChalkContext,
23 utils::generics, 25 utils::generics,
24 AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, ProjectionTy, Substitution, 26 AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, Interner, ProjectionTy,
25 TraitRef, Ty, TyKind, WhereClause, 27 ProjectionTyExt, QuantifiedWhereClause, Substitution, TraitRef, TraitRefExt, Ty, TyBuilder,
28 TyExt, TyKind, WhereClause,
26}; 29};
27use mapping::{
28 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
29};
30
31pub use self::interner::Interner;
32pub(crate) use self::interner::*;
33 30
34pub(super) mod tls; 31pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>;
35mod interner; 32pub(crate) type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>;
36mod mapping; 33pub(crate) type StructDatum = chalk_solve::rust_ir::AdtDatum<Interner>;
37 34pub(crate) type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>;
38pub(crate) trait ToChalk { 35pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>;
39 type Chalk; 36
40 fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk; 37pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
41 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self; 38pub(crate) type TraitId = chalk_ir::TraitId<Interner>;
42} 39pub(crate) type AdtId = chalk_ir::AdtId<Interner>;
43 40pub(crate) type ImplId = chalk_ir::ImplId<Interner>;
44pub(crate) fn from_chalk<T, ChalkT>(db: &dyn HirDatabase, chalk: ChalkT) -> T 41pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>;
45where 42pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>;
46 T: ToChalk<Chalk = ChalkT>, 43pub(crate) type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>;
47{ 44pub(crate) type Variances = chalk_ir::Variances<Interner>;
48 T::from_chalk(db, chalk)
49}
50 45
51impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { 46impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
52 fn associated_ty_data(&self, id: AssocTypeId) -> Arc<AssociatedTyDatum> { 47 fn associated_ty_data(&self, id: AssocTypeId) -> Arc<AssociatedTyDatum> {
@@ -80,19 +75,19 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
80 fn impls_for_trait( 75 fn impls_for_trait(
81 &self, 76 &self,
82 trait_id: TraitId, 77 trait_id: TraitId,
83 parameters: &[GenericArg<Interner>], 78 parameters: &[chalk_ir::GenericArg<Interner>],
84 binders: &CanonicalVarKinds<Interner>, 79 binders: &CanonicalVarKinds<Interner>,
85 ) -> Vec<ImplId> { 80 ) -> Vec<ImplId> {
86 debug!("impls_for_trait {:?}", trait_id); 81 debug!("impls_for_trait {:?}", trait_id);
87 let trait_: hir_def::TraitId = from_chalk(self.db, trait_id); 82 let trait_: hir_def::TraitId = from_chalk_trait_id(trait_id);
88 83
89 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone()); 84 let ty: Ty = parameters[0].assert_ty_ref(&Interner).clone();
90 85
91 fn binder_kind( 86 fn binder_kind(
92 ty: &Ty, 87 ty: &Ty,
93 binders: &CanonicalVarKinds<Interner>, 88 binders: &CanonicalVarKinds<Interner>,
94 ) -> Option<chalk_ir::TyVariableKind> { 89 ) -> Option<chalk_ir::TyVariableKind> {
95 if let TyKind::BoundVar(bv) = ty.interned(&Interner) { 90 if let TyKind::BoundVar(bv) = ty.kind(&Interner) {
96 let binders = binders.as_slice(&Interner); 91 let binders = binders.as_slice(&Interner);
97 if bv.debruijn == DebruijnIndex::INNERMOST { 92 if bv.debruijn == DebruijnIndex::INNERMOST {
98 if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind { 93 if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind {
@@ -103,7 +98,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
103 None 98 None
104 } 99 }
105 100
106 let self_ty_fp = TyFingerprint::for_impl(&ty); 101 let self_ty_fp = TyFingerprint::for_trait_impl(&ty);
107 let fps: &[TyFingerprint] = match binder_kind(&ty, binders) { 102 let fps: &[TyFingerprint] = match binder_kind(&ty, binders) {
108 Some(chalk_ir::TyVariableKind::Integer) => &ALL_INT_FPS, 103 Some(chalk_ir::TyVariableKind::Integer) => &ALL_INT_FPS,
109 Some(chalk_ir::TyVariableKind::Float) => &ALL_FLOAT_FPS, 104 Some(chalk_ir::TyVariableKind::Float) => &ALL_FLOAT_FPS,
@@ -166,7 +161,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
166 Some(LangItemTarget::TraitId(trait_)) => trait_, 161 Some(LangItemTarget::TraitId(trait_)) => trait_,
167 _ => return None, 162 _ => return None,
168 }; 163 };
169 Some(trait_.to_chalk(self.db)) 164 Some(to_chalk_trait_id(trait_))
170 } 165 }
171 166
172 fn program_clauses_for_env( 167 fn program_clauses_for_env(
@@ -184,16 +179,16 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
184 .db 179 .db
185 .return_type_impl_traits(func) 180 .return_type_impl_traits(func)
186 .expect("impl trait id without impl traits"); 181 .expect("impl trait id without impl traits");
187 let data = &datas.value.impl_traits[idx as usize]; 182 let (datas, binders) = (*datas).as_ref().into_value_and_skipped_binders();
183 let data = &datas.impl_traits[idx as usize];
188 let bound = OpaqueTyDatumBound { 184 let bound = OpaqueTyDatumBound {
189 bounds: make_binders( 185 bounds: make_only_type_binders(
190 data.bounds.value.iter().cloned().map(|b| b.to_chalk(self.db)).collect(),
191 1, 186 1,
187 data.bounds.skip_binders().iter().cloned().collect(),
192 ), 188 ),
193 where_clauses: make_binders(vec![], 0), 189 where_clauses: make_only_type_binders(0, vec![]),
194 }; 190 };
195 let num_vars = datas.num_binders; 191 chalk_ir::Binders::new(binders, bound)
196 make_binders(bound, num_vars)
197 } 192 }
198 crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => { 193 crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => {
199 if let Some((future_trait, future_output)) = self 194 if let Some((future_trait, future_output)) = self
@@ -215,7 +210,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
215 let impl_bound = WhereClause::Implemented(TraitRef { 210 let impl_bound = WhereClause::Implemented(TraitRef {
216 trait_id: to_chalk_trait_id(future_trait), 211 trait_id: to_chalk_trait_id(future_trait),
217 // Self type as the first parameter. 212 // Self type as the first parameter.
218 substitution: Substitution::single( 213 substitution: Substitution::from1(
214 &Interner,
219 TyKind::BoundVar(BoundVar { 215 TyKind::BoundVar(BoundVar {
220 debruijn: DebruijnIndex::INNERMOST, 216 debruijn: DebruijnIndex::INNERMOST,
221 index: 0, 217 index: 0,
@@ -227,7 +223,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
227 alias: AliasTy::Projection(ProjectionTy { 223 alias: AliasTy::Projection(ProjectionTy {
228 associated_ty_id: to_assoc_type_id(future_output), 224 associated_ty_id: to_assoc_type_id(future_output),
229 // Self type as the first parameter. 225 // Self type as the first parameter.
230 substitution: Substitution::single( 226 substitution: Substitution::from1(
227 &Interner,
231 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) 228 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
232 .intern(&Interner), 229 .intern(&Interner),
233 ), 230 ),
@@ -237,25 +234,25 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
237 .intern(&Interner), 234 .intern(&Interner),
238 }); 235 });
239 let bound = OpaqueTyDatumBound { 236 let bound = OpaqueTyDatumBound {
240 bounds: make_binders( 237 bounds: make_only_type_binders(
238 1,
241 vec![ 239 vec![
242 wrap_in_empty_binders(impl_bound).to_chalk(self.db), 240 crate::wrap_empty_binders(impl_bound),
243 wrap_in_empty_binders(proj_bound).to_chalk(self.db), 241 crate::wrap_empty_binders(proj_bound),
244 ], 242 ],
245 1,
246 ), 243 ),
247 where_clauses: make_binders(vec![], 0), 244 where_clauses: make_only_type_binders(0, vec![]),
248 }; 245 };
249 // The opaque type has 1 parameter. 246 // The opaque type has 1 parameter.
250 make_binders(bound, 1) 247 make_only_type_binders(1, bound)
251 } else { 248 } else {
252 // If failed to find Symbol’s value as variable is void: Future::Output, return empty bounds as fallback. 249 // If failed to find Symbol’s value as variable is void: Future::Output, return empty bounds as fallback.
253 let bound = OpaqueTyDatumBound { 250 let bound = OpaqueTyDatumBound {
254 bounds: make_binders(vec![], 0), 251 bounds: make_only_type_binders(0, vec![]),
255 where_clauses: make_binders(vec![], 0), 252 where_clauses: make_only_type_binders(0, vec![]),
256 }; 253 };
257 // The opaque type has 1 parameter. 254 // The opaque type has 1 parameter.
258 make_binders(bound, 1) 255 make_only_type_binders(1, bound)
259 } 256 }
260 } 257 }
261 }; 258 };
@@ -265,7 +262,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
265 262
266 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> { 263 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> {
267 // FIXME: actually provide the hidden type; it is relevant for auto traits 264 // FIXME: actually provide the hidden type; it is relevant for auto traits
268 TyKind::Unknown.intern(&Interner).to_chalk(self.db) 265 TyKind::Error.intern(&Interner)
269 } 266 }
270 267
271 fn is_object_safe(&self, _trait_id: chalk_ir::TraitId<Interner>) -> bool { 268 fn is_object_safe(&self, _trait_id: chalk_ir::TraitId<Interner>) -> bool {
@@ -286,33 +283,32 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
286 _closure_id: chalk_ir::ClosureId<Interner>, 283 _closure_id: chalk_ir::ClosureId<Interner>,
287 substs: &chalk_ir::Substitution<Interner>, 284 substs: &chalk_ir::Substitution<Interner>,
288 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { 285 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
289 let sig_ty: Ty = 286 let sig_ty = substs.at(&Interner, 0).assert_ty_ref(&Interner).clone();
290 from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone());
291 let sig = &sig_ty.callable_sig(self.db).expect("first closure param should be fn ptr"); 287 let sig = &sig_ty.callable_sig(self.db).expect("first closure param should be fn ptr");
292 let io = rust_ir::FnDefInputsAndOutputDatum { 288 let io = rust_ir::FnDefInputsAndOutputDatum {
293 argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(), 289 argument_types: sig.params().iter().cloned().collect(),
294 return_type: sig.ret().clone().to_chalk(self.db), 290 return_type: sig.ret().clone(),
295 }; 291 };
296 make_binders(io.shifted_in(&Interner), 0) 292 make_only_type_binders(0, io.shifted_in(&Interner))
297 } 293 }
298 fn closure_upvars( 294 fn closure_upvars(
299 &self, 295 &self,
300 _closure_id: chalk_ir::ClosureId<Interner>, 296 _closure_id: chalk_ir::ClosureId<Interner>,
301 _substs: &chalk_ir::Substitution<Interner>, 297 _substs: &chalk_ir::Substitution<Interner>,
302 ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> { 298 ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> {
303 let ty = Ty::unit().to_chalk(self.db); 299 let ty = TyBuilder::unit();
304 make_binders(ty, 0) 300 make_only_type_binders(0, ty)
305 } 301 }
306 fn closure_fn_substitution( 302 fn closure_fn_substitution(
307 &self, 303 &self,
308 _closure_id: chalk_ir::ClosureId<Interner>, 304 _closure_id: chalk_ir::ClosureId<Interner>,
309 _substs: &chalk_ir::Substitution<Interner>, 305 _substs: &chalk_ir::Substitution<Interner>,
310 ) -> chalk_ir::Substitution<Interner> { 306 ) -> chalk_ir::Substitution<Interner> {
311 Substitution::empty().to_chalk(self.db) 307 Substitution::empty(&Interner)
312 } 308 }
313 309
314 fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String { 310 fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String {
315 let id = from_chalk(self.db, trait_id); 311 let id = from_chalk_trait_id(trait_id);
316 self.db.trait_data(id).name.to_string() 312 self.db.trait_data(id).name.to_string()
317 } 313 }
318 fn adt_name(&self, chalk_ir::AdtId(adt_id): AdtId) -> String { 314 fn adt_name(&self, chalk_ir::AdtId(adt_id): AdtId) -> String {
@@ -387,7 +383,7 @@ pub(crate) fn associated_ty_data_query(
387 // Lower bounds -- we could/should maybe move this to a separate query in `lower` 383 // Lower bounds -- we could/should maybe move this to a separate query in `lower`
388 let type_alias_data = db.type_alias_data(type_alias); 384 let type_alias_data = db.type_alias_data(type_alias);
389 let generic_params = generics(db.upcast(), type_alias.into()); 385 let generic_params = generics(db.upcast(), type_alias.into());
390 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 386 let bound_vars = generic_params.bound_vars_subst(DebruijnIndex::INNERMOST);
391 let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast()); 387 let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast());
392 let ctx = crate::TyLoweringContext::new(db, &resolver) 388 let ctx = crate::TyLoweringContext::new(db, &resolver)
393 .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable); 389 .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable);
@@ -403,10 +399,10 @@ pub(crate) fn associated_ty_data_query(
403 let where_clauses = convert_where_clauses(db, type_alias.into(), &bound_vars); 399 let where_clauses = convert_where_clauses(db, type_alias.into(), &bound_vars);
404 let bound_data = rust_ir::AssociatedTyDatumBound { bounds, where_clauses }; 400 let bound_data = rust_ir::AssociatedTyDatumBound { bounds, where_clauses };
405 let datum = AssociatedTyDatum { 401 let datum = AssociatedTyDatum {
406 trait_id: trait_.to_chalk(db), 402 trait_id: to_chalk_trait_id(trait_),
407 id, 403 id,
408 name: type_alias, 404 name: type_alias,
409 binders: make_binders(bound_data, generic_params.len()), 405 binders: make_only_type_binders(generic_params.len(), bound_data),
410 }; 406 };
411 Arc::new(datum) 407 Arc::new(datum)
412} 408}
@@ -417,11 +413,11 @@ pub(crate) fn trait_datum_query(
417 trait_id: TraitId, 413 trait_id: TraitId,
418) -> Arc<TraitDatum> { 414) -> Arc<TraitDatum> {
419 debug!("trait_datum {:?}", trait_id); 415 debug!("trait_datum {:?}", trait_id);
420 let trait_: hir_def::TraitId = from_chalk(db, trait_id); 416 let trait_ = from_chalk_trait_id(trait_id);
421 let trait_data = db.trait_data(trait_); 417 let trait_data = db.trait_data(trait_);
422 debug!("trait {:?} = {:?}", trait_id, trait_data.name); 418 debug!("trait {:?} = {:?}", trait_id, trait_data.name);
423 let generic_params = generics(db.upcast(), trait_.into()); 419 let generic_params = generics(db.upcast(), trait_.into());
424 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 420 let bound_vars = generic_params.bound_vars_subst(DebruijnIndex::INNERMOST);
425 let flags = rust_ir::TraitFlags { 421 let flags = rust_ir::TraitFlags {
426 auto: trait_data.is_auto, 422 auto: trait_data.is_auto,
427 upstream: trait_.lookup(db.upcast()).container.krate() != krate, 423 upstream: trait_.lookup(db.upcast()).container.krate() != krate,
@@ -439,7 +435,7 @@ pub(crate) fn trait_datum_query(
439 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name)); 435 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name));
440 let trait_datum = TraitDatum { 436 let trait_datum = TraitDatum {
441 id: trait_id, 437 id: trait_id,
442 binders: make_binders(trait_datum_bound, bound_vars.len()), 438 binders: make_only_type_binders(bound_vars.len(&Interner), trait_datum_bound),
443 flags, 439 flags,
444 associated_ty_ids, 440 associated_ty_ids,
445 well_known, 441 well_known,
@@ -490,7 +486,7 @@ pub(crate) fn struct_datum_query(
490 let upstream = adt_id.module(db.upcast()).krate() != krate; 486 let upstream = adt_id.module(db.upcast()).krate() != krate;
491 let where_clauses = { 487 let where_clauses = {
492 let generic_params = generics(db.upcast(), adt_id.into()); 488 let generic_params = generics(db.upcast(), adt_id.into());
493 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 489 let bound_vars = generic_params.bound_vars_subst(DebruijnIndex::INNERMOST);
494 convert_where_clauses(db, adt_id.into(), &bound_vars) 490 convert_where_clauses(db, adt_id.into(), &bound_vars)
495 }; 491 };
496 let flags = rust_ir::AdtFlags { 492 let flags = rust_ir::AdtFlags {
@@ -508,7 +504,7 @@ pub(crate) fn struct_datum_query(
508 // FIXME set ADT kind 504 // FIXME set ADT kind
509 kind: rust_ir::AdtKind::Struct, 505 kind: rust_ir::AdtKind::Struct,
510 id: struct_id, 506 id: struct_id,
511 binders: make_binders(struct_datum_bound, num_params), 507 binders: make_only_type_binders(num_params, struct_datum_bound),
512 flags, 508 flags,
513 }; 509 };
514 Arc::new(struct_datum) 510 Arc::new(struct_datum)
@@ -535,11 +531,12 @@ fn impl_def_datum(
535 .impl_trait(impl_id) 531 .impl_trait(impl_id)
536 // ImplIds for impls where the trait ref can't be resolved should never reach Chalk 532 // ImplIds for impls where the trait ref can't be resolved should never reach Chalk
537 .expect("invalid impl passed to Chalk") 533 .expect("invalid impl passed to Chalk")
538 .value; 534 .into_value_and_skipped_binders()
535 .0;
539 let impl_data = db.impl_data(impl_id); 536 let impl_data = db.impl_data(impl_id);
540 537
541 let generic_params = generics(db.upcast(), impl_id.into()); 538 let generic_params = generics(db.upcast(), impl_id.into());
542 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 539 let bound_vars = generic_params.bound_vars_subst(DebruijnIndex::INNERMOST);
543 let trait_ = trait_ref.hir_trait_id(); 540 let trait_ = trait_ref.hir_trait_id();
544 let impl_type = if impl_id.lookup(db.upcast()).container.krate() == krate { 541 let impl_type = if impl_id.lookup(db.upcast()).container.krate() == krate {
545 rust_ir::ImplType::Local 542 rust_ir::ImplType::Local
@@ -555,7 +552,6 @@ fn impl_def_datum(
555 trait_ref.display(db), 552 trait_ref.display(db),
556 where_clauses 553 where_clauses
557 ); 554 );
558 let trait_ref = trait_ref.to_chalk(db);
559 555
560 let polarity = if negative { rust_ir::Polarity::Negative } else { rust_ir::Polarity::Positive }; 556 let polarity = if negative { rust_ir::Polarity::Negative } else { rust_ir::Polarity::Positive };
561 557
@@ -577,7 +573,7 @@ fn impl_def_datum(
577 .collect(); 573 .collect();
578 debug!("impl_datum: {:?}", impl_datum_bound); 574 debug!("impl_datum: {:?}", impl_datum_bound);
579 let impl_datum = ImplDatum { 575 let impl_datum = ImplDatum {
580 binders: make_binders(impl_datum_bound, bound_vars.len()), 576 binders: make_only_type_binders(bound_vars.len(&Interner), impl_datum_bound),
581 impl_type, 577 impl_type,
582 polarity, 578 polarity,
583 associated_ty_value_ids, 579 associated_ty_value_ids,
@@ -605,18 +601,22 @@ fn type_alias_associated_ty_value(
605 _ => panic!("assoc ty value should be in impl"), 601 _ => panic!("assoc ty value should be in impl"),
606 }; 602 };
607 603
608 let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist").value; // we don't return any assoc ty values if the impl'd trait can't be resolved 604 let trait_ref = db
605 .impl_trait(impl_id)
606 .expect("assoc ty value should not exist")
607 .into_value_and_skipped_binders()
608 .0; // we don't return any assoc ty values if the impl'd trait can't be resolved
609 609
610 let assoc_ty = db 610 let assoc_ty = db
611 .trait_data(trait_ref.hir_trait_id()) 611 .trait_data(trait_ref.hir_trait_id())
612 .associated_type_by_name(&type_alias_data.name) 612 .associated_type_by_name(&type_alias_data.name)
613 .expect("assoc ty value should not exist"); // validated when building the impl data as well 613 .expect("assoc ty value should not exist"); // validated when building the impl data as well
614 let ty = db.ty(type_alias.into()); 614 let (ty, binders) = db.ty(type_alias.into()).into_value_and_skipped_binders();
615 let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) }; 615 let value_bound = rust_ir::AssociatedTyValueBound { ty };
616 let value = rust_ir::AssociatedTyValue { 616 let value = rust_ir::AssociatedTyValue {
617 impl_id: impl_id.to_chalk(db), 617 impl_id: impl_id.to_chalk(db),
618 associated_ty_id: to_assoc_type_id(assoc_ty), 618 associated_ty_id: to_assoc_type_id(assoc_ty),
619 value: make_binders(value_bound, ty.num_binders), 619 value: chalk_ir::Binders::new(binders, value_bound),
620 }; 620 };
621 Arc::new(value) 621 Arc::new(value)
622} 622}
@@ -628,34 +628,25 @@ pub(crate) fn fn_def_datum_query(
628) -> Arc<FnDefDatum> { 628) -> Arc<FnDefDatum> {
629 let callable_def: CallableDefId = from_chalk(db, fn_def_id); 629 let callable_def: CallableDefId = from_chalk(db, fn_def_id);
630 let generic_params = generics(db.upcast(), callable_def.into()); 630 let generic_params = generics(db.upcast(), callable_def.into());
631 let sig = db.callable_item_signature(callable_def); 631 let (sig, binders) = db.callable_item_signature(callable_def).into_value_and_skipped_binders();
632 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 632 let bound_vars = generic_params.bound_vars_subst(DebruijnIndex::INNERMOST);
633 let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars); 633 let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars);
634 let bound = rust_ir::FnDefDatumBound { 634 let bound = rust_ir::FnDefDatumBound {
635 // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway 635 // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway
636 inputs_and_output: make_binders( 636 inputs_and_output: make_only_type_binders(
637 0,
637 rust_ir::FnDefInputsAndOutputDatum { 638 rust_ir::FnDefInputsAndOutputDatum {
638 argument_types: sig 639 argument_types: sig.params().iter().cloned().collect(),
639 .value 640 return_type: sig.ret().clone(),
640 .params()
641 .iter()
642 .map(|ty| ty.clone().to_chalk(db))
643 .collect(),
644 return_type: sig.value.ret().clone().to_chalk(db),
645 } 641 }
646 .shifted_in(&Interner), 642 .shifted_in(&Interner),
647 0,
648 ), 643 ),
649 where_clauses, 644 where_clauses,
650 }; 645 };
651 let datum = FnDefDatum { 646 let datum = FnDefDatum {
652 id: fn_def_id, 647 id: fn_def_id,
653 sig: chalk_ir::FnSig { 648 sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: sig.is_varargs },
654 abi: (), 649 binders: chalk_ir::Binders::new(binders, bound),
655 safety: chalk_ir::Safety::Safe,
656 variadic: sig.value.is_varargs,
657 },
658 binders: make_binders(bound, sig.num_binders),
659 }; 650 };
660 Arc::new(datum) 651 Arc::new(datum)
661} 652}
@@ -685,42 +676,65 @@ pub(crate) fn adt_variance_query(
685 ) 676 )
686} 677}
687 678
688impl From<FnDefId> for crate::db::InternedCallableDefId { 679pub(super) fn convert_where_clauses(
689 fn from(fn_def_id: FnDefId) -> Self { 680 db: &dyn HirDatabase,
690 InternKey::from_intern_id(fn_def_id.0) 681 def: GenericDefId,
691 } 682 substs: &Substitution,
692} 683) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> {
693 684 let generic_predicates = db.generic_predicates(def);
694impl From<crate::db::InternedCallableDefId> for FnDefId { 685 let mut result = Vec::with_capacity(generic_predicates.len());
695 fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self { 686 for pred in generic_predicates.iter() {
696 chalk_ir::FnDefId(callable_def_id.as_intern_id()) 687 result.push(pred.clone().substitute(&Interner, substs));
697 } 688 }
698} 689 result
699
700impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId {
701 fn from(id: OpaqueTyId) -> Self {
702 InternKey::from_intern_id(id.0)
703 }
704}
705
706impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId {
707 fn from(id: crate::db::InternedOpaqueTyId) -> Self {
708 chalk_ir::OpaqueTyId(id.as_intern_id())
709 }
710}
711
712impl From<chalk_ir::ClosureId<Interner>> for crate::db::InternedClosureId {
713 fn from(id: chalk_ir::ClosureId<Interner>) -> Self {
714 Self::from_intern_id(id.0)
715 }
716} 690}
717 691
718impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> { 692pub(super) fn generic_predicate_to_inline_bound(
719 fn from(id: crate::db::InternedClosureId) -> Self { 693 db: &dyn HirDatabase,
720 chalk_ir::ClosureId(id.as_intern_id()) 694 pred: &QuantifiedWhereClause,
695 self_ty: &Ty,
696) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> {
697 // An InlineBound is like a GenericPredicate, except the self type is left out.
698 // We don't have a special type for this, but Chalk does.
699 let self_ty_shifted_in = self_ty.clone().shifted_in_from(&Interner, DebruijnIndex::ONE);
700 let (pred, binders) = pred.as_ref().into_value_and_skipped_binders();
701 match pred {
702 WhereClause::Implemented(trait_ref) => {
703 if trait_ref.self_type_parameter(&Interner) != self_ty_shifted_in {
704 // we can only convert predicates back to type bounds if they
705 // have the expected self type
706 return None;
707 }
708 let args_no_self = trait_ref.substitution.as_slice(&Interner)[1..]
709 .iter()
710 .map(|ty| ty.clone().cast(&Interner))
711 .collect();
712 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
713 Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound)))
714 }
715 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
716 if projection_ty.self_type_parameter(&Interner) != self_ty_shifted_in {
717 return None;
718 }
719 let trait_ = projection_ty.trait_(db);
720 let args_no_self = projection_ty.substitution.as_slice(&Interner)[1..]
721 .iter()
722 .map(|ty| ty.clone().cast(&Interner))
723 .collect();
724 let alias_eq_bound = rust_ir::AliasEqBound {
725 value: ty.clone(),
726 trait_bound: rust_ir::TraitBound {
727 trait_id: to_chalk_trait_id(trait_),
728 args_no_self,
729 },
730 associated_ty_id: projection_ty.associated_ty_id,
731 parameters: Vec::new(), // FIXME we don't support generic associated types yet
732 };
733 Some(chalk_ir::Binders::new(
734 binders,
735 rust_ir::InlineBound::AliasEqBound(alias_eq_bound),
736 ))
737 }
738 _ => None,
721 } 739 }
722} 740}
723
724fn wrap_in_empty_binders<T: crate::TypeWalk>(value: T) -> crate::Binders<T> {
725 crate::Binders::wrap_empty(value)
726}
diff --git a/crates/hir_ty/src/chalk_ext.rs b/crates/hir_ty/src/chalk_ext.rs
new file mode 100644
index 000000000..8c4542956
--- /dev/null
+++ b/crates/hir_ty/src/chalk_ext.rs
@@ -0,0 +1,305 @@
1//! Various extensions traits for Chalk types.
2
3use chalk_ir::Mutability;
4use hir_def::{
5 type_ref::Rawness, AssocContainerId, FunctionId, GenericDefId, HasModule, Lookup, TraitId,
6};
7
8use crate::{
9 db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
10 from_placeholder_idx, to_chalk_trait_id, AdtId, AliasEq, AliasTy, Binders, CallableDefId,
11 CallableSig, FnPointer, ImplTraitId, Interner, Lifetime, ProjectionTy, QuantifiedWhereClause,
12 Substitution, TraitRef, Ty, TyBuilder, TyKind, WhereClause,
13};
14
15pub trait TyExt {
16 fn is_unit(&self) -> bool;
17 fn is_never(&self) -> bool;
18 fn is_unknown(&self) -> bool;
19
20 fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)>;
21 fn as_tuple(&self) -> Option<&Substitution>;
22 fn as_fn_def(&self, db: &dyn HirDatabase) -> Option<FunctionId>;
23 fn as_reference(&self) -> Option<(&Ty, Lifetime, Mutability)>;
24 fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)>;
25 fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId>;
26
27 fn callable_def(&self, db: &dyn HirDatabase) -> Option<CallableDefId>;
28 fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig>;
29
30 fn strip_references(&self) -> &Ty;
31
32 /// If this is a `dyn Trait`, returns that trait.
33 fn dyn_trait(&self) -> Option<TraitId>;
34
35 fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>>;
36 fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId>;
37
38 /// FIXME: Get rid of this, it's not a good abstraction
39 fn equals_ctor(&self, other: &Ty) -> bool;
40}
41
42impl TyExt for Ty {
43 fn is_unit(&self) -> bool {
44 matches!(self.kind(&Interner), TyKind::Tuple(0, _))
45 }
46
47 fn is_never(&self) -> bool {
48 matches!(self.kind(&Interner), TyKind::Never)
49 }
50
51 fn is_unknown(&self) -> bool {
52 matches!(self.kind(&Interner), TyKind::Error)
53 }
54
55 fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)> {
56 match self.kind(&Interner) {
57 TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),
58 _ => None,
59 }
60 }
61
62 fn as_tuple(&self) -> Option<&Substitution> {
63 match self.kind(&Interner) {
64 TyKind::Tuple(_, substs) => Some(substs),
65 _ => None,
66 }
67 }
68
69 fn as_fn_def(&self, db: &dyn HirDatabase) -> Option<FunctionId> {
70 if let Some(CallableDefId::FunctionId(func)) = self.callable_def(db) {
71 Some(func)
72 } else {
73 None
74 }
75 }
76 fn as_reference(&self) -> Option<(&Ty, Lifetime, Mutability)> {
77 match self.kind(&Interner) {
78 TyKind::Ref(mutability, lifetime, ty) => Some((ty, lifetime.clone(), *mutability)),
79 _ => None,
80 }
81 }
82
83 fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
84 match self.kind(&Interner) {
85 TyKind::Ref(mutability, _, ty) => Some((ty, Rawness::Ref, *mutability)),
86 TyKind::Raw(mutability, ty) => Some((ty, Rawness::RawPtr, *mutability)),
87 _ => None,
88 }
89 }
90
91 fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId> {
92 match *self.kind(&Interner) {
93 TyKind::Adt(AdtId(adt), ..) => Some(adt.into()),
94 TyKind::FnDef(callable, ..) => {
95 Some(db.lookup_intern_callable_def(callable.into()).into())
96 }
97 TyKind::AssociatedType(type_alias, ..) => Some(from_assoc_type_id(type_alias).into()),
98 TyKind::Foreign(type_alias, ..) => Some(from_foreign_def_id(type_alias).into()),
99 _ => None,
100 }
101 }
102
103 fn callable_def(&self, db: &dyn HirDatabase) -> Option<CallableDefId> {
104 match self.kind(&Interner) {
105 &TyKind::FnDef(def, ..) => Some(db.lookup_intern_callable_def(def.into())),
106 _ => None,
107 }
108 }
109
110 fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
111 match self.kind(&Interner) {
112 TyKind::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
113 TyKind::FnDef(def, parameters) => {
114 let callable_def = db.lookup_intern_callable_def((*def).into());
115 let sig = db.callable_item_signature(callable_def);
116 Some(sig.substitute(&Interner, &parameters))
117 }
118 TyKind::Closure(.., substs) => {
119 let sig_param = substs.at(&Interner, 0).assert_ty_ref(&Interner);
120 sig_param.callable_sig(db)
121 }
122 _ => None,
123 }
124 }
125
126 fn dyn_trait(&self) -> Option<TraitId> {
127 let trait_ref = match self.kind(&Interner) {
128 TyKind::Dyn(dyn_ty) => dyn_ty.bounds.skip_binders().interned().get(0).and_then(|b| {
129 match b.skip_binders() {
130 WhereClause::Implemented(trait_ref) => Some(trait_ref),
131 _ => None,
132 }
133 }),
134 _ => None,
135 }?;
136 Some(from_chalk_trait_id(trait_ref.trait_id))
137 }
138
139 fn strip_references(&self) -> &Ty {
140 let mut t: &Ty = self;
141 while let TyKind::Ref(_mutability, _lifetime, ty) = t.kind(&Interner) {
142 t = ty;
143 }
144 t
145 }
146
147 fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> {
148 match self.kind(&Interner) {
149 TyKind::OpaqueType(opaque_ty_id, ..) => {
150 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
151 ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
152 let krate = def.module(db.upcast()).krate();
153 if let Some(future_trait) = db
154 .lang_item(krate, "future_trait".into())
155 .and_then(|item| item.as_trait())
156 {
157 // This is only used by type walking.
158 // Parameters will be walked outside, and projection predicate is not used.
159 // So just provide the Future trait.
160 let impl_bound = Binders::empty(
161 &Interner,
162 WhereClause::Implemented(TraitRef {
163 trait_id: to_chalk_trait_id(future_trait),
164 substitution: Substitution::empty(&Interner),
165 }),
166 );
167 Some(vec![impl_bound])
168 } else {
169 None
170 }
171 }
172 ImplTraitId::ReturnTypeImplTrait(..) => None,
173 }
174 }
175 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
176 let predicates = match db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into())
177 {
178 ImplTraitId::ReturnTypeImplTrait(func, idx) => {
179 db.return_type_impl_traits(func).map(|it| {
180 let data = (*it)
181 .as_ref()
182 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
183 data.substitute(&Interner, &opaque_ty.substitution)
184 })
185 }
186 // It always has an parameter for Future::Output type.
187 ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(),
188 };
189
190 predicates.map(|it| it.into_value_and_skipped_binders().0)
191 }
192 TyKind::Placeholder(idx) => {
193 let id = from_placeholder_idx(db, *idx);
194 let generic_params = db.generic_params(id.parent);
195 let param_data = &generic_params.types[id.local_id];
196 match param_data.provenance {
197 hir_def::generics::TypeParamProvenance::ArgumentImplTrait => {
198 let substs = TyBuilder::type_params_subst(db, id.parent);
199 let predicates = db
200 .generic_predicates(id.parent)
201 .into_iter()
202 .map(|pred| pred.clone().substitute(&Interner, &substs))
203 .filter(|wc| match &wc.skip_binders() {
204 WhereClause::Implemented(tr) => {
205 &tr.self_type_parameter(&Interner) == self
206 }
207 WhereClause::AliasEq(AliasEq {
208 alias: AliasTy::Projection(proj),
209 ty: _,
210 }) => &proj.self_type_parameter(&Interner) == self,
211 _ => false,
212 })
213 .collect::<Vec<_>>();
214
215 Some(predicates)
216 }
217 _ => None,
218 }
219 }
220 _ => None,
221 }
222 }
223
224 fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> {
225 match self.kind(&Interner) {
226 TyKind::AssociatedType(id, ..) => {
227 match from_assoc_type_id(*id).lookup(db.upcast()).container {
228 AssocContainerId::TraitId(trait_id) => Some(trait_id),
229 _ => None,
230 }
231 }
232 TyKind::Alias(AliasTy::Projection(projection_ty)) => {
233 match from_assoc_type_id(projection_ty.associated_ty_id)
234 .lookup(db.upcast())
235 .container
236 {
237 AssocContainerId::TraitId(trait_id) => Some(trait_id),
238 _ => None,
239 }
240 }
241 _ => None,
242 }
243 }
244
245 fn equals_ctor(&self, other: &Ty) -> bool {
246 match (self.kind(&Interner), other.kind(&Interner)) {
247 (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2,
248 (TyKind::Slice(_), TyKind::Slice(_)) | (TyKind::Array(_, _), TyKind::Array(_, _)) => {
249 true
250 }
251 (TyKind::FnDef(def_id, ..), TyKind::FnDef(def_id2, ..)) => def_id == def_id2,
252 (TyKind::OpaqueType(ty_id, ..), TyKind::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
253 (TyKind::AssociatedType(ty_id, ..), TyKind::AssociatedType(ty_id2, ..)) => {
254 ty_id == ty_id2
255 }
256 (TyKind::Foreign(ty_id, ..), TyKind::Foreign(ty_id2, ..)) => ty_id == ty_id2,
257 (TyKind::Closure(id1, _), TyKind::Closure(id2, _)) => id1 == id2,
258 (TyKind::Ref(mutability, ..), TyKind::Ref(mutability2, ..))
259 | (TyKind::Raw(mutability, ..), TyKind::Raw(mutability2, ..)) => {
260 mutability == mutability2
261 }
262 (
263 TyKind::Function(FnPointer { num_binders, sig, .. }),
264 TyKind::Function(FnPointer { num_binders: num_binders2, sig: sig2, .. }),
265 ) => num_binders == num_binders2 && sig == sig2,
266 (TyKind::Tuple(cardinality, _), TyKind::Tuple(cardinality2, _)) => {
267 cardinality == cardinality2
268 }
269 (TyKind::Str, TyKind::Str) | (TyKind::Never, TyKind::Never) => true,
270 (TyKind::Scalar(scalar), TyKind::Scalar(scalar2)) => scalar == scalar2,
271 _ => false,
272 }
273 }
274}
275
276pub trait ProjectionTyExt {
277 fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef;
278 fn trait_(&self, db: &dyn HirDatabase) -> TraitId;
279}
280
281impl ProjectionTyExt for ProjectionTy {
282 fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
283 TraitRef {
284 trait_id: to_chalk_trait_id(self.trait_(db)),
285 substitution: self.substitution.clone(),
286 }
287 }
288
289 fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
290 match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container {
291 AssocContainerId::TraitId(it) => it,
292 _ => panic!("projection ty without parent trait"),
293 }
294 }
295}
296
297pub trait TraitRefExt {
298 fn hir_trait_id(&self) -> TraitId;
299}
300
301impl TraitRefExt for TraitRef {
302 fn hir_trait_id(&self) -> TraitId {
303 from_chalk_trait_id(self.trait_id)
304 }
305}
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs
index 58e4247c6..cf67d4266 100644
--- a/crates/hir_ty/src/db.rs
+++ b/crates/hir_ty/src/db.rs
@@ -1,18 +1,19 @@
1//! FIXME: write short doc here 1//! The home of `HirDatabase`, which is the Salsa database containing all the
2//! type inference-related queries.
2 3
3use std::sync::Arc; 4use std::sync::Arc;
4 5
5use base_db::{impl_intern_key, salsa, CrateId, Upcast}; 6use base_db::{impl_intern_key, salsa, CrateId, Upcast};
6use hir_def::{ 7use hir_def::{
7 db::DefDatabase, expr::ExprId, ConstParamId, DefWithBodyId, FunctionId, GenericDefId, ImplId, 8 db::DefDatabase, expr::ExprId, ConstParamId, DefWithBodyId, FunctionId, GenericDefId, ImplId,
8 LocalFieldId, TypeParamId, VariantId, 9 LifetimeParamId, LocalFieldId, TypeParamId, VariantId,
9}; 10};
10use la_arena::ArenaMap; 11use la_arena::ArenaMap;
11 12
12use crate::{ 13use crate::{
14 chalk_db,
13 method_resolution::{InherentImpls, TraitImpls}, 15 method_resolution::{InherentImpls, TraitImpls},
14 traits::chalk, 16 Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, Interner, PolyFnSig,
15 Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, PolyFnSig,
16 QuantifiedWhereClause, ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId, 17 QuantifiedWhereClause, ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId,
17}; 18};
18use hir_expand::name::Name; 19use hir_expand::name::Name;
@@ -86,51 +87,68 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
86 #[salsa::interned] 87 #[salsa::interned]
87 fn intern_type_param_id(&self, param_id: TypeParamId) -> InternedTypeParamId; 88 fn intern_type_param_id(&self, param_id: TypeParamId) -> InternedTypeParamId;
88 #[salsa::interned] 89 #[salsa::interned]
90 fn intern_lifetime_param_id(&self, param_id: LifetimeParamId) -> InternedLifetimeParamId;
91 #[salsa::interned]
92 fn intern_const_param_id(&self, param_id: ConstParamId) -> InternedConstParamId;
93 #[salsa::interned]
89 fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId; 94 fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId;
90 #[salsa::interned] 95 #[salsa::interned]
91 fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> InternedClosureId; 96 fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> InternedClosureId;
92 97
93 #[salsa::invoke(chalk::associated_ty_data_query)] 98 #[salsa::invoke(chalk_db::associated_ty_data_query)]
94 fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>; 99 fn associated_ty_data(&self, id: chalk_db::AssocTypeId) -> Arc<chalk_db::AssociatedTyDatum>;
95 100
96 #[salsa::invoke(chalk::trait_datum_query)] 101 #[salsa::invoke(chalk_db::trait_datum_query)]
97 fn trait_datum(&self, krate: CrateId, trait_id: chalk::TraitId) -> Arc<chalk::TraitDatum>; 102 fn trait_datum(&self, krate: CrateId, trait_id: chalk_db::TraitId)
103 -> Arc<chalk_db::TraitDatum>;
98 104
99 #[salsa::invoke(chalk::struct_datum_query)] 105 #[salsa::invoke(chalk_db::struct_datum_query)]
100 fn struct_datum(&self, krate: CrateId, struct_id: chalk::AdtId) -> Arc<chalk::StructDatum>; 106 fn struct_datum(
107 &self,
108 krate: CrateId,
109 struct_id: chalk_db::AdtId,
110 ) -> Arc<chalk_db::StructDatum>;
101 111
102 #[salsa::invoke(crate::traits::chalk::impl_datum_query)] 112 #[salsa::invoke(chalk_db::impl_datum_query)]
103 fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc<chalk::ImplDatum>; 113 fn impl_datum(&self, krate: CrateId, impl_id: chalk_db::ImplId) -> Arc<chalk_db::ImplDatum>;
104 114
105 #[salsa::invoke(crate::traits::chalk::fn_def_datum_query)] 115 #[salsa::invoke(chalk_db::fn_def_datum_query)]
106 fn fn_def_datum(&self, krate: CrateId, fn_def_id: FnDefId) -> Arc<chalk::FnDefDatum>; 116 fn fn_def_datum(&self, krate: CrateId, fn_def_id: FnDefId) -> Arc<chalk_db::FnDefDatum>;
107 117
108 #[salsa::invoke(crate::traits::chalk::fn_def_variance_query)] 118 #[salsa::invoke(chalk_db::fn_def_variance_query)]
109 fn fn_def_variance(&self, krate: CrateId, fn_def_id: FnDefId) -> chalk::Variances; 119 fn fn_def_variance(&self, krate: CrateId, fn_def_id: FnDefId) -> chalk_db::Variances;
110 120
111 #[salsa::invoke(crate::traits::chalk::adt_variance_query)] 121 #[salsa::invoke(chalk_db::adt_variance_query)]
112 fn adt_variance(&self, krate: CrateId, adt_id: chalk::AdtId) -> chalk::Variances; 122 fn adt_variance(&self, krate: CrateId, adt_id: chalk_db::AdtId) -> chalk_db::Variances;
113 123
114 #[salsa::invoke(crate::traits::chalk::associated_ty_value_query)] 124 #[salsa::invoke(chalk_db::associated_ty_value_query)]
115 fn associated_ty_value( 125 fn associated_ty_value(
116 &self, 126 &self,
117 krate: CrateId, 127 krate: CrateId,
118 id: chalk::AssociatedTyValueId, 128 id: chalk_db::AssociatedTyValueId,
119 ) -> Arc<chalk::AssociatedTyValue>; 129 ) -> Arc<chalk_db::AssociatedTyValue>;
120 130
121 #[salsa::invoke(crate::traits::trait_solve_query)] 131 #[salsa::invoke(trait_solve_wait)]
132 #[salsa::transparent]
122 fn trait_solve( 133 fn trait_solve(
123 &self, 134 &self,
124 krate: CrateId, 135 krate: CrateId,
125 goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>, 136 goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>,
126 ) -> Option<crate::traits::Solution>; 137 ) -> Option<crate::Solution>;
127 138
128 #[salsa::invoke(crate::traits::chalk::program_clauses_for_chalk_env_query)] 139 #[salsa::invoke(crate::traits::trait_solve_query)]
140 fn trait_solve_query(
141 &self,
142 krate: CrateId,
143 goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>,
144 ) -> Option<crate::Solution>;
145
146 #[salsa::invoke(chalk_db::program_clauses_for_chalk_env_query)]
129 fn program_clauses_for_chalk_env( 147 fn program_clauses_for_chalk_env(
130 &self, 148 &self,
131 krate: CrateId, 149 krate: CrateId,
132 env: chalk_ir::Environment<chalk::Interner>, 150 env: chalk_ir::Environment<Interner>,
133 ) -> chalk_ir::ProgramClauses<chalk::Interner>; 151 ) -> chalk_ir::ProgramClauses<Interner>;
134} 152}
135 153
136fn infer_wait(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> { 154fn infer_wait(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
@@ -146,6 +164,15 @@ fn infer_wait(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult>
146 db.infer_query(def) 164 db.infer_query(def)
147} 165}
148 166
167fn trait_solve_wait(
168 db: &dyn HirDatabase,
169 krate: CrateId,
170 goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>,
171) -> Option<crate::Solution> {
172 let _p = profile::span("trait_solve::wait");
173 db.trait_solve_query(krate, goal)
174}
175
149#[test] 176#[test]
150fn hir_database_is_object_safe() { 177fn hir_database_is_object_safe() {
151 fn _assert_object_safe(_: &dyn HirDatabase) {} 178 fn _assert_object_safe(_: &dyn HirDatabase) {}
@@ -156,6 +183,14 @@ pub struct InternedTypeParamId(salsa::InternId);
156impl_intern_key!(InternedTypeParamId); 183impl_intern_key!(InternedTypeParamId);
157 184
158#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 185#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
186pub struct InternedLifetimeParamId(salsa::InternId);
187impl_intern_key!(InternedLifetimeParamId);
188
189#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
190pub struct InternedConstParamId(salsa::InternId);
191impl_intern_key!(InternedConstParamId);
192
193#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
159pub struct InternedOpaqueTyId(salsa::InternId); 194pub struct InternedOpaqueTyId(salsa::InternId);
160impl_intern_key!(InternedOpaqueTyId); 195impl_intern_key!(InternedOpaqueTyId);
161 196
diff --git a/crates/hir_ty/src/diagnostics.rs b/crates/hir_ty/src/diagnostics.rs
index 86f937e1d..84fc8ce14 100644
--- a/crates/hir_ty/src/diagnostics.rs
+++ b/crates/hir_ty/src/diagnostics.rs
@@ -1,4 +1,4 @@
1//! FIXME: write short doc here 1//! Type inference-based diagnostics.
2mod expr; 2mod expr;
3mod match_check; 3mod match_check;
4mod unsafe_check; 4mod unsafe_check;
diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs
index 33a0f4d7d..075dc4131 100644
--- a/crates/hir_ty/src/diagnostics/decl_check.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check.rs
@@ -35,6 +35,8 @@ use crate::{
35}; 35};
36 36
37mod allow { 37mod allow {
38 pub(super) const BAD_STYLE: &str = "bad_style";
39 pub(super) const NONSTANDARD_STYLE: &str = "nonstandard_style";
38 pub(super) const NON_SNAKE_CASE: &str = "non_snake_case"; 40 pub(super) const NON_SNAKE_CASE: &str = "non_snake_case";
39 pub(super) const NON_UPPER_CASE_GLOBAL: &str = "non_upper_case_globals"; 41 pub(super) const NON_UPPER_CASE_GLOBAL: &str = "non_upper_case_globals";
40 pub(super) const NON_CAMEL_CASE_TYPES: &str = "non_camel_case_types"; 42 pub(super) const NON_CAMEL_CASE_TYPES: &str = "non_camel_case_types";
@@ -83,15 +85,44 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
83 } 85 }
84 86
85 /// Checks whether not following the convention is allowed for this item. 87 /// Checks whether not following the convention is allowed for this item.
86 /// 88 fn allowed(&self, id: AttrDefId, allow_name: &str, recursing: bool) -> bool {
87 /// Currently this method doesn't check parent attributes. 89 let is_allowed = |def_id| {
88 fn allowed(&self, id: AttrDefId, allow_name: &str) -> bool { 90 let attrs = self.db.attrs(def_id);
89 self.db.attrs(id).by_key("allow").tt_values().any(|tt| tt.to_string().contains(allow_name)) 91 // don't bug the user about directly no_mangle annotated stuff, they can't do anything about it
92 (!recursing && attrs.by_key("no_mangle").exists())
93 || attrs.by_key("allow").tt_values().any(|tt| {
94 let allows = tt.to_string();
95 allows.contains(allow_name)
96 || allows.contains(allow::BAD_STYLE)
97 || allows.contains(allow::NONSTANDARD_STYLE)
98 })
99 };
100
101 is_allowed(id)
102 // go upwards one step or give up
103 || match id {
104 AttrDefId::ModuleId(m) => m.containing_module(self.db.upcast()).map(|v| v.into()),
105 AttrDefId::FunctionId(f) => Some(f.lookup(self.db.upcast()).container.into()),
106 AttrDefId::StaticId(sid) => Some(sid.lookup(self.db.upcast()).container.into()),
107 AttrDefId::ConstId(cid) => Some(cid.lookup(self.db.upcast()).container.into()),
108 AttrDefId::TraitId(tid) => Some(tid.lookup(self.db.upcast()).container.into()),
109 AttrDefId::ImplId(iid) => Some(iid.lookup(self.db.upcast()).container.into()),
110 // These warnings should not explore macro definitions at all
111 AttrDefId::MacroDefId(_) => None,
112 // Will never occur under an enum/struct/union/type alias
113 AttrDefId::AdtId(_) => None,
114 AttrDefId::FieldId(_) => None,
115 AttrDefId::EnumVariantId(_) => None,
116 AttrDefId::TypeAliasId(_) => None,
117 AttrDefId::GenericParamId(_) => None,
118 }
119 .map(|mid| self.allowed(mid, allow_name, true))
120 .unwrap_or(false)
90 } 121 }
91 122
92 fn validate_func(&mut self, func: FunctionId) { 123 fn validate_func(&mut self, func: FunctionId) {
93 let data = self.db.function_data(func); 124 let data = self.db.function_data(func);
94 if data.is_in_extern_block { 125 if data.is_in_extern_block() {
95 cov_mark::hit!(extern_func_incorrect_case_ignored); 126 cov_mark::hit!(extern_func_incorrect_case_ignored);
96 return; 127 return;
97 } 128 }
@@ -99,8 +130,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
99 let body = self.db.body(func.into()); 130 let body = self.db.body(func.into());
100 131
101 // Recursively validate inner scope items, such as static variables and constants. 132 // Recursively validate inner scope items, such as static variables and constants.
102 let db = self.db; 133 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() { 134 for (_, module) in block_def_map.modules() {
105 for def_id in module.scope.declarations() { 135 for def_id in module.scope.declarations() {
106 let mut validator = DeclValidator::new(self.db, self.krate, self.sink); 136 let mut validator = DeclValidator::new(self.db, self.krate, self.sink);
@@ -110,7 +140,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
110 } 140 }
111 141
112 // Check whether non-snake case identifiers are allowed for this function. 142 // Check whether non-snake case identifiers are allowed for this function.
113 if self.allowed(func.into(), allow::NON_SNAKE_CASE) { 143 if self.allowed(func.into(), allow::NON_SNAKE_CASE, false) {
114 return; 144 return;
115 } 145 }
116 146
@@ -329,8 +359,9 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
329 fn validate_struct(&mut self, struct_id: StructId) { 359 fn validate_struct(&mut self, struct_id: StructId) {
330 let data = self.db.struct_data(struct_id); 360 let data = self.db.struct_data(struct_id);
331 361
332 let non_camel_case_allowed = self.allowed(struct_id.into(), allow::NON_CAMEL_CASE_TYPES); 362 let non_camel_case_allowed =
333 let non_snake_case_allowed = self.allowed(struct_id.into(), allow::NON_SNAKE_CASE); 363 self.allowed(struct_id.into(), allow::NON_CAMEL_CASE_TYPES, false);
364 let non_snake_case_allowed = self.allowed(struct_id.into(), allow::NON_SNAKE_CASE, false);
334 365
335 // Check the structure name. 366 // Check the structure name.
336 let struct_name = data.name.to_string(); 367 let struct_name = data.name.to_string();
@@ -462,7 +493,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
462 let data = self.db.enum_data(enum_id); 493 let data = self.db.enum_data(enum_id);
463 494
464 // Check whether non-camel case names are allowed for this enum. 495 // Check whether non-camel case names are allowed for this enum.
465 if self.allowed(enum_id.into(), allow::NON_CAMEL_CASE_TYPES) { 496 if self.allowed(enum_id.into(), allow::NON_CAMEL_CASE_TYPES, false) {
466 return; 497 return;
467 } 498 }
468 499
@@ -585,7 +616,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
585 fn validate_const(&mut self, const_id: ConstId) { 616 fn validate_const(&mut self, const_id: ConstId) {
586 let data = self.db.const_data(const_id); 617 let data = self.db.const_data(const_id);
587 618
588 if self.allowed(const_id.into(), allow::NON_UPPER_CASE_GLOBAL) { 619 if self.allowed(const_id.into(), allow::NON_UPPER_CASE_GLOBAL, false) {
589 return; 620 return;
590 } 621 }
591 622
@@ -633,7 +664,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
633 return; 664 return;
634 } 665 }
635 666
636 if self.allowed(static_id.into(), allow::NON_UPPER_CASE_GLOBAL) { 667 if self.allowed(static_id.into(), allow::NON_UPPER_CASE_GLOBAL, false) {
637 return; 668 return;
638 } 669 }
639 670
@@ -868,23 +899,116 @@ fn main() {
868 fn allow_attributes() { 899 fn allow_attributes() {
869 check_diagnostics( 900 check_diagnostics(
870 r#" 901 r#"
871 #[allow(non_snake_case)] 902#[allow(non_snake_case)]
872 fn NonSnakeCaseName(SOME_VAR: u8) -> u8{ 903fn NonSnakeCaseName(SOME_VAR: u8) -> u8{
873 let OtherVar = SOME_VAR + 1; 904 // cov_flags generated output from elsewhere in this file
874 OtherVar 905 extern "C" {
906 #[no_mangle]
907 static lower_case: u8;
875 } 908 }
876 909
877 #[allow(non_snake_case, non_camel_case_types)] 910 let OtherVar = SOME_VAR + 1;
878 pub struct some_type { 911 OtherVar
879 SOME_FIELD: u8, 912}
880 SomeField: u16, 913
914#[allow(nonstandard_style)]
915mod CheckNonstandardStyle {
916 fn HiImABadFnName() {}
917}
918
919#[allow(bad_style)]
920mod CheckBadStyle {
921 fn HiImABadFnName() {}
922}
923
924mod F {
925 #![allow(non_snake_case)]
926 fn CheckItWorksWithModAttr(BAD_NAME_HI: u8) {}
927}
928
929#[allow(non_snake_case, non_camel_case_types)]
930pub struct some_type {
931 SOME_FIELD: u8,
932 SomeField: u16,
933}
934
935#[allow(non_upper_case_globals)]
936pub const some_const: u8 = 10;
937
938#[allow(non_upper_case_globals)]
939pub static SomeStatic: u8 = 10;
940 "#,
941 );
881 } 942 }
882 943
883 #[allow(non_upper_case_globals)] 944 #[test]
884 pub const some_const: u8 = 10; 945 fn allow_attributes_crate_attr() {
946 check_diagnostics(
947 r#"
948#![allow(non_snake_case)]
885 949
886 #[allow(non_upper_case_globals)] 950mod F {
887 pub static SomeStatic: u8 = 10; 951 fn CheckItWorksWithCrateAttr(BAD_NAME_HI: u8) {}
952}
953 "#,
954 );
955 }
956
957 #[test]
958 #[ignore]
959 fn bug_trait_inside_fn() {
960 // FIXME:
961 // This is broken, and in fact, should not even be looked at by this
962 // lint in the first place. There's weird stuff going on in the
963 // collection phase.
964 // It's currently being brought in by:
965 // * validate_func on `a` recursing into modules
966 // * then it finds the trait and then the function while iterating
967 // through modules
968 // * then validate_func is called on Dirty
969 // * ... which then proceeds to look at some unknown module taking no
970 // attrs from either the impl or the fn a, and then finally to the root
971 // module
972 //
973 // It should find the attribute on the trait, but it *doesn't even see
974 // the trait* as far as I can tell.
975
976 check_diagnostics(
977 r#"
978trait T { fn a(); }
979struct U {}
980impl T for U {
981 fn a() {
982 // this comes out of bitflags, mostly
983 #[allow(non_snake_case)]
984 trait __BitFlags {
985 const HiImAlsoBad: u8 = 2;
986 #[inline]
987 fn Dirty(&self) -> bool {
988 false
989 }
990 }
991
992 }
993}
994 "#,
995 );
996 }
997
998 #[test]
999 #[ignore]
1000 fn bug_traits_arent_checked() {
1001 // FIXME: Traits and functions in traits aren't currently checked by
1002 // r-a, even though rustc will complain about them.
1003 check_diagnostics(
1004 r#"
1005trait BAD_TRAIT {
1006 // ^^^^^^^^^ Trait `BAD_TRAIT` should have CamelCase name, e.g. `BadTrait`
1007 fn BAD_FUNCTION();
1008 // ^^^^^^^^^^^^ Function `BAD_FUNCTION` should have snake_case name, e.g. `bad_function`
1009 fn BadFunction();
1010 // ^^^^^^^^^^^^ Function `BadFunction` should have snake_case name, e.g. `bad_function`
1011}
888 "#, 1012 "#,
889 ); 1013 );
890 } 1014 }
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index 3909ad354..79602c3dd 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -14,8 +14,7 @@ use crate::{
14 MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr, 14 MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr,
15 MissingPatFields, RemoveThisSemicolon, 15 MissingPatFields, RemoveThisSemicolon,
16 }, 16 },
17 utils::variant_data, 17 AdtId, InferenceResult, Interner, TyExt, TyKind,
18 AdtId, InferenceResult, Interner, Ty, TyKind,
19}; 18};
20 19
21pub(crate) use hir_def::{ 20pub(crate) use hir_def::{
@@ -104,7 +103,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
104 let root = source_ptr.file_syntax(db.upcast()); 103 let root = source_ptr.file_syntax(db.upcast());
105 if let ast::Expr::RecordExpr(record_expr) = &source_ptr.value.to_node(&root) { 104 if let ast::Expr::RecordExpr(record_expr) = &source_ptr.value.to_node(&root) {
106 if let Some(_) = record_expr.record_expr_field_list() { 105 if let Some(_) = record_expr.record_expr_field_list() {
107 let variant_data = variant_data(db.upcast(), variant_def); 106 let variant_data = variant_def.variant_data(db.upcast());
108 let missed_fields = missed_fields 107 let missed_fields = missed_fields
109 .into_iter() 108 .into_iter()
110 .map(|idx| variant_data.fields()[idx].name.clone()) 109 .map(|idx| variant_data.fields()[idx].name.clone())
@@ -135,7 +134,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
135 let root = source_ptr.file_syntax(db.upcast()); 134 let root = source_ptr.file_syntax(db.upcast());
136 if let ast::Pat::RecordPat(record_pat) = expr.to_node(&root) { 135 if let ast::Pat::RecordPat(record_pat) = expr.to_node(&root) {
137 if let Some(_) = record_pat.record_pat_field_list() { 136 if let Some(_) = record_pat.record_pat_field_list() {
138 let variant_data = variant_data(db.upcast(), variant_def); 137 let variant_data = variant_def.variant_data(db.upcast());
139 let missed_fields = missed_fields 138 let missed_fields = missed_fields
140 .into_iter() 139 .into_iter()
141 .map(|idx| variant_data.fields()[idx].name.clone()) 140 .map(|idx| variant_data.fields()[idx].name.clone())
@@ -245,7 +244,8 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
245 Some(callee) => callee, 244 Some(callee) => callee,
246 None => return, 245 None => return,
247 }; 246 };
248 let sig = db.callable_item_signature(callee.into()).value; 247 let sig =
248 db.callable_item_signature(callee.into()).into_value_and_skipped_binders().0;
249 249
250 (sig, args) 250 (sig, args)
251 } 251 }
@@ -314,7 +314,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
314 if pat_ty == match_expr_ty 314 if pat_ty == match_expr_ty
315 || match_expr_ty 315 || match_expr_ty
316 .as_reference() 316 .as_reference()
317 .map(|(match_expr_ty, _)| match_expr_ty == pat_ty) 317 .map(|(match_expr_ty, ..)| match_expr_ty == pat_ty)
318 .unwrap_or(false) 318 .unwrap_or(false)
319 { 319 {
320 // If we had a NotUsefulMatchArm diagnostic, we could 320 // If we had a NotUsefulMatchArm diagnostic, we could
@@ -378,7 +378,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
378 _ => return, 378 _ => return,
379 }; 379 };
380 380
381 let (params, required) = match mismatch.expected.interned(&Interner) { 381 let (params, required) = match mismatch.expected.kind(&Interner) {
382 TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters) 382 TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters)
383 if *enum_id == core_result_enum => 383 if *enum_id == core_result_enum =>
384 { 384 {
@@ -392,7 +392,9 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
392 _ => return, 392 _ => return,
393 }; 393 };
394 394
395 if params.len() > 0 && params[0] == mismatch.actual { 395 if params.len(&Interner) > 0
396 && params.at(&Interner, 0).ty(&Interner) == Some(&mismatch.actual)
397 {
396 let (_, source_map) = db.body_with_source_map(self.owner); 398 let (_, source_map) = db.body_with_source_map(self.owner);
397 399
398 if let Ok(source_ptr) = source_map.expr_syntax(id) { 400 if let Ok(source_ptr) = source_map.expr_syntax(id) {
@@ -421,7 +423,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
421 None => return, 423 None => return,
422 }; 424 };
423 425
424 if mismatch.actual != Ty::unit() || mismatch.expected != *possible_tail_ty { 426 if !mismatch.actual.is_unit() || mismatch.expected != *possible_tail_ty {
425 return; 427 return;
426 } 428 }
427 429
@@ -450,7 +452,7 @@ pub fn record_literal_missing_fields(
450 return None; 452 return None;
451 } 453 }
452 454
453 let variant_data = variant_data(db.upcast(), variant_def); 455 let variant_data = variant_def.variant_data(db.upcast());
454 456
455 let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect(); 457 let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
456 let missed_fields: Vec<LocalFieldId> = variant_data 458 let missed_fields: Vec<LocalFieldId> = variant_data
@@ -480,7 +482,7 @@ pub fn record_pattern_missing_fields(
480 return None; 482 return None;
481 } 483 }
482 484
483 let variant_data = variant_data(db.upcast(), variant_def); 485 let variant_data = variant_def.variant_data(db.upcast());
484 486
485 let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect(); 487 let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
486 let missed_fields: Vec<LocalFieldId> = variant_data 488 let missed_fields: Vec<LocalFieldId> = variant_data
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs
index 5a5cdcbf3..e9762622f 100644
--- a/crates/hir_ty/src/diagnostics/match_check.rs
+++ b/crates/hir_ty/src/diagnostics/match_check.rs
@@ -227,7 +227,7 @@ use hir_def::{
227use la_arena::Idx; 227use la_arena::Idx;
228use smallvec::{smallvec, SmallVec}; 228use smallvec::{smallvec, SmallVec};
229 229
230use crate::{db::HirDatabase, AdtId, InferenceResult, Interner, TyKind}; 230use crate::{db::HirDatabase, AdtId, InferenceResult, Interner, TyExt, TyKind};
231 231
232#[derive(Debug, Clone, Copy)] 232#[derive(Debug, Clone, Copy)]
233/// Either a pattern from the source code being analyzed, represented as 233/// Either a pattern from the source code being analyzed, represented as
@@ -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..ed97dc0e3 100644
--- a/crates/hir_ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs
@@ -11,7 +11,9 @@ use hir_def::{
11}; 11};
12use hir_expand::diagnostics::DiagnosticSink; 12use hir_expand::diagnostics::DiagnosticSink;
13 13
14use crate::{db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Interner, TyKind}; 14use crate::{
15 db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Interner, TyExt, TyKind,
16};
15 17
16pub(super) struct UnsafeValidator<'a, 'b: 'a> { 18pub(super) struct UnsafeValidator<'a, 'b: 'a> {
17 owner: DefWithBodyId, 19 owner: DefWithBodyId,
@@ -32,7 +34,7 @@ impl<'a, 'b> UnsafeValidator<'a, 'b> {
32 let def = self.owner; 34 let def = self.owner;
33 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def); 35 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def);
34 let is_unsafe = match self.owner { 36 let is_unsafe = match self.owner {
35 DefWithBodyId::FunctionId(it) => db.function_data(it).qualifier.is_unsafe, 37 DefWithBodyId::FunctionId(it) => db.function_data(it).is_unsafe(),
36 DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false, 38 DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false,
37 }; 39 };
38 if is_unsafe 40 if is_unsafe
@@ -86,7 +88,7 @@ fn walk_unsafe(
86 match expr { 88 match expr {
87 &Expr::Call { callee, .. } => { 89 &Expr::Call { callee, .. } => {
88 if let Some(func) = infer[callee].as_fn_def(db) { 90 if let Some(func) = infer[callee].as_fn_def(db) {
89 if db.function_data(func).qualifier.is_unsafe { 91 if db.function_data(func).is_unsafe() {
90 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 92 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
91 } 93 }
92 } 94 }
@@ -103,14 +105,14 @@ fn walk_unsafe(
103 Expr::MethodCall { .. } => { 105 Expr::MethodCall { .. } => {
104 if infer 106 if infer
105 .method_resolution(current) 107 .method_resolution(current)
106 .map(|func| db.function_data(func).qualifier.is_unsafe) 108 .map(|func| db.function_data(func).is_unsafe())
107 .unwrap_or(false) 109 .unwrap_or(false)
108 { 110 {
109 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 111 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
110 } 112 }
111 } 113 }
112 Expr::UnaryOp { expr, op: UnaryOp::Deref } => { 114 Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
113 if let TyKind::Raw(..) = &infer[*expr].interned(&Interner) { 115 if let TyKind::Raw(..) = &infer[*expr].kind(&Interner) {
114 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 116 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
115 } 117 }
116 } 118 }
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 51480304b..e7c9dabc2 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -1,14 +1,19 @@
1//! FIXME: write short doc here 1//! The `HirDisplay` trait, which serves two purposes: Turning various bits from
2//! HIR back into source code, and just displaying them for debugging/testing
3//! purposes.
2 4
3use std::{array, fmt}; 5use std::{
6 array,
7 fmt::{self, Debug},
8};
4 9
5use chalk_ir::Mutability; 10use chalk_ir::BoundVar;
6use hir_def::{ 11use hir_def::{
7 db::DefDatabase, 12 db::DefDatabase,
8 find_path, 13 find_path,
9 generics::TypeParamProvenance, 14 generics::TypeParamProvenance,
10 item_scope::ItemInNs, 15 item_scope::ItemInNs,
11 path::{GenericArg, Path, PathKind}, 16 path::{Path, PathKind},
12 type_ref::{TypeBound, TypeRef}, 17 type_ref::{TypeBound, TypeRef},
13 visibility::Visibility, 18 visibility::Visibility,
14 AssocContainerId, Lookup, ModuleId, TraitId, 19 AssocContainerId, Lookup, ModuleId, TraitId,
@@ -16,10 +21,12 @@ use hir_def::{
16use hir_expand::name::Name; 21use hir_expand::name::Name;
17 22
18use crate::{ 23use crate::{
19 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, 24 const_from_placeholder_idx, db::HirDatabase, from_assoc_type_id, from_foreign_def_id,
20 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy, 25 from_placeholder_idx, lt_from_placeholder_idx, mapping::from_chalk, primitive, subst_prefix,
21 CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy, 26 to_assoc_type_id, utils::generics, AdtId, AliasEq, AliasTy, CallableDefId, CallableSig, Const,
22 ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause, 27 ConstValue, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, LifetimeData,
28 LifetimeOutlives, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause,
29 Scalar, TraitRef, TraitRefExt, Ty, TyExt, TyKind, WhereClause,
23}; 30};
24 31
25pub struct HirFormatter<'a> { 32pub struct HirFormatter<'a> {
@@ -46,6 +53,10 @@ pub trait HirDisplay {
46 where 53 where
47 Self: Sized, 54 Self: Sized,
48 { 55 {
56 assert!(
57 !matches!(display_target, DisplayTarget::SourceCode { .. }),
58 "HirDisplayWrapper cannot fail with DisplaySourceCodeError, use HirDisplay::hir_fmt directly instead"
59 );
49 HirDisplayWrapper { db, t: self, max_size, omit_verbose_types, display_target } 60 HirDisplayWrapper { db, t: self, max_size, omit_verbose_types, display_target }
50 } 61 }
51 62
@@ -230,7 +241,7 @@ where
230 Err(HirDisplayError::FmtError) => Err(fmt::Error), 241 Err(HirDisplayError::FmtError) => Err(fmt::Error),
231 Err(HirDisplayError::DisplaySourceCodeError(_)) => { 242 Err(HirDisplayError::DisplaySourceCodeError(_)) => {
232 // This should never happen 243 // This should never happen
233 panic!("HirDisplay failed when calling Display::fmt!") 244 panic!("HirDisplay::hir_fmt failed with DisplaySourceCodeError when calling Display::fmt!")
234 } 245 }
235 } 246 }
236 } 247 }
@@ -251,16 +262,12 @@ impl HirDisplay for ProjectionTy {
251 } 262 }
252 263
253 let trait_ = f.db.trait_data(self.trait_(f.db)); 264 let trait_ = f.db.trait_data(self.trait_(f.db));
254 let first_parameter = self.substitution[0].into_displayable( 265 write!(f, "<")?;
255 f.db, 266 self.self_type_parameter(&Interner).hir_fmt(f)?;
256 f.max_size, 267 write!(f, " as {}", trait_.name)?;
257 f.omit_verbose_types, 268 if self.substitution.len(&Interner) > 1 {
258 f.display_target,
259 );
260 write!(f, "<{} as {}", first_parameter, trait_.name)?;
261 if self.substitution.len() > 1 {
262 write!(f, "<")?; 269 write!(f, "<")?;
263 f.write_joined(&self.substitution[1..], ", ")?; 270 f.write_joined(&self.substitution.as_slice(&Interner)[1..], ", ")?;
264 write!(f, ">")?; 271 write!(f, ">")?;
265 } 272 }
266 write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?; 273 write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?;
@@ -274,7 +281,40 @@ impl HirDisplay for OpaqueTy {
274 return write!(f, "{}", TYPE_HINT_TRUNCATION); 281 return write!(f, "{}", TYPE_HINT_TRUNCATION);
275 } 282 }
276 283
277 self.substitution[0].hir_fmt(f) 284 self.substitution.at(&Interner, 0).hir_fmt(f)
285 }
286}
287
288impl HirDisplay for GenericArg {
289 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
290 match self.interned() {
291 crate::GenericArgData::Ty(ty) => ty.hir_fmt(f),
292 crate::GenericArgData::Lifetime(lt) => lt.hir_fmt(f),
293 crate::GenericArgData::Const(c) => c.hir_fmt(f),
294 }
295 }
296}
297
298impl HirDisplay for Const {
299 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
300 let data = self.interned();
301 match data.value {
302 ConstValue::BoundVar(idx) => idx.hir_fmt(f),
303 ConstValue::InferenceVar(..) => write!(f, "_"),
304 ConstValue::Placeholder(idx) => {
305 let id = const_from_placeholder_idx(f.db, idx);
306 let generics = generics(f.db.upcast(), id.parent);
307 let param_data = &generics.params.consts[id.local_id];
308 write!(f, "{}", param_data.name)
309 }
310 ConstValue::Concrete(_) => write!(f, "_"),
311 }
312 }
313}
314
315impl HirDisplay for BoundVar {
316 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
317 write!(f, "?{}.{}", self.debruijn.depth(), self.index)
278 } 318 }
279} 319}
280 320
@@ -284,7 +324,7 @@ impl HirDisplay for Ty {
284 return write!(f, "{}", TYPE_HINT_TRUNCATION); 324 return write!(f, "{}", TYPE_HINT_TRUNCATION);
285 } 325 }
286 326
287 match self.interned(&Interner) { 327 match self.kind(&Interner) {
288 TyKind::Never => write!(f, "!")?, 328 TyKind::Never => write!(f, "!")?,
289 TyKind::Str => write!(f, "str")?, 329 TyKind::Str => write!(f, "str")?,
290 TyKind::Scalar(Scalar::Bool) => write!(f, "bool")?, 330 TyKind::Scalar(Scalar::Bool) => write!(f, "bool")?,
@@ -297,16 +337,15 @@ impl HirDisplay for Ty {
297 t.hir_fmt(f)?; 337 t.hir_fmt(f)?;
298 write!(f, "]")?; 338 write!(f, "]")?;
299 } 339 }
300 TyKind::Array(t) => { 340 TyKind::Array(t, c) => {
301 write!(f, "[")?; 341 write!(f, "[")?;
302 t.hir_fmt(f)?; 342 t.hir_fmt(f)?;
303 write!(f, "; _]")?; 343 write!(f, "; ")?;
344 c.hir_fmt(f)?;
345 write!(f, "]")?;
304 } 346 }
305 TyKind::Raw(m, t) | TyKind::Ref(m, t) => { 347 TyKind::Raw(m, t) | TyKind::Ref(m, _, t) => {
306 let ty_display = 348 if matches!(self.kind(&Interner), TyKind::Raw(..)) {
307 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
308
309 if matches!(self.interned(&Interner), TyKind::Raw(..)) {
310 write!( 349 write!(
311 f, 350 f,
312 "*{}", 351 "*{}",
@@ -328,7 +367,7 @@ impl HirDisplay for Ty {
328 367
329 // FIXME: all this just to decide whether to use parentheses... 368 // FIXME: all this just to decide whether to use parentheses...
330 let datas; 369 let datas;
331 let predicates: Vec<_> = match t.interned(&Interner) { 370 let predicates: Vec<_> = match t.kind(&Interner) {
332 TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => { 371 TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => {
333 dyn_ty.bounds.skip_binders().interned().iter().cloned().collect() 372 dyn_ty.bounds.skip_binders().interned().iter().cloned().collect()
334 } 373 }
@@ -344,8 +383,8 @@ impl HirDisplay for Ty {
344 let data = (*datas) 383 let data = (*datas)
345 .as_ref() 384 .as_ref()
346 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 385 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
347 let bounds = data.subst(parameters); 386 let bounds = data.substitute(&Interner, parameters);
348 bounds.value 387 bounds.into_value_and_skipped_binders().0
349 } else { 388 } else {
350 Vec::new() 389 Vec::new()
351 } 390 }
@@ -360,26 +399,26 @@ impl HirDisplay for Ty {
360 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) 399 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_)
361 && predicates.len() <= 2 400 && predicates.len() <= 2
362 { 401 {
363 return write!(f, "{}", ty_display); 402 return t.hir_fmt(f);
364 } 403 }
365 } 404 }
366 405
367 if predicates.len() > 1 { 406 if predicates.len() > 1 {
368 write!(f, "(")?; 407 write!(f, "(")?;
369 write!(f, "{}", ty_display)?; 408 t.hir_fmt(f)?;
370 write!(f, ")")?; 409 write!(f, ")")?;
371 } else { 410 } else {
372 write!(f, "{}", ty_display)?; 411 t.hir_fmt(f)?;
373 } 412 }
374 } 413 }
375 TyKind::Tuple(_, substs) => { 414 TyKind::Tuple(_, substs) => {
376 if substs.len() == 1 { 415 if substs.len(&Interner) == 1 {
377 write!(f, "(")?; 416 write!(f, "(")?;
378 substs[0].hir_fmt(f)?; 417 substs.at(&Interner, 0).hir_fmt(f)?;
379 write!(f, ",)")?; 418 write!(f, ",)")?;
380 } else { 419 } else {
381 write!(f, "(")?; 420 write!(f, "(")?;
382 f.write_joined(&*substs.0, ", ")?; 421 f.write_joined(&*substs.as_slice(&Interner), ", ")?;
383 write!(f, ")")?; 422 write!(f, ")")?;
384 } 423 }
385 } 424 }
@@ -389,7 +428,7 @@ impl HirDisplay for Ty {
389 } 428 }
390 TyKind::FnDef(def, parameters) => { 429 TyKind::FnDef(def, parameters) => {
391 let def = from_chalk(f.db, *def); 430 let def = from_chalk(f.db, *def);
392 let sig = f.db.callable_item_signature(def).subst(parameters); 431 let sig = f.db.callable_item_signature(def).substitute(&Interner, parameters);
393 match def { 432 match def {
394 CallableDefId::FunctionId(ff) => { 433 CallableDefId::FunctionId(ff) => {
395 write!(f, "fn {}", f.db.function_data(ff).name)? 434 write!(f, "fn {}", f.db.function_data(ff).name)?
@@ -399,7 +438,7 @@ impl HirDisplay for Ty {
399 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? 438 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)?
400 } 439 }
401 }; 440 };
402 if parameters.len() > 0 { 441 if parameters.len(&Interner) > 0 {
403 let generics = generics(f.db.upcast(), def.into()); 442 let generics = generics(f.db.upcast(), def.into());
404 let (parent_params, self_param, type_params, _impl_trait_params) = 443 let (parent_params, self_param, type_params, _impl_trait_params) =
405 generics.provenance_split(); 444 generics.provenance_split();
@@ -407,7 +446,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? 446 // 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 { 447 if total_len > 0 {
409 write!(f, "<")?; 448 write!(f, "<")?;
410 f.write_joined(&parameters.0[..total_len], ", ")?; 449 f.write_joined(&parameters.as_slice(&Interner)[..total_len], ", ")?;
411 write!(f, ">")?; 450 write!(f, ">")?;
412 } 451 }
413 } 452 }
@@ -415,15 +454,9 @@ impl HirDisplay for Ty {
415 f.write_joined(sig.params(), ", ")?; 454 f.write_joined(sig.params(), ", ")?;
416 write!(f, ")")?; 455 write!(f, ")")?;
417 let ret = sig.ret(); 456 let ret = sig.ret();
418 if *ret != Ty::unit() { 457 if !ret.is_unit() {
419 let ret_display = ret.into_displayable( 458 write!(f, " -> ")?;
420 f.db, 459 ret.hir_fmt(f)?;
421 f.max_size,
422 f.omit_verbose_types,
423 f.display_target,
424 );
425
426 write!(f, " -> {}", ret_display)?;
427 } 460 }
428 } 461 }
429 TyKind::Adt(AdtId(def_id), parameters) => { 462 TyKind::Adt(AdtId(def_id), parameters) => {
@@ -451,7 +484,7 @@ impl HirDisplay for Ty {
451 } 484 }
452 } 485 }
453 486
454 if parameters.len() > 0 { 487 if parameters.len(&Interner) > 0 {
455 let parameters_to_write = if f.display_target.is_source_code() 488 let parameters_to_write = if f.display_target.is_source_code()
456 || f.omit_verbose_types() 489 || f.omit_verbose_types()
457 { 490 {
@@ -460,30 +493,35 @@ impl HirDisplay for Ty {
460 .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) 493 .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
461 .filter(|defaults| !defaults.is_empty()) 494 .filter(|defaults| !defaults.is_empty())
462 { 495 {
463 None => parameters.0.as_ref(), 496 None => parameters.as_slice(&Interner),
464 Some(default_parameters) => { 497 Some(default_parameters) => {
465 let mut default_from = 0; 498 let mut default_from = 0;
466 for (i, parameter) in parameters.iter().enumerate() { 499 for (i, parameter) in parameters.iter(&Interner).enumerate() {
467 match (parameter.interned(&Interner), default_parameters.get(i)) 500 match (
468 { 501 parameter.assert_ty_ref(&Interner).kind(&Interner),
469 (&TyKind::Unknown, _) | (_, None) => { 502 default_parameters.get(i),
503 ) {
504 (&TyKind::Error, _) | (_, None) => {
470 default_from = i + 1; 505 default_from = i + 1;
471 } 506 }
472 (_, Some(default_parameter)) => { 507 (_, Some(default_parameter)) => {
473 let actual_default = default_parameter 508 let actual_default =
474 .clone() 509 default_parameter.clone().substitute(
475 .subst(&parameters.prefix(i)); 510 &Interner,
476 if parameter != &actual_default { 511 &subst_prefix(parameters, i),
512 );
513 if parameter.assert_ty_ref(&Interner) != &actual_default
514 {
477 default_from = i + 1; 515 default_from = i + 1;
478 } 516 }
479 } 517 }
480 } 518 }
481 } 519 }
482 &parameters.0[0..default_from] 520 &parameters.as_slice(&Interner)[0..default_from]
483 } 521 }
484 } 522 }
485 } else { 523 } else {
486 parameters.0.as_ref() 524 parameters.as_slice(&Interner)
487 }; 525 };
488 if !parameters_to_write.is_empty() { 526 if !parameters_to_write.is_empty() {
489 write!(f, "<")?; 527 write!(f, "<")?;
@@ -504,9 +542,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) 542 // 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() { 543 if f.display_target.is_test() {
506 write!(f, "{}::{}", trait_.name, type_alias_data.name)?; 544 write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
507 if parameters.len() > 0 { 545 if parameters.len(&Interner) > 0 {
508 write!(f, "<")?; 546 write!(f, "<")?;
509 f.write_joined(&*parameters.0, ", ")?; 547 f.write_joined(&*parameters.as_slice(&Interner), ", ")?;
510 write!(f, ">")?; 548 write!(f, ">")?;
511 } 549 }
512 } else { 550 } else {
@@ -518,7 +556,7 @@ impl HirDisplay for Ty {
518 projection_ty.hir_fmt(f)?; 556 projection_ty.hir_fmt(f)?;
519 } 557 }
520 } 558 }
521 TyKind::ForeignType(type_alias) => { 559 TyKind::Foreign(type_alias) => {
522 let type_alias = f.db.type_alias_data(from_foreign_def_id(*type_alias)); 560 let type_alias = f.db.type_alias_data(from_foreign_def_id(*type_alias));
523 write!(f, "{}", type_alias.name)?; 561 write!(f, "{}", type_alias.name)?;
524 } 562 }
@@ -531,13 +569,13 @@ impl HirDisplay for Ty {
531 let data = (*datas) 569 let data = (*datas)
532 .as_ref() 570 .as_ref()
533 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 571 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
534 let bounds = data.subst(&parameters); 572 let bounds = data.substitute(&Interner, &parameters);
535 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 573 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 574 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
537 } 575 }
538 ImplTraitId::AsyncBlockTypeImplTrait(..) => { 576 ImplTraitId::AsyncBlockTypeImplTrait(..) => {
539 write!(f, "impl Future<Output = ")?; 577 write!(f, "impl Future<Output = ")?;
540 parameters[0].hir_fmt(f)?; 578 parameters.at(&Interner, 0).hir_fmt(f)?;
541 write!(f, ">")?; 579 write!(f, ">")?;
542 } 580 }
543 } 581 }
@@ -548,7 +586,7 @@ impl HirDisplay for Ty {
548 DisplaySourceCodeError::Closure, 586 DisplaySourceCodeError::Closure,
549 )); 587 ));
550 } 588 }
551 let sig = substs[0].callable_sig(f.db); 589 let sig = substs.at(&Interner, 0).assert_ty_ref(&Interner).callable_sig(f.db);
552 if let Some(sig) = sig { 590 if let Some(sig) = sig {
553 if sig.params().is_empty() { 591 if sig.params().is_empty() {
554 write!(f, "||")?; 592 write!(f, "||")?;
@@ -560,13 +598,8 @@ impl HirDisplay for Ty {
560 write!(f, "|")?; 598 write!(f, "|")?;
561 }; 599 };
562 600
563 let ret_display = sig.ret().into_displayable( 601 write!(f, " -> ")?;
564 f.db, 602 sig.ret().hir_fmt(f)?;
565 f.max_size,
566 f.omit_verbose_types,
567 f.display_target,
568 );
569 write!(f, " -> {}", ret_display)?;
570 } else { 603 } else {
571 write!(f, "{{closure}}")?; 604 write!(f, "{{closure}}")?;
572 } 605 }
@@ -580,26 +613,27 @@ impl HirDisplay for Ty {
580 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? 613 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
581 } 614 }
582 TypeParamProvenance::ArgumentImplTrait => { 615 TypeParamProvenance::ArgumentImplTrait => {
583 let substs = Substitution::type_params_for_generics(f.db, &generics); 616 let substs = generics.type_params_subst(f.db);
584 let bounds = f 617 let bounds =
585 .db 618 f.db.generic_predicates(id.parent)
586 .generic_predicates(id.parent) 619 .into_iter()
587 .into_iter() 620 .map(|pred| pred.clone().substitute(&Interner, &substs))
588 .map(|pred| pred.clone().subst(&substs)) 621 .filter(|wc| match &wc.skip_binders() {
589 .filter(|wc| match &wc.skip_binders() { 622 WhereClause::Implemented(tr) => {
590 WhereClause::Implemented(tr) => tr.self_type_parameter() == self, 623 &tr.self_type_parameter(&Interner) == self
591 WhereClause::AliasEq(AliasEq { 624 }
592 alias: AliasTy::Projection(proj), 625 WhereClause::AliasEq(AliasEq {
593 ty: _, 626 alias: AliasTy::Projection(proj),
594 }) => proj.self_type_parameter() == self, 627 ty: _,
595 _ => false, 628 }) => &proj.self_type_parameter(&Interner) == self,
596 }) 629 _ => false,
597 .collect::<Vec<_>>(); 630 })
631 .collect::<Vec<_>>();
598 write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?; 632 write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?;
599 } 633 }
600 } 634 }
601 } 635 }
602 TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 636 TyKind::BoundVar(idx) => idx.hir_fmt(f)?,
603 TyKind::Dyn(dyn_ty) => { 637 TyKind::Dyn(dyn_ty) => {
604 write_bounds_like_dyn_trait_with_prefix( 638 write_bounds_like_dyn_trait_with_prefix(
605 "dyn", 639 "dyn",
@@ -617,15 +651,15 @@ impl HirDisplay for Ty {
617 let data = (*datas) 651 let data = (*datas)
618 .as_ref() 652 .as_ref()
619 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 653 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
620 let bounds = data.subst(&opaque_ty.substitution); 654 let bounds = data.substitute(&Interner, &opaque_ty.substitution);
621 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 655 write_bounds_like_dyn_trait_with_prefix("impl", bounds.skip_binders(), f)?;
622 } 656 }
623 ImplTraitId::AsyncBlockTypeImplTrait(..) => { 657 ImplTraitId::AsyncBlockTypeImplTrait(..) => {
624 write!(f, "{{async block}}")?; 658 write!(f, "{{async block}}")?;
625 } 659 }
626 }; 660 };
627 } 661 }
628 TyKind::Unknown => { 662 TyKind::Error => {
629 if f.display_target.is_source_code() { 663 if f.display_target.is_source_code() {
630 return Err(HirDisplayError::DisplaySourceCodeError( 664 return Err(HirDisplayError::DisplaySourceCodeError(
631 DisplaySourceCodeError::UnknownType, 665 DisplaySourceCodeError::UnknownType,
@@ -634,6 +668,8 @@ impl HirDisplay for Ty {
634 write!(f, "{{unknown}}")?; 668 write!(f, "{{unknown}}")?;
635 } 669 }
636 TyKind::InferenceVar(..) => write!(f, "_")?, 670 TyKind::InferenceVar(..) => write!(f, "_")?,
671 TyKind::Generator(..) => write!(f, "{{generator}}")?,
672 TyKind::GeneratorWitness(..) => write!(f, "{{generator witness}}")?,
637 } 673 }
638 Ok(()) 674 Ok(())
639 } 675 }
@@ -652,10 +688,9 @@ impl HirDisplay for CallableSig {
652 } 688 }
653 write!(f, ")")?; 689 write!(f, ")")?;
654 let ret = self.ret(); 690 let ret = self.ret();
655 if *ret != Ty::unit() { 691 if !ret.is_unit() {
656 let ret_display = 692 write!(f, " -> ")?;
657 ret.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); 693 ret.hir_fmt(f)?;
658 write!(f, " -> {}", ret_display)?;
659 } 694 }
660 Ok(()) 695 Ok(())
661 } 696 }
@@ -712,15 +747,17 @@ fn write_bounds_like_dyn_trait(
712 if !first { 747 if !first {
713 write!(f, " + ")?; 748 write!(f, " + ")?;
714 } 749 }
715 // We assume that the self type is $0 (i.e. the 750 // We assume that the self type is ^0.0 (i.e. the
716 // existential) here, which is the only thing that's 751 // existential) here, which is the only thing that's
717 // possible in actual Rust, and hence don't print it 752 // possible in actual Rust, and hence don't print it
718 write!(f, "{}", f.db.trait_data(trait_).name)?; 753 write!(f, "{}", f.db.trait_data(trait_).name)?;
719 if let [_, params @ ..] = &*trait_ref.substitution.0 { 754 if let [_, params @ ..] = &*trait_ref.substitution.as_slice(&Interner) {
720 if is_fn_trait { 755 if is_fn_trait {
721 if let Some(args) = params.first().and_then(|it| it.as_tuple()) { 756 if let Some(args) =
757 params.first().and_then(|it| it.assert_ty_ref(&Interner).as_tuple())
758 {
722 write!(f, "(")?; 759 write!(f, "(")?;
723 f.write_joined(&*args.0, ", ")?; 760 f.write_joined(args.as_slice(&Interner), ", ")?;
724 write!(f, ")")?; 761 write!(f, ")")?;
725 } 762 }
726 } else if !params.is_empty() { 763 } else if !params.is_empty() {
@@ -752,6 +789,10 @@ fn write_bounds_like_dyn_trait(
752 } 789 }
753 ty.hir_fmt(f)?; 790 ty.hir_fmt(f)?;
754 } 791 }
792
793 // FIXME implement these
794 WhereClause::LifetimeOutlives(_) => {}
795 WhereClause::TypeOutlives(_) => {}
755 } 796 }
756 first = false; 797 first = false;
757 } 798 }
@@ -761,31 +802,29 @@ fn write_bounds_like_dyn_trait(
761 Ok(()) 802 Ok(())
762} 803}
763 804
764impl TraitRef { 805fn fmt_trait_ref(tr: &TraitRef, f: &mut HirFormatter, use_as: bool) -> Result<(), HirDisplayError> {
765 fn hir_fmt_ext(&self, f: &mut HirFormatter, use_as: bool) -> Result<(), HirDisplayError> { 806 if f.should_truncate() {
766 if f.should_truncate() { 807 return write!(f, "{}", TYPE_HINT_TRUNCATION);
767 return write!(f, "{}", TYPE_HINT_TRUNCATION); 808 }
768 }
769 809
770 self.substitution[0].hir_fmt(f)?; 810 tr.self_type_parameter(&Interner).hir_fmt(f)?;
771 if use_as { 811 if use_as {
772 write!(f, " as ")?; 812 write!(f, " as ")?;
773 } else { 813 } else {
774 write!(f, ": ")?; 814 write!(f, ": ")?;
775 } 815 }
776 write!(f, "{}", f.db.trait_data(self.hir_trait_id()).name)?; 816 write!(f, "{}", f.db.trait_data(tr.hir_trait_id()).name)?;
777 if self.substitution.len() > 1 { 817 if tr.substitution.len(&Interner) > 1 {
778 write!(f, "<")?; 818 write!(f, "<")?;
779 f.write_joined(&self.substitution[1..], ", ")?; 819 f.write_joined(&tr.substitution.as_slice(&Interner)[1..], ", ")?;
780 write!(f, ">")?; 820 write!(f, ">")?;
781 }
782 Ok(())
783 } 821 }
822 Ok(())
784} 823}
785 824
786impl HirDisplay for TraitRef { 825impl HirDisplay for TraitRef {
787 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 826 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
788 self.hir_fmt_ext(f, false) 827 fmt_trait_ref(self, f, false)
789 } 828 }
790} 829}
791 830
@@ -799,7 +838,7 @@ impl HirDisplay for WhereClause {
799 WhereClause::Implemented(trait_ref) => trait_ref.hir_fmt(f)?, 838 WhereClause::Implemented(trait_ref) => trait_ref.hir_fmt(f)?,
800 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { 839 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
801 write!(f, "<")?; 840 write!(f, "<")?;
802 projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?; 841 fmt_trait_ref(&projection_ty.trait_ref(f.db), f, true)?;
803 write!( 842 write!(
804 f, 843 f,
805 ">::{} = ", 844 ">::{} = ",
@@ -808,20 +847,44 @@ impl HirDisplay for WhereClause {
808 ty.hir_fmt(f)?; 847 ty.hir_fmt(f)?;
809 } 848 }
810 WhereClause::AliasEq(_) => write!(f, "{{error}}")?, 849 WhereClause::AliasEq(_) => write!(f, "{{error}}")?,
850
851 // FIXME implement these
852 WhereClause::TypeOutlives(..) => {}
853 WhereClause::LifetimeOutlives(..) => {}
811 } 854 }
812 Ok(()) 855 Ok(())
813 } 856 }
814} 857}
815 858
859impl HirDisplay for LifetimeOutlives {
860 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
861 self.a.hir_fmt(f)?;
862 write!(f, ": ")?;
863 self.b.hir_fmt(f)
864 }
865}
866
816impl HirDisplay for Lifetime { 867impl HirDisplay for Lifetime {
817 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 868 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
869 self.interned().hir_fmt(f)
870 }
871}
872
873impl HirDisplay for LifetimeData {
874 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
818 match self { 875 match self {
819 Lifetime::Parameter(id) => { 876 LifetimeData::BoundVar(idx) => idx.hir_fmt(f),
877 LifetimeData::InferenceVar(_) => write!(f, "_"),
878 LifetimeData::Placeholder(idx) => {
879 let id = lt_from_placeholder_idx(f.db, *idx);
820 let generics = generics(f.db.upcast(), id.parent); 880 let generics = generics(f.db.upcast(), id.parent);
821 let param_data = &generics.params.lifetimes[id.local_id]; 881 let param_data = &generics.params.lifetimes[id.local_id];
822 write!(f, "{}", &param_data.name) 882 write!(f, "{}", param_data.name)
823 } 883 }
824 Lifetime::Static => write!(f, "'static"), 884 LifetimeData::Static => write!(f, "'static"),
885 LifetimeData::Empty(_) => Ok(()),
886 LifetimeData::Erased => Ok(()),
887 LifetimeData::Phantom(_, _) => Ok(()),
825 } 888 }
826 } 889 }
827} 890}
@@ -832,9 +895,11 @@ impl HirDisplay for DomainGoal {
832 DomainGoal::Holds(wc) => { 895 DomainGoal::Holds(wc) => {
833 write!(f, "Holds(")?; 896 write!(f, "Holds(")?;
834 wc.hir_fmt(f)?; 897 wc.hir_fmt(f)?;
835 write!(f, ")") 898 write!(f, ")")?;
836 } 899 }
900 _ => write!(f, "?")?,
837 } 901 }
902 Ok(())
838 } 903 }
839} 904}
840 905
@@ -1016,11 +1081,11 @@ impl HirDisplay for Path {
1016 } 1081 }
1017} 1082}
1018 1083
1019impl HirDisplay for GenericArg { 1084impl HirDisplay for hir_def::path::GenericArg {
1020 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 1085 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
1021 match self { 1086 match self {
1022 GenericArg::Type(ty) => ty.hir_fmt(f), 1087 hir_def::path::GenericArg::Type(ty) => ty.hir_fmt(f),
1023 GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name), 1088 hir_def::path::GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name),
1024 } 1089 }
1025 } 1090 }
1026} 1091}
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index e4407ff50..bf2da2d4a 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -18,7 +18,7 @@ use std::mem;
18use std::ops::Index; 18use std::ops::Index;
19use std::sync::Arc; 19use std::sync::Arc;
20 20
21use chalk_ir::{cast::Cast, Mutability}; 21use chalk_ir::{cast::Cast, DebruijnIndex, Mutability};
22use hir_def::{ 22use hir_def::{
23 body::Body, 23 body::Body,
24 data::{ConstData, FunctionData, StaticData}, 24 data::{ConstData, FunctionData, StaticData},
@@ -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,
42}; 41};
43use crate::{ 42use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, 43 db::HirDatabase, fold_tys, infer::diagnostics::InferenceDiagnostic,
45 to_assoc_type_id, to_chalk_trait_id, AliasEq, AliasTy, Interner, TyKind, 44 lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Canonical, Interner,
45 TyBuilder, TyExt, 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
@@ -131,10 +131,7 @@ pub struct InferenceResult {
131 method_resolutions: FxHashMap<ExprId, FunctionId>, 131 method_resolutions: FxHashMap<ExprId, FunctionId>,
132 /// For each field access expr, records the field it resolves to. 132 /// For each field access expr, records the field it resolves to.
133 field_resolutions: FxHashMap<ExprId, FieldId>, 133 field_resolutions: FxHashMap<ExprId, FieldId>,
134 /// For each field in record literal, records the field it resolves to. 134 /// For each struct literal or pattern, records the variant it resolves to.
135 record_field_resolutions: FxHashMap<ExprId, FieldId>,
136 record_pat_field_resolutions: FxHashMap<PatId, FieldId>,
137 /// For each struct literal, records the variant it resolves to.
138 variant_resolutions: FxHashMap<ExprOrPatId, VariantId>, 135 variant_resolutions: FxHashMap<ExprOrPatId, VariantId>,
139 /// For each associated item record what it resolves to 136 /// For each associated item record what it resolves to
140 assoc_resolutions: FxHashMap<ExprOrPatId, AssocItemId>, 137 assoc_resolutions: FxHashMap<ExprOrPatId, AssocItemId>,
@@ -153,12 +150,6 @@ impl InferenceResult {
153 pub fn field_resolution(&self, expr: ExprId) -> Option<FieldId> { 150 pub fn field_resolution(&self, expr: ExprId) -> Option<FieldId> {
154 self.field_resolutions.get(&expr).copied() 151 self.field_resolutions.get(&expr).copied()
155 } 152 }
156 pub fn record_field_resolution(&self, expr: ExprId) -> Option<FieldId> {
157 self.record_field_resolutions.get(&expr).copied()
158 }
159 pub fn record_pat_field_resolution(&self, pat: PatId) -> Option<FieldId> {
160 self.record_pat_field_resolutions.get(&pat).copied()
161 }
162 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> { 153 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> {
163 self.variant_resolutions.get(&id.into()).copied() 154 self.variant_resolutions.get(&id.into()).copied()
164 } 155 }
@@ -210,6 +201,7 @@ struct InferenceContext<'a> {
210 table: unify::InferenceTable, 201 table: unify::InferenceTable,
211 trait_env: Arc<TraitEnvironment>, 202 trait_env: Arc<TraitEnvironment>,
212 obligations: Vec<DomainGoal>, 203 obligations: Vec<DomainGoal>,
204 last_obligations_check: Option<u32>,
213 result: InferenceResult, 205 result: InferenceResult,
214 /// The return type of the function being inferred, or the closure if we're 206 /// The return type of the function being inferred, or the closure if we're
215 /// currently within one. 207 /// currently within one.
@@ -245,7 +237,8 @@ impl<'a> InferenceContext<'a> {
245 result: InferenceResult::default(), 237 result: InferenceResult::default(),
246 table: unify::InferenceTable::new(), 238 table: unify::InferenceTable::new(),
247 obligations: Vec::default(), 239 obligations: Vec::default(),
248 return_ty: TyKind::Unknown.intern(&Interner), // set in collect_fn_signature 240 last_obligations_check: None,
241 return_ty: TyKind::Error.intern(&Interner), // set in collect_fn_signature
249 trait_env: owner 242 trait_env: owner
250 .as_generic_def_id() 243 .as_generic_def_id()
251 .map_or_else(Default::default, |d| db.trait_environment(d)), 244 .map_or_else(Default::default, |d| db.trait_environment(d)),
@@ -259,7 +252,7 @@ impl<'a> InferenceContext<'a> {
259 } 252 }
260 253
261 fn err_ty(&self) -> Ty { 254 fn err_ty(&self) -> Ty {
262 TyKind::Unknown.intern(&Interner) 255 TyKind::Error.intern(&Interner)
263 } 256 }
264 257
265 fn resolve_all(mut self) -> InferenceResult { 258 fn resolve_all(mut self) -> InferenceResult {
@@ -323,30 +316,44 @@ impl<'a> InferenceContext<'a> {
323 316
324 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. 317 /// 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 { 318 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
326 match ty.interned(&Interner) { 319 match ty.kind(&Interner) {
327 TyKind::Unknown => self.table.new_type_var(), 320 TyKind::Error => self.table.new_type_var(),
328 _ => ty, 321 _ => ty,
329 } 322 }
330 } 323 }
331 324
332 fn insert_type_vars(&mut self, ty: Ty) -> Ty { 325 fn insert_type_vars(&mut self, ty: Ty) -> Ty {
333 ty.fold(&mut |ty| self.insert_type_vars_shallow(ty)) 326 fold_tys(ty, |ty, _| self.insert_type_vars_shallow(ty), DebruijnIndex::INNERMOST)
334 } 327 }
335 328
336 fn resolve_obligations_as_possible(&mut self) { 329 fn resolve_obligations_as_possible(&mut self) {
330 if self.last_obligations_check == Some(self.table.revision) {
331 // no change
332 return;
333 }
334 let _span = profile::span("resolve_obligations_as_possible");
335
336 self.last_obligations_check = Some(self.table.revision);
337 let obligations = mem::replace(&mut self.obligations, Vec::new()); 337 let obligations = mem::replace(&mut self.obligations, Vec::new());
338 for obligation in obligations { 338 for obligation in obligations {
339 let in_env = InEnvironment::new(self.trait_env.env.clone(), obligation.clone()); 339 let in_env = InEnvironment::new(&self.trait_env.env, obligation.clone());
340 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env); 340 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env);
341 let solution = 341 let solution =
342 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone()); 342 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone());
343 343
344 match solution { 344 match solution {
345 Some(Solution::Unique(substs)) => { 345 Some(Solution::Unique(canonical_subst)) => {
346 canonicalized.apply_solution(self, substs.0); 346 canonicalized.apply_solution(
347 self,
348 Canonical {
349 binders: canonical_subst.binders,
350 // FIXME: handle constraints
351 value: canonical_subst.value.subst,
352 },
353 );
347 } 354 }
348 Some(Solution::Ambig(Guidance::Definite(substs))) => { 355 Some(Solution::Ambig(Guidance::Definite(substs))) => {
349 canonicalized.apply_solution(self, substs.0); 356 canonicalized.apply_solution(self, substs);
350 self.obligations.push(obligation); 357 self.obligations.push(obligation);
351 } 358 }
352 Some(_) => { 359 Some(_) => {
@@ -360,6 +367,11 @@ impl<'a> InferenceContext<'a> {
360 } 367 }
361 } 368 }
362 369
370 fn push_obligation(&mut self, o: DomainGoal) {
371 self.obligations.push(o);
372 self.last_obligations_check = None;
373 }
374
363 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { 375 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
364 self.table.unify(ty1, ty2) 376 self.table.unify(ty1, ty2)
365 } 377 }
@@ -395,21 +407,19 @@ impl<'a> InferenceContext<'a> {
395 _ => panic!("resolve_associated_type called with non-associated type"), 407 _ => panic!("resolve_associated_type called with non-associated type"),
396 }; 408 };
397 let ty = self.table.new_type_var(); 409 let ty = self.table.new_type_var();
398 let substs = Substitution::build_for_def(self.db, res_assoc_ty) 410 let trait_ref = TyBuilder::trait_ref(self.db, trait_)
399 .push(inner_ty) 411 .push(inner_ty)
400 .fill(params.iter().cloned()) 412 .fill(params.iter().cloned())
401 .build(); 413 .build();
402 let trait_ref =
403 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs.clone() };
404 let alias_eq = AliasEq { 414 let alias_eq = AliasEq {
405 alias: AliasTy::Projection(ProjectionTy { 415 alias: AliasTy::Projection(ProjectionTy {
406 associated_ty_id: to_assoc_type_id(res_assoc_ty), 416 associated_ty_id: to_assoc_type_id(res_assoc_ty),
407 substitution: substs, 417 substitution: trait_ref.substitution.clone(),
408 }), 418 }),
409 ty: ty.clone(), 419 ty: ty.clone(),
410 }; 420 };
411 self.obligations.push(trait_ref.cast(&Interner)); 421 self.push_obligation(trait_ref.cast(&Interner));
412 self.obligations.push(alias_eq.cast(&Interner)); 422 self.push_obligation(alias_eq.cast(&Interner));
413 self.resolve_ty_as_possible(ty) 423 self.resolve_ty_as_possible(ty)
414 } 424 }
415 None => self.err_ty(), 425 None => self.err_ty(),
@@ -424,19 +434,23 @@ impl<'a> InferenceContext<'a> {
424 /// to do it as well. 434 /// to do it as well.
425 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 435 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
426 let ty = self.resolve_ty_as_possible(ty); 436 let ty = self.resolve_ty_as_possible(ty);
427 ty.fold(&mut |ty| match ty.interned(&Interner) { 437 fold_tys(
428 TyKind::Alias(AliasTy::Projection(proj_ty)) => { 438 ty,
429 self.normalize_projection_ty(proj_ty.clone()) 439 |ty, _| match ty.kind(&Interner) {
430 } 440 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
431 _ => ty, 441 self.normalize_projection_ty(proj_ty.clone())
432 }) 442 }
443 _ => ty,
444 },
445 DebruijnIndex::INNERMOST,
446 )
433 } 447 }
434 448
435 fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty { 449 fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {
436 let var = self.table.new_type_var(); 450 let var = self.table.new_type_var();
437 let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() }; 451 let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() };
438 let obligation = alias_eq.cast(&Interner); 452 let obligation = alias_eq.cast(&Interner);
439 self.obligations.push(obligation); 453 self.push_obligation(obligation);
440 var 454 var
441 } 455 }
442 456
@@ -458,56 +472,32 @@ impl<'a> InferenceContext<'a> {
458 TypeNs::AdtId(AdtId::StructId(strukt)) => { 472 TypeNs::AdtId(AdtId::StructId(strukt)) => {
459 let substs = ctx.substs_from_path(path, strukt.into(), true); 473 let substs = ctx.substs_from_path(path, strukt.into(), true);
460 let ty = self.db.ty(strukt.into()); 474 let ty = self.db.ty(strukt.into());
461 let ty = self.insert_type_vars(ty.subst(&substs)); 475 let ty = self.insert_type_vars(ty.substitute(&Interner, &substs));
462 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) 476 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
463 } 477 }
464 TypeNs::AdtId(AdtId::UnionId(u)) => { 478 TypeNs::AdtId(AdtId::UnionId(u)) => {
465 let substs = ctx.substs_from_path(path, u.into(), true); 479 let substs = ctx.substs_from_path(path, u.into(), true);
466 let ty = self.db.ty(u.into()); 480 let ty = self.db.ty(u.into());
467 let ty = self.insert_type_vars(ty.subst(&substs)); 481 let ty = self.insert_type_vars(ty.substitute(&Interner, &substs));
468 forbid_unresolved_segments((ty, Some(u.into())), unresolved) 482 forbid_unresolved_segments((ty, Some(u.into())), unresolved)
469 } 483 }
470 TypeNs::EnumVariantId(var) => { 484 TypeNs::EnumVariantId(var) => {
471 let substs = ctx.substs_from_path(path, var.into(), true); 485 let substs = ctx.substs_from_path(path, var.into(), true);
472 let ty = self.db.ty(var.parent.into()); 486 let ty = self.db.ty(var.parent.into());
473 let ty = self.insert_type_vars(ty.subst(&substs)); 487 let ty = self.insert_type_vars(ty.substitute(&Interner, &substs));
474 forbid_unresolved_segments((ty, Some(var.into())), unresolved) 488 forbid_unresolved_segments((ty, Some(var.into())), unresolved)
475 } 489 }
476 TypeNs::SelfType(impl_id) => { 490 TypeNs::SelfType(impl_id) => {
477 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 491 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
478 let substs = Substitution::type_params_for_generics(self.db, &generics); 492 let substs = generics.type_params_subst(self.db);
479 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 493 let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs);
480 match unresolved { 494 self.resolve_variant_on_alias(ty, unresolved, path)
481 None => {
482 let variant = ty_variant(&ty);
483 (ty, variant)
484 }
485 Some(1) => {
486 let segment = path.mod_path().segments().last().unwrap();
487 // this could be an enum variant or associated type
488 if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
489 let enum_data = self.db.enum_data(enum_id);
490 if let Some(local_id) = enum_data.variant(segment) {
491 let variant = EnumVariantId { parent: enum_id, local_id };
492 return (ty, Some(variant.into()));
493 }
494 }
495 // FIXME potentially resolve assoc type
496 (self.err_ty(), None)
497 }
498 Some(_) => {
499 // FIXME diagnostic
500 (self.err_ty(), None)
501 }
502 }
503 } 495 }
504 TypeNs::TypeAliasId(it) => { 496 TypeNs::TypeAliasId(it) => {
505 let substs = Substitution::build_for_def(self.db, it) 497 let ty = TyBuilder::def_ty(self.db, it.into())
506 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 498 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
507 .build(); 499 .build();
508 let ty = self.db.ty(it.into()).subst(&substs); 500 self.resolve_variant_on_alias(ty, unresolved, path)
509 let variant = ty_variant(&ty);
510 forbid_unresolved_segments((ty, variant), unresolved)
511 } 501 }
512 TypeNs::AdtSelfType(_) => { 502 TypeNs::AdtSelfType(_) => {
513 // FIXME this could happen in array size expressions, once we're checking them 503 // FIXME this could happen in array size expressions, once we're checking them
@@ -531,19 +521,46 @@ impl<'a> InferenceContext<'a> {
531 result 521 result
532 } else { 522 } else {
533 // FIXME diagnostic 523 // FIXME diagnostic
534 (TyKind::Unknown.intern(&Interner), None) 524 (TyKind::Error.intern(&Interner), None)
535 } 525 }
536 } 526 }
527 }
537 528
538 fn ty_variant(ty: &Ty) -> Option<VariantId> { 529 fn resolve_variant_on_alias(
539 ty.as_adt().and_then(|(adt_id, _)| match adt_id { 530 &mut self,
540 AdtId::StructId(s) => Some(VariantId::StructId(s)), 531 ty: Ty,
541 AdtId::UnionId(u) => Some(VariantId::UnionId(u)), 532 unresolved: Option<usize>,
542 AdtId::EnumId(_) => { 533 path: &Path,
543 // FIXME Error E0071, expected struct, variant or union type, found enum `Foo` 534 ) -> (Ty, Option<VariantId>) {
544 None 535 match unresolved {
536 None => {
537 let variant = ty.as_adt().and_then(|(adt_id, _)| match adt_id {
538 AdtId::StructId(s) => Some(VariantId::StructId(s)),
539 AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
540 AdtId::EnumId(_) => {
541 // FIXME Error E0071, expected struct, variant or union type, found enum `Foo`
542 None
543 }
544 });
545 (ty, variant)
546 }
547 Some(1) => {
548 let segment = path.mod_path().segments().last().unwrap();
549 // this could be an enum variant or associated type
550 if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
551 let enum_data = self.db.enum_data(enum_id);
552 if let Some(local_id) = enum_data.variant(segment) {
553 let variant = EnumVariantId { parent: enum_id, local_id };
554 return (ty, Some(variant.into()));
555 }
545 } 556 }
546 }) 557 // FIXME potentially resolve assoc type
558 (self.err_ty(), None)
559 }
560 Some(_) => {
561 // FIXME diagnostic
562 (self.err_ty(), None)
563 }
547 } 564 }
548 } 565 }
549 566
@@ -681,25 +698,6 @@ impl<'a> InferenceContext<'a> {
681 } 698 }
682} 699}
683 700
684/// The kinds of placeholders we need during type inference. There's separate
685/// values for general types, and for integer and float variables. The latter
686/// two are used for inference of literal values (e.g. `100` could be one of
687/// several integer types).
688#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
689pub struct InferenceVar {
690 index: u32,
691}
692
693impl InferenceVar {
694 fn to_inner(self) -> unify::TypeVarId {
695 unify::TypeVarId(self.index)
696 }
697
698 fn from_inner(unify::TypeVarId(index): unify::TypeVarId) -> Self {
699 InferenceVar { index }
700 }
701}
702
703/// When inferring an expression, we propagate downward whatever type hint we 701/// When inferring an expression, we propagate downward whatever type hint we
704/// are able in the form of an `Expectation`. 702/// are able in the form of an `Expectation`.
705#[derive(Clone, PartialEq, Eq, Debug)] 703#[derive(Clone, PartialEq, Eq, Debug)]
@@ -744,7 +742,7 @@ impl Expectation {
744 fn none() -> Self { 742 fn none() -> Self {
745 Expectation { 743 Expectation {
746 // FIXME 744 // FIXME
747 ty: TyKind::Unknown.intern(&Interner), 745 ty: TyKind::Error.intern(&Interner),
748 rvalue_hint: false, 746 rvalue_hint: false,
749 } 747 }
750 } 748 }
@@ -752,7 +750,7 @@ impl Expectation {
752 fn coercion_target(&self) -> Ty { 750 fn coercion_target(&self) -> Ty {
753 if self.rvalue_hint { 751 if self.rvalue_hint {
754 // FIXME 752 // FIXME
755 TyKind::Unknown.intern(&Interner) 753 TyKind::Error.intern(&Interner)
756 } else { 754 } else {
757 self.ty.clone() 755 self.ty.clone()
758 } 756 }
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 9c62932b1..1f463a425 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, Canonical, Interner, Solution, Ty, TyBuilder, TyExt, 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,17 +71,19 @@ 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.kind(&Interner), to_ty.kind(&Interner)) {
77 // `*mut T` -> `*const T` 75 // `*mut T` -> `*const T`
76 (TyKind::Raw(_, inner), TyKind::Raw(m2 @ Mutability::Not, ..)) => {
77 from_ty = TyKind::Raw(*m2, inner.clone()).intern(&Interner);
78 }
78 // `&mut T` -> `&T` 79 // `&mut T` -> `&T`
79 (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) 80 (TyKind::Ref(_, lt, inner), TyKind::Ref(m2 @ Mutability::Not, ..)) => {
80 | (TyKind::Ref(m1, ..), TyKind::Ref(m2 @ Mutability::Not, ..)) => { 81 from_ty = TyKind::Ref(*m2, lt.clone(), inner.clone()).intern(&Interner);
81 *m1 = *m2;
82 } 82 }
83 // `&T` -> `*const T` 83 // `&T` -> `*const T`
84 // `&mut T` -> `*mut T`/`*const T` 84 // `&mut T` -> `*mut T`/`*const T`
85 (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..)) 85 (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..))
86 | (TyKind::Ref(Mutability::Mut, substs), &TyKind::Raw(m2, ..)) => { 86 | (TyKind::Ref(Mutability::Mut, _, substs), &TyKind::Raw(m2, ..)) => {
87 from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner); 87 from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner);
88 } 88 }
89 89
@@ -95,12 +95,12 @@ impl<'a> InferenceContext<'a> {
95 (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) { 95 (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) {
96 None => return false, 96 None => return false,
97 Some(sig) => { 97 Some(sig) => {
98 from_ty = Ty::fn_ptr(sig); 98 from_ty = TyBuilder::fn_ptr(sig);
99 } 99 }
100 }, 100 },
101 101
102 (TyKind::Closure(.., substs), TyKind::Function { .. }) => { 102 (TyKind::Closure(.., substs), TyKind::Function { .. }) => {
103 from_ty = substs[0].clone(); 103 from_ty = substs.at(&Interner, 0).assert_ty_ref(&Interner).clone();
104 } 104 }
105 105
106 _ => {} 106 _ => {}
@@ -111,9 +111,11 @@ impl<'a> InferenceContext<'a> {
111 } 111 }
112 112
113 // Auto Deref if cannot coerce 113 // Auto Deref if cannot coerce
114 match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { 114 match (from_ty.kind(&Interner), to_ty.kind(&Interner)) {
115 // FIXME: DerefMut 115 // FIXME: DerefMut
116 (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => self.unify_autoderef_behind_ref(st1, st2), 116 (TyKind::Ref(.., st1), TyKind::Ref(.., st2)) => {
117 self.unify_autoderef_behind_ref(st1, st2)
118 }
117 119
118 // Otherwise, normal unify 120 // Otherwise, normal unify
119 _ => self.unify(&from_ty, to_ty), 121 _ => self.unify(&from_ty, to_ty),
@@ -130,19 +132,16 @@ impl<'a> InferenceContext<'a> {
130 _ => return None, 132 _ => return None,
131 }; 133 };
132 134
133 let generic_params = crate::utils::generics(self.db.upcast(), coerce_unsized_trait.into()); 135 let trait_ref = {
134 if generic_params.len() != 2 { 136 let b = TyBuilder::trait_ref(self.db, coerce_unsized_trait);
135 // The CoerceUnsized trait should have two generic params: Self and T. 137 if b.remaining() != 2 {
136 return None; 138 // The CoerceUnsized trait should have two generic params: Self and T.
137 } 139 return None;
140 }
141 b.push(from_ty.clone()).push(to_ty.clone()).build()
142 };
138 143
139 let substs = Substitution::build_for_generics(&generic_params) 144 let goal = InEnvironment::new(&self.trait_env.env, trait_ref.cast(&Interner));
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));
146 145
147 let canonicalizer = self.canonicalizer(); 146 let canonicalizer = self.canonicalizer();
148 let canonicalized = canonicalizer.canonicalize_obligation(goal); 147 let canonicalized = canonicalizer.canonicalize_obligation(goal);
@@ -151,7 +150,14 @@ impl<'a> InferenceContext<'a> {
151 150
152 match solution { 151 match solution {
153 Solution::Unique(v) => { 152 Solution::Unique(v) => {
154 canonicalized.apply_solution(self, v.0); 153 canonicalized.apply_solution(
154 self,
155 Canonical {
156 binders: v.binders,
157 // FIXME handle constraints
158 value: v.value.subst,
159 },
160 );
155 } 161 }
156 _ => return None, 162 _ => return None,
157 }; 163 };
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index e6ede05ca..50497eecb 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -3,7 +3,7 @@
3use std::iter::{repeat, repeat_with}; 3use std::iter::{repeat, repeat_with};
4use std::{mem, sync::Arc}; 4use std::{mem, sync::Arc};
5 5
6use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; 6use chalk_ir::{cast::Cast, fold::Shift, Mutability, TyVariableKind};
7use hir_def::{ 7use hir_def::{
8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
9 path::{GenericArg, GenericArgs}, 9 path::{GenericArg, GenericArgs},
@@ -15,15 +15,16 @@ use stdx::always;
15use syntax::ast::RangeOp; 15use syntax::ast::RangeOp;
16 16
17use crate::{ 17use crate::{
18 autoderef, 18 autoderef, dummy_usize_const,
19 lower::lower_to_chalk_mutability, 19 lower::lower_to_chalk_mutability,
20 mapping::from_chalk,
20 method_resolution, op, 21 method_resolution, op,
21 primitive::{self, UintTy}, 22 primitive::{self, UintTy},
22 to_assoc_type_id, to_chalk_trait_id, 23 static_lifetime, to_chalk_trait_id,
23 traits::{chalk::from_chalk, FnTrait, InEnvironment}, 24 traits::FnTrait,
24 utils::{generics, variant_data, Generics}, 25 utils::{generics, Generics},
25 AdtId, Binders, CallableDefId, DomainGoal, FnPointer, FnSig, Interner, Rawness, Scalar, 26 AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner,
26 Substitution, TraitRef, Ty, TyKind, 27 ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind,
27}; 28};
28 29
29use super::{ 30use super::{
@@ -73,38 +74,33 @@ impl<'a> InferenceContext<'a> {
73 let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?; 74 let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?;
74 let output_assoc_type = 75 let output_assoc_type =
75 self.db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?; 76 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 77
81 let mut param_builder = Substitution::builder(num_args);
82 let mut arg_tys = vec![]; 78 let mut arg_tys = vec![];
83 for _ in 0..num_args { 79 let arg_ty = TyBuilder::tuple(num_args)
84 let arg = self.table.new_type_var(); 80 .fill(repeat_with(|| {
85 param_builder = param_builder.push(arg.clone()); 81 let arg = self.table.new_type_var();
86 arg_tys.push(arg); 82 arg_tys.push(arg.clone());
87 } 83 arg
88 let parameters = param_builder.build(); 84 }))
89 let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner); 85 .build();
90 let substs = 86
91 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 87 let projection = {
88 let b = TyBuilder::assoc_type_projection(self.db, output_assoc_type);
89 if b.remaining() != 2 {
90 return None;
91 }
92 b.push(ty.clone()).push(arg_ty).build()
93 };
92 94
93 let trait_env = self.trait_env.env.clone(); 95 let trait_env = self.trait_env.env.clone();
94 let implements_fn_trait: DomainGoal = 96 let obligation = InEnvironment {
95 TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() } 97 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, 98 environment: trait_env,
100 }); 99 };
101 if self.db.trait_solve(krate, goal.value).is_some() { 100 let canonical = self.canonicalizer().canonicalize_obligation(obligation.clone());
102 self.obligations.push(implements_fn_trait); 101 if self.db.trait_solve(krate, canonical.value).is_some() {
103 let output_proj_ty = crate::ProjectionTy { 102 self.push_obligation(obligation.goal);
104 associated_ty_id: to_assoc_type_id(output_assoc_type), 103 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)) 104 Some((arg_tys, return_ty))
109 } else { 105 } else {
110 None 106 None
@@ -119,6 +115,8 @@ impl<'a> InferenceContext<'a> {
119 } 115 }
120 116
121 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 117 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
118 self.db.check_canceled();
119
122 let body = Arc::clone(&self.body); // avoid borrow checker problem 120 let body = Arc::clone(&self.body); // avoid borrow checker problem
123 let ty = match &body[tgt_expr] { 121 let ty = match &body[tgt_expr] {
124 Expr::Missing => self.err_ty(), 122 Expr::Missing => self.err_ty(),
@@ -136,7 +134,7 @@ impl<'a> InferenceContext<'a> {
136 both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe); 134 both_arms_diverge &= mem::replace(&mut self.diverges, Diverges::Maybe);
137 let else_ty = match else_branch { 135 let else_ty = match else_branch {
138 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected), 136 Some(else_branch) => self.infer_expr_inner(*else_branch, &expected),
139 None => Ty::unit(), 137 None => TyBuilder::unit(),
140 }; 138 };
141 both_arms_diverge &= self.diverges; 139 both_arms_diverge &= self.diverges;
142 140
@@ -183,7 +181,8 @@ impl<'a> InferenceContext<'a> {
183 let inner_ty = self.infer_expr(*body, &Expectation::none()); 181 let inner_ty = self.infer_expr(*body, &Expectation::none());
184 let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body); 182 let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body);
185 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into(); 183 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
186 TyKind::OpaqueType(opaque_ty_id, Substitution::single(inner_ty)).intern(&Interner) 184 TyKind::OpaqueType(opaque_ty_id, Substitution::from1(&Interner, inner_ty))
185 .intern(&Interner)
187 } 186 }
188 Expr::Loop { body, label } => { 187 Expr::Loop { body, label } => {
189 self.breakables.push(BreakableContext { 188 self.breakables.push(BreakableContext {
@@ -191,7 +190,7 @@ impl<'a> InferenceContext<'a> {
191 break_ty: self.table.new_type_var(), 190 break_ty: self.table.new_type_var(),
192 label: label.map(|label| self.body[label].name.clone()), 191 label: label.map(|label| self.body[label].name.clone()),
193 }); 192 });
194 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 193 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
195 194
196 let ctxt = self.breakables.pop().expect("breakable stack broken"); 195 let ctxt = self.breakables.pop().expect("breakable stack broken");
197 if ctxt.may_break { 196 if ctxt.may_break {
@@ -215,11 +214,11 @@ impl<'a> InferenceContext<'a> {
215 *condition, 214 *condition,
216 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), 215 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
217 ); 216 );
218 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 217 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
219 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 218 let _ctxt = self.breakables.pop().expect("breakable stack broken");
220 // the body may not run, so it diverging doesn't mean we diverge 219 // the body may not run, so it diverging doesn't mean we diverge
221 self.diverges = Diverges::Maybe; 220 self.diverges = Diverges::Maybe;
222 Ty::unit() 221 TyBuilder::unit()
223 } 222 }
224 Expr::For { iterable, body, pat, label } => { 223 Expr::For { iterable, body, pat, label } => {
225 let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); 224 let iterable_ty = self.infer_expr(*iterable, &Expectation::none());
@@ -234,11 +233,11 @@ impl<'a> InferenceContext<'a> {
234 233
235 self.infer_pat(*pat, &pat_ty, BindingMode::default()); 234 self.infer_pat(*pat, &pat_ty, BindingMode::default());
236 235
237 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 236 self.infer_expr(*body, &Expectation::has_type(TyBuilder::unit()));
238 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 237 let _ctxt = self.breakables.pop().expect("breakable stack broken");
239 // the body may not run, so it diverging doesn't mean we diverge 238 // the body may not run, so it diverging doesn't mean we diverge
240 self.diverges = Diverges::Maybe; 239 self.diverges = Diverges::Maybe;
241 Ty::unit() 240 TyBuilder::unit()
242 } 241 }
243 Expr::Lambda { body, args, ret_type, arg_types } => { 242 Expr::Lambda { body, args, ret_type, arg_types } => {
244 assert_eq!(args.len(), arg_types.len()); 243 assert_eq!(args.len(), arg_types.len());
@@ -262,14 +261,17 @@ impl<'a> InferenceContext<'a> {
262 }; 261 };
263 sig_tys.push(ret_ty.clone()); 262 sig_tys.push(ret_ty.clone());
264 let sig_ty = TyKind::Function(FnPointer { 263 let sig_ty = TyKind::Function(FnPointer {
265 num_args: sig_tys.len() - 1, 264 num_binders: 0,
266 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, 265 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
267 substs: Substitution(sig_tys.clone().into()), 266 substitution: FnSubst(
267 Substitution::from_iter(&Interner, sig_tys.clone()).shifted_in(&Interner),
268 ),
268 }) 269 })
269 .intern(&Interner); 270 .intern(&Interner);
270 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); 271 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
271 let closure_ty = 272 let closure_ty =
272 TyKind::Closure(closure_id, Substitution::single(sig_ty)).intern(&Interner); 273 TyKind::Closure(closure_id, Substitution::from1(&Interner, sig_ty))
274 .intern(&Interner);
273 275
274 // Eagerly try to relate the closure type with the expected 276 // Eagerly try to relate the closure type with the expected
275 // type, otherwise we often won't have enough information to 277 // type, otherwise we often won't have enough information to
@@ -316,7 +318,13 @@ impl<'a> InferenceContext<'a> {
316 self.normalize_associated_types_in(ret_ty) 318 self.normalize_associated_types_in(ret_ty)
317 } 319 }
318 Expr::MethodCall { receiver, args, method_name, generic_args } => self 320 Expr::MethodCall { receiver, args, method_name, generic_args } => self
319 .infer_method_call(tgt_expr, *receiver, &args, &method_name, generic_args.as_ref()), 321 .infer_method_call(
322 tgt_expr,
323 *receiver,
324 &args,
325 &method_name,
326 generic_args.as_deref(),
327 ),
320 Expr::Match { expr, arms } => { 328 Expr::Match { expr, arms } => {
321 let input_ty = self.infer_expr(*expr, &Expectation::none()); 329 let input_ty = self.infer_expr(*expr, &Expectation::none());
322 330
@@ -358,7 +366,7 @@ impl<'a> InferenceContext<'a> {
358 let val_ty = if let Some(expr) = expr { 366 let val_ty = if let Some(expr) = expr {
359 self.infer_expr(*expr, &Expectation::none()) 367 self.infer_expr(*expr, &Expectation::none())
360 } else { 368 } else {
361 Ty::unit() 369 TyBuilder::unit()
362 }; 370 };
363 371
364 let last_ty = 372 let last_ty =
@@ -384,7 +392,7 @@ impl<'a> InferenceContext<'a> {
384 if let Some(expr) = expr { 392 if let Some(expr) = expr {
385 self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone())); 393 self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone()));
386 } else { 394 } else {
387 let unit = Ty::unit(); 395 let unit = TyBuilder::unit();
388 self.coerce(&unit, &self.return_ty.clone()); 396 self.coerce(&unit, &self.return_ty.clone());
389 } 397 }
390 TyKind::Never.intern(&Interner) 398 TyKind::Never.intern(&Interner)
@@ -397,16 +405,19 @@ impl<'a> InferenceContext<'a> {
397 TyKind::Never.intern(&Interner) 405 TyKind::Never.intern(&Interner)
398 } 406 }
399 Expr::RecordLit { path, fields, spread } => { 407 Expr::RecordLit { path, fields, spread } => {
400 let (ty, def_id) = self.resolve_variant(path.as_ref()); 408 let (ty, def_id) = self.resolve_variant(path.as_deref());
401 if let Some(variant) = def_id { 409 if let Some(variant) = def_id {
402 self.write_variant_resolution(tgt_expr.into(), variant); 410 self.write_variant_resolution(tgt_expr.into(), variant);
403 } 411 }
404 412
405 self.unify(&ty, &expected.ty); 413 self.unify(&ty, &expected.ty);
406 414
407 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 415 let substs = ty
416 .as_adt()
417 .map(|(_, s)| s.clone())
418 .unwrap_or_else(|| Substitution::empty(&Interner));
408 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 419 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)); 420 let variant_data = def_id.map(|it| it.variant_data(self.db.upcast()));
410 for field in fields.iter() { 421 for field in fields.iter() {
411 let field_def = 422 let field_def =
412 variant_data.as_ref().and_then(|it| match it.field(&field.name) { 423 variant_data.as_ref().and_then(|it| match it.field(&field.name) {
@@ -418,11 +429,8 @@ impl<'a> InferenceContext<'a> {
418 None 429 None
419 } 430 }
420 }); 431 });
421 if let Some(field_def) = field_def {
422 self.result.record_field_resolutions.insert(field.expr, field_def);
423 }
424 let field_ty = field_def.map_or(self.err_ty(), |it| { 432 let field_ty = field_def.map_or(self.err_ty(), |it| {
425 field_types[it.local_id].clone().subst(&substs) 433 field_types[it.local_id].clone().substitute(&Interner, &substs)
426 }); 434 });
427 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 435 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
428 } 436 }
@@ -453,10 +461,14 @@ impl<'a> InferenceContext<'a> {
453 }) 461 })
454 .unwrap_or(true) 462 .unwrap_or(true)
455 }; 463 };
456 match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { 464 match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) {
457 TyKind::Tuple(_, substs) => { 465 TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| {
458 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) 466 substs
459 } 467 .as_slice(&Interner)
468 .get(idx)
469 .map(|a| a.assert_ty_ref(&Interner))
470 .cloned()
471 }),
460 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { 472 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
461 let local_id = self.db.struct_data(*s).variant_data.field(name)?; 473 let local_id = self.db.struct_data(*s).variant_data.field(name)?;
462 let field = FieldId { parent: (*s).into(), local_id }; 474 let field = FieldId { parent: (*s).into(), local_id };
@@ -465,7 +477,7 @@ impl<'a> InferenceContext<'a> {
465 Some( 477 Some(
466 self.db.field_types((*s).into())[field.local_id] 478 self.db.field_types((*s).into())[field.local_id]
467 .clone() 479 .clone()
468 .subst(&parameters), 480 .substitute(&Interner, &parameters),
469 ) 481 )
470 } else { 482 } else {
471 None 483 None
@@ -479,7 +491,7 @@ impl<'a> InferenceContext<'a> {
479 Some( 491 Some(
480 self.db.field_types((*u).into())[field.local_id] 492 self.db.field_types((*u).into())[field.local_id]
481 .clone() 493 .clone()
482 .subst(&parameters), 494 .substitute(&Interner, &parameters),
483 ) 495 )
484 } else { 496 } else {
485 None 497 None
@@ -526,24 +538,17 @@ impl<'a> InferenceContext<'a> {
526 let inner_ty = self.infer_expr_inner(*expr, &expectation); 538 let inner_ty = self.infer_expr_inner(*expr, &expectation);
527 match rawness { 539 match rawness {
528 Rawness::RawPtr => TyKind::Raw(mutability, inner_ty), 540 Rawness::RawPtr => TyKind::Raw(mutability, inner_ty),
529 Rawness::Ref => TyKind::Ref(mutability, inner_ty), 541 Rawness::Ref => TyKind::Ref(mutability, static_lifetime(), inner_ty),
530 } 542 }
531 .intern(&Interner) 543 .intern(&Interner)
532 } 544 }
533 Expr::Box { expr } => { 545 Expr::Box { expr } => {
534 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 546 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
535 if let Some(box_) = self.resolve_boxed_box() { 547 if let Some(box_) = self.resolve_boxed_box() {
536 let mut sb = 548 TyBuilder::adt(self.db, box_)
537 Substitution::build_for_generics(&generics(self.db.upcast(), box_.into())); 549 .push(inner_ty)
538 sb = sb.push(inner_ty); 550 .fill_with_defaults(self.db, || self.table.new_type_var())
539 match self.db.generic_defaults(box_.into()).get(1) { 551 .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 { 552 } else {
548 self.err_ty() 553 self.err_ty()
549 } 554 }
@@ -571,7 +576,7 @@ impl<'a> InferenceContext<'a> {
571 None => self.err_ty(), 576 None => self.err_ty(),
572 }, 577 },
573 UnaryOp::Neg => { 578 UnaryOp::Neg => {
574 match inner_ty.interned(&Interner) { 579 match inner_ty.kind(&Interner) {
575 // Fast path for builtins 580 // Fast path for builtins
576 TyKind::Scalar(Scalar::Int(_)) 581 TyKind::Scalar(Scalar::Int(_))
577 | TyKind::Scalar(Scalar::Uint(_)) 582 | TyKind::Scalar(Scalar::Uint(_))
@@ -584,7 +589,7 @@ impl<'a> InferenceContext<'a> {
584 } 589 }
585 } 590 }
586 UnaryOp::Not => { 591 UnaryOp::Not => {
587 match inner_ty.interned(&Interner) { 592 match inner_ty.kind(&Interner) {
588 // Fast path for builtins 593 // Fast path for builtins
589 TyKind::Scalar(Scalar::Bool) 594 TyKind::Scalar(Scalar::Bool)
590 | TyKind::Scalar(Scalar::Int(_)) 595 | TyKind::Scalar(Scalar::Int(_))
@@ -633,31 +638,31 @@ impl<'a> InferenceContext<'a> {
633 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 638 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
634 match (range_type, lhs_ty, rhs_ty) { 639 match (range_type, lhs_ty, rhs_ty) {
635 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 640 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
636 Some(adt) => Ty::adt_ty(adt, Substitution::empty()), 641 Some(adt) => TyBuilder::adt(self.db, adt).build(),
637 None => self.err_ty(), 642 None => self.err_ty(),
638 }, 643 },
639 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 644 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
640 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 645 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
641 None => self.err_ty(), 646 None => self.err_ty(),
642 }, 647 },
643 (RangeOp::Inclusive, None, Some(ty)) => { 648 (RangeOp::Inclusive, None, Some(ty)) => {
644 match self.resolve_range_to_inclusive() { 649 match self.resolve_range_to_inclusive() {
645 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 650 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
646 None => self.err_ty(), 651 None => self.err_ty(),
647 } 652 }
648 } 653 }
649 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 654 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
650 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 655 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
651 None => self.err_ty(), 656 None => self.err_ty(),
652 }, 657 },
653 (RangeOp::Inclusive, Some(_), Some(ty)) => { 658 (RangeOp::Inclusive, Some(_), Some(ty)) => {
654 match self.resolve_range_inclusive() { 659 match self.resolve_range_inclusive() {
655 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 660 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
656 None => self.err_ty(), 661 None => self.err_ty(),
657 } 662 }
658 } 663 }
659 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 664 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
660 Some(adt) => Ty::adt_ty(adt, Substitution::single(ty)), 665 Some(adt) => TyBuilder::adt(self.db, adt).push(ty).build(),
661 None => self.err_ty(), 666 None => self.err_ty(),
662 }, 667 },
663 (RangeOp::Inclusive, _, None) => self.err_ty(), 668 (RangeOp::Inclusive, _, None) => self.err_ty(),
@@ -690,10 +695,10 @@ impl<'a> InferenceContext<'a> {
690 } 695 }
691 } 696 }
692 Expr::Tuple { exprs } => { 697 Expr::Tuple { exprs } => {
693 let mut tys = match expected.ty.interned(&Interner) { 698 let mut tys = match expected.ty.kind(&Interner) {
694 TyKind::Tuple(_, substs) => substs 699 TyKind::Tuple(_, substs) => substs
695 .iter() 700 .iter(&Interner)
696 .cloned() 701 .map(|a| a.assert_ty_ref(&Interner).clone())
697 .chain(repeat_with(|| self.table.new_type_var())) 702 .chain(repeat_with(|| self.table.new_type_var()))
698 .take(exprs.len()) 703 .take(exprs.len())
699 .collect::<Vec<_>>(), 704 .collect::<Vec<_>>(),
@@ -704,11 +709,11 @@ impl<'a> InferenceContext<'a> {
704 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 709 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
705 } 710 }
706 711
707 TyKind::Tuple(tys.len(), Substitution(tys.into())).intern(&Interner) 712 TyKind::Tuple(tys.len(), Substitution::from_iter(&Interner, tys)).intern(&Interner)
708 } 713 }
709 Expr::Array(array) => { 714 Expr::Array(array) => {
710 let elem_ty = match expected.ty.interned(&Interner) { 715 let elem_ty = match expected.ty.kind(&Interner) {
711 TyKind::Array(st) | TyKind::Slice(st) => st.clone(), 716 TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(),
712 _ => self.table.new_type_var(), 717 _ => self.table.new_type_var(),
713 }; 718 };
714 719
@@ -732,17 +737,19 @@ impl<'a> InferenceContext<'a> {
732 } 737 }
733 } 738 }
734 739
735 TyKind::Array(elem_ty).intern(&Interner) 740 TyKind::Array(elem_ty, dummy_usize_const()).intern(&Interner)
736 } 741 }
737 Expr::Literal(lit) => match lit { 742 Expr::Literal(lit) => match lit {
738 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), 743 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
739 Literal::String(..) => { 744 Literal::String(..) => {
740 TyKind::Ref(Mutability::Not, TyKind::Str.intern(&Interner)).intern(&Interner) 745 TyKind::Ref(Mutability::Not, static_lifetime(), TyKind::Str.intern(&Interner))
746 .intern(&Interner)
741 } 747 }
742 Literal::ByteString(..) => { 748 Literal::ByteString(..) => {
743 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); 749 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner);
744 let array_type = TyKind::Array(byte_type).intern(&Interner); 750 let array_type =
745 TyKind::Ref(Mutability::Not, array_type).intern(&Interner) 751 TyKind::Array(byte_type, dummy_usize_const()).intern(&Interner);
752 TyKind::Ref(Mutability::Not, static_lifetime(), array_type).intern(&Interner)
746 } 753 }
747 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), 754 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner),
748 Literal::Int(_v, ty) => match ty { 755 Literal::Int(_v, ty) => match ty {
@@ -822,8 +829,8 @@ impl<'a> InferenceContext<'a> {
822 // we don't even make an attempt at coercion 829 // we don't even make an attempt at coercion
823 self.table.new_maybe_never_var() 830 self.table.new_maybe_never_var()
824 } else { 831 } else {
825 self.coerce(&Ty::unit(), &expected.coercion_target()); 832 self.coerce(&TyBuilder::unit(), &expected.coercion_target());
826 Ty::unit() 833 TyBuilder::unit()
827 } 834 }
828 }; 835 };
829 ty 836 ty
@@ -859,10 +866,10 @@ impl<'a> InferenceContext<'a> {
859 self.write_method_resolution(tgt_expr, func); 866 self.write_method_resolution(tgt_expr, func);
860 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) 867 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into())))
861 } 868 }
862 None => (receiver_ty, Binders::new(0, self.err_ty()), None), 869 None => (receiver_ty, Binders::empty(&Interner, self.err_ty()), None),
863 }; 870 };
864 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); 871 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty);
865 let method_ty = method_ty.subst(&substs); 872 let method_ty = method_ty.substitute(&Interner, &substs);
866 let method_ty = self.insert_type_vars(method_ty); 873 let method_ty = self.insert_type_vars(method_ty);
867 self.register_obligations_for_call(&method_ty); 874 self.register_obligations_for_call(&method_ty);
868 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) { 875 let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) {
@@ -878,7 +885,9 @@ impl<'a> InferenceContext<'a> {
878 // Apply autoref so the below unification works correctly 885 // Apply autoref so the below unification works correctly
879 // FIXME: return correct autorefs from lookup_method 886 // FIXME: return correct autorefs from lookup_method
880 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 887 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
881 Some((_, mutability)) => TyKind::Ref(mutability, derefed_receiver_ty).intern(&Interner), 888 Some((_, lifetime, mutability)) => {
889 TyKind::Ref(mutability, lifetime, derefed_receiver_ty).intern(&Interner)
890 }
882 _ => derefed_receiver_ty, 891 _ => derefed_receiver_ty,
883 }; 892 };
884 self.unify(&expected_receiver_ty, &actual_receiver_ty); 893 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -951,18 +960,20 @@ impl<'a> InferenceContext<'a> {
951 substs.push(self.err_ty()); 960 substs.push(self.err_ty());
952 } 961 }
953 assert_eq!(substs.len(), total_len); 962 assert_eq!(substs.len(), total_len);
954 Substitution(substs.into()) 963 Substitution::from_iter(&Interner, substs)
955 } 964 }
956 965
957 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 966 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
958 if let TyKind::FnDef(fn_def, parameters) = callable_ty.interned(&Interner) { 967 if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(&Interner) {
959 let def: CallableDefId = from_chalk(self.db, *fn_def); 968 let def: CallableDefId = from_chalk(self.db, *fn_def);
960 let generic_predicates = self.db.generic_predicates(def.into()); 969 let generic_predicates = self.db.generic_predicates(def.into());
961 for predicate in generic_predicates.iter() { 970 for predicate in generic_predicates.iter() {
962 let (predicate, binders) = 971 let (predicate, binders) = predicate
963 predicate.clone().subst(parameters).into_value_and_skipped_binders(); 972 .clone()
964 always!(binders == 0); // quantified where clauses not yet handled 973 .substitute(&Interner, parameters)
965 self.obligations.push(predicate.cast(&Interner)); 974 .into_value_and_skipped_binders();
975 always!(binders.len(&Interner) == 0); // quantified where clauses not yet handled
976 self.push_obligation(predicate.cast(&Interner));
966 } 977 }
967 // add obligation for trait implementation, if this is a trait method 978 // add obligation for trait implementation, if this is a trait method
968 match def { 979 match def {
@@ -970,9 +981,11 @@ impl<'a> InferenceContext<'a> {
970 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container 981 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
971 { 982 {
972 // construct a TraitRef 983 // construct a TraitRef
973 let substs = 984 let substs = crate::subst_prefix(
974 parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); 985 &*parameters,
975 self.obligations.push( 986 generics(self.db.upcast(), trait_.into()).len(),
987 );
988 self.push_obligation(
976 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs } 989 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }
977 .cast(&Interner), 990 .cast(&Interner),
978 ); 991 );
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 474363709..aea354cde 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -7,15 +7,13 @@ use chalk_ir::Mutability;
7use hir_def::{ 7use hir_def::{
8 expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat}, 8 expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat},
9 path::Path, 9 path::Path,
10 FieldId,
11}; 10};
12use hir_expand::name::Name; 11use hir_expand::name::Name;
13 12
14use super::{BindingMode, Expectation, InferenceContext}; 13use super::{BindingMode, Expectation, InferenceContext};
15use crate::{ 14use crate::{
16 lower::lower_to_chalk_mutability, 15 lower::lower_to_chalk_mutability, static_lifetime, Interner, Substitution, Ty, TyBuilder,
17 utils::{generics, variant_data}, 16 TyExt, TyKind,
18 Interner, Substitution, Ty, TyKind,
19}; 17};
20 18
21impl<'a> InferenceContext<'a> { 19impl<'a> InferenceContext<'a> {
@@ -29,13 +27,14 @@ impl<'a> InferenceContext<'a> {
29 ellipsis: Option<usize>, 27 ellipsis: Option<usize>,
30 ) -> Ty { 28 ) -> Ty {
31 let (ty, def) = self.resolve_variant(path); 29 let (ty, def) = self.resolve_variant(path);
32 let var_data = def.map(|it| variant_data(self.db.upcast(), it)); 30 let var_data = def.map(|it| it.variant_data(self.db.upcast()));
33 if let Some(variant) = def { 31 if let Some(variant) = def {
34 self.write_variant_resolution(id.into(), variant); 32 self.write_variant_resolution(id.into(), variant);
35 } 33 }
36 self.unify(&ty, expected); 34 self.unify(&ty, expected);
37 35
38 let substs = ty.substs().cloned().unwrap_or_else(Substitution::empty); 36 let substs =
37 ty.as_adt().map(|(_, s)| s.clone()).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 }
@@ -67,25 +68,22 @@ impl<'a> InferenceContext<'a> {
67 id: PatId, 68 id: PatId,
68 ) -> Ty { 69 ) -> Ty {
69 let (ty, def) = self.resolve_variant(path); 70 let (ty, def) = self.resolve_variant(path);
70 let var_data = def.map(|it| variant_data(self.db.upcast(), it)); 71 let var_data = def.map(|it| it.variant_data(self.db.upcast()));
71 if let Some(variant) = def { 72 if let Some(variant) = def {
72 self.write_variant_resolution(id.into(), variant); 73 self.write_variant_resolution(id.into(), variant);
73 } 74 }
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 =
79 ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(&Interner));
78 80
79 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 81 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
80 for subpat in subpats { 82 for subpat in subpats {
81 let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name)); 83 let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name));
82 if let Some(local_id) = matching_field { 84 let expected_ty = matching_field.map_or(self.err_ty(), |field| {
83 let field_def = FieldId { parent: def.unwrap(), local_id }; 85 field_tys[field].clone().substitute(&Interner, &substs)
84 self.result.record_pat_field_resolutions.insert(subpat.pat, field_def); 86 });
85 }
86
87 let expected_ty = matching_field
88 .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs));
89 let expected_ty = self.normalize_associated_types_in(expected_ty); 87 let expected_ty = self.normalize_associated_types_in(expected_ty);
90 self.infer_pat(subpat.pat, &expected_ty, default_bm); 88 self.infer_pat(subpat.pat, &expected_ty, default_bm);
91 } 89 }
@@ -102,7 +100,7 @@ impl<'a> InferenceContext<'a> {
102 let body = Arc::clone(&self.body); // avoid borrow checker problem 100 let body = Arc::clone(&self.body); // avoid borrow checker problem
103 101
104 if is_non_ref_pat(&body, pat) { 102 if is_non_ref_pat(&body, pat) {
105 while let Some((inner, mutability)) = expected.as_reference() { 103 while let Some((inner, _lifetime, mutability)) = expected.as_reference() {
106 expected = inner; 104 expected = inner;
107 default_bm = match default_bm { 105 default_bm = match default_bm {
108 BindingMode::Move => BindingMode::Ref(mutability), 106 BindingMode::Move => BindingMode::Ref(mutability),
@@ -124,7 +122,7 @@ impl<'a> InferenceContext<'a> {
124 let ty = match &body[pat] { 122 let ty = match &body[pat] {
125 &Pat::Tuple { ref args, ellipsis } => { 123 &Pat::Tuple { ref args, ellipsis } => {
126 let expectations = match expected.as_tuple() { 124 let expectations = match expected.as_tuple() {
127 Some(parameters) => &*parameters.0, 125 Some(parameters) => &*parameters.as_slice(&Interner),
128 _ => &[], 126 _ => &[],
129 }; 127 };
130 128
@@ -134,7 +132,8 @@ impl<'a> InferenceContext<'a> {
134 }; 132 };
135 let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); 133 let n_uncovered_patterns = expectations.len().saturating_sub(args.len());
136 let err_ty = self.err_ty(); 134 let err_ty = self.err_ty();
137 let mut expectations_iter = expectations.iter().chain(repeat(&err_ty)); 135 let mut expectations_iter =
136 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); 137 let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm);
139 138
140 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); 139 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len());
@@ -142,7 +141,8 @@ impl<'a> InferenceContext<'a> {
142 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); 141 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
143 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 142 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
144 143
145 TyKind::Tuple(inner_tys.len(), Substitution(inner_tys.into())).intern(&Interner) 144 TyKind::Tuple(inner_tys.len(), Substitution::from_iter(&Interner, inner_tys))
145 .intern(&Interner)
146 } 146 }
147 Pat::Or(ref pats) => { 147 Pat::Or(ref pats) => {
148 if let Some((first_pat, rest)) = pats.split_first() { 148 if let Some((first_pat, rest)) = pats.split_first() {
@@ -158,7 +158,7 @@ impl<'a> InferenceContext<'a> {
158 Pat::Ref { pat, mutability } => { 158 Pat::Ref { pat, mutability } => {
159 let mutability = lower_to_chalk_mutability(*mutability); 159 let mutability = lower_to_chalk_mutability(*mutability);
160 let expectation = match expected.as_reference() { 160 let expectation = match expected.as_reference() {
161 Some((inner_ty, exp_mut)) => { 161 Some((inner_ty, _lifetime, exp_mut)) => {
162 if mutability != exp_mut { 162 if mutability != exp_mut {
163 // FIXME: emit type error? 163 // FIXME: emit type error?
164 } 164 }
@@ -167,10 +167,10 @@ impl<'a> InferenceContext<'a> {
167 _ => self.result.standard_types.unknown.clone(), 167 _ => self.result.standard_types.unknown.clone(),
168 }; 168 };
169 let subty = self.infer_pat(*pat, &expectation, default_bm); 169 let subty = self.infer_pat(*pat, &expectation, default_bm);
170 TyKind::Ref(mutability, subty).intern(&Interner) 170 TyKind::Ref(mutability, static_lifetime(), subty).intern(&Interner)
171 } 171 }
172 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( 172 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat(
173 p.as_ref(), 173 p.as_deref(),
174 subpats, 174 subpats,
175 expected, 175 expected,
176 default_bm, 176 default_bm,
@@ -178,7 +178,7 @@ impl<'a> InferenceContext<'a> {
178 *ellipsis, 178 *ellipsis,
179 ), 179 ),
180 Pat::Record { path: p, args: fields, ellipsis: _ } => { 180 Pat::Record { path: p, args: fields, ellipsis: _ } => {
181 self.infer_record_pat(p.as_ref(), fields, expected, default_bm, pat) 181 self.infer_record_pat(p.as_deref(), fields, expected, default_bm, pat)
182 } 182 }
183 Pat::Path(path) => { 183 Pat::Path(path) => {
184 // FIXME use correct resolver for the surrounding expression 184 // FIXME use correct resolver for the surrounding expression
@@ -200,7 +200,8 @@ impl<'a> InferenceContext<'a> {
200 200
201 let bound_ty = match mode { 201 let bound_ty = match mode {
202 BindingMode::Ref(mutability) => { 202 BindingMode::Ref(mutability) => {
203 TyKind::Ref(mutability, inner_ty.clone()).intern(&Interner) 203 TyKind::Ref(mutability, static_lifetime(), inner_ty.clone())
204 .intern(&Interner)
204 } 205 }
205 BindingMode::Move => inner_ty.clone(), 206 BindingMode::Move => inner_ty.clone(),
206 }; 207 };
@@ -209,17 +210,20 @@ impl<'a> InferenceContext<'a> {
209 return inner_ty; 210 return inner_ty;
210 } 211 }
211 Pat::Slice { prefix, slice, suffix } => { 212 Pat::Slice { prefix, slice, suffix } => {
212 let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.interned(&Interner) { 213 let elem_ty = match expected.kind(&Interner) {
213 TyKind::Array(st) => (TyKind::Array, st.clone()), 214 TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(),
214 TyKind::Slice(st) => (TyKind::Slice, st.clone()), 215 _ => self.err_ty(),
215 _ => (TyKind::Slice, self.err_ty()),
216 }; 216 };
217 217
218 for pat_id in prefix.iter().chain(suffix) { 218 for pat_id in prefix.iter().chain(suffix) {
219 self.infer_pat(*pat_id, &elem_ty, default_bm); 219 self.infer_pat(*pat_id, &elem_ty, default_bm);
220 } 220 }
221 221
222 let pat_ty = container_ty(elem_ty).intern(&Interner); 222 let pat_ty = match expected.kind(&Interner) {
223 TyKind::Array(_, const_) => TyKind::Array(elem_ty, const_.clone()),
224 _ => TyKind::Slice(elem_ty),
225 }
226 .intern(&Interner);
223 if let Some(slice_pat_id) = slice { 227 if let Some(slice_pat_id) = slice {
224 self.infer_pat(*slice_pat_id, &pat_ty, default_bm); 228 self.infer_pat(*slice_pat_id, &pat_ty, default_bm);
225 } 229 }
@@ -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.as_slice(&Interner).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..495282eba 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -11,7 +11,8 @@ use hir_def::{
11use hir_expand::name::Name; 11use hir_expand::name::Name;
12 12
13use crate::{ 13use crate::{
14 method_resolution, to_chalk_trait_id, Interner, Substitution, Ty, TyKind, ValueTyDefId, 14 method_resolution, Interner, Substitution, TraitRefExt, Ty, TyBuilder, TyExt, TyKind,
15 ValueTyDefId,
15}; 16};
16 17
17use super::{ExprOrPatId, InferenceContext, TraitRef}; 18use super::{ExprOrPatId, InferenceContext, TraitRef};
@@ -82,10 +83,10 @@ impl<'a> InferenceContext<'a> {
82 } 83 }
83 ValueNs::ImplSelf(impl_id) => { 84 ValueNs::ImplSelf(impl_id) => {
84 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 85 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
85 let substs = Substitution::type_params_for_generics(self.db, &generics); 86 let substs = generics.type_params_subst(self.db);
86 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 87 let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs);
87 if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() { 88 if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() {
88 let ty = self.db.value_ty(struct_id.into()).subst(&substs); 89 let ty = self.db.value_ty(struct_id.into()).substitute(&Interner, &substs);
89 return Some(ty); 90 return Some(ty);
90 } else { 91 } else {
91 // FIXME: diagnostic, invalid Self reference 92 // FIXME: diagnostic, invalid Self reference
@@ -95,16 +96,13 @@ impl<'a> InferenceContext<'a> {
95 ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)), 96 ValueNs::GenericParam(it) => return Some(self.db.const_param_ty(it)),
96 }; 97 };
97 98
98 let ty = self.db.value_ty(typable); 99 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); 100 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
102 let substs = ctx.substs_from_path(path, typable, true); 101 let substs = ctx.substs_from_path(path, typable, true);
103 let full_substs = Substitution::builder(substs.len()) 102 let ty = TyBuilder::value_ty(self.db, typable)
104 .use_parent_substs(&parent_substs) 103 .use_parent_substs(&parent_substs)
105 .fill(substs.0[parent_substs.len()..].iter().cloned()) 104 .fill(substs.as_slice(&Interner)[parent_substs.len(&Interner)..].iter().cloned())
106 .build(); 105 .build();
107 let ty = ty.subst(&full_substs);
108 Some(ty) 106 Some(ty)
109 } 107 }
110 108
@@ -147,7 +145,7 @@ impl<'a> InferenceContext<'a> {
147 remaining_segments_for_ty, 145 remaining_segments_for_ty,
148 true, 146 true,
149 ); 147 );
150 if let TyKind::Unknown = ty.interned(&Interner) { 148 if let TyKind::Error = ty.kind(&Interner) {
151 return None; 149 return None;
152 } 150 }
153 151
@@ -212,7 +210,7 @@ impl<'a> InferenceContext<'a> {
212 name: &Name, 210 name: &Name,
213 id: ExprOrPatId, 211 id: ExprOrPatId,
214 ) -> Option<(ValueNs, Option<Substitution>)> { 212 ) -> Option<(ValueNs, Option<Substitution>)> {
215 if let TyKind::Unknown = ty.interned(&Interner) { 213 if let TyKind::Error = ty.kind(&Interner) {
216 return None; 214 return None;
217 } 215 }
218 216
@@ -245,27 +243,22 @@ impl<'a> InferenceContext<'a> {
245 }; 243 };
246 let substs = match container { 244 let substs = match container {
247 AssocContainerId::ImplId(impl_id) => { 245 AssocContainerId::ImplId(impl_id) => {
248 let impl_substs = Substitution::build_for_def(self.db, impl_id) 246 let impl_substs = TyBuilder::subst_for_def(self.db, impl_id)
249 .fill(iter::repeat_with(|| self.table.new_type_var())) 247 .fill(iter::repeat_with(|| self.table.new_type_var()))
250 .build(); 248 .build();
251 let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs); 249 let impl_self_ty =
250 self.db.impl_self_ty(impl_id).substitute(&Interner, &impl_substs);
252 self.unify(&impl_self_ty, &ty); 251 self.unify(&impl_self_ty, &ty);
253 Some(impl_substs) 252 Some(impl_substs)
254 } 253 }
255 AssocContainerId::TraitId(trait_) => { 254 AssocContainerId::TraitId(trait_) => {
256 // we're picking this method 255 // we're picking this method
257 let trait_substs = Substitution::build_for_def(self.db, trait_) 256 let trait_ref = TyBuilder::trait_ref(self.db, trait_)
258 .push(ty.clone()) 257 .push(ty.clone())
259 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 258 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
260 .build(); 259 .build();
261 self.obligations.push( 260 self.push_obligation(trait_ref.clone().cast(&Interner));
262 TraitRef { 261 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 } 262 }
270 AssocContainerId::ModuleId(_) => None, 263 AssocContainerId::ModuleId(_) => None,
271 }; 264 };
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 6e7b0f5a6..a887e20b0 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -2,13 +2,17 @@
2 2
3use std::borrow::Cow; 3use std::borrow::Cow;
4 4
5use chalk_ir::{FloatTy, IntTy, TyVariableKind, UniverseIndex, VariableKind}; 5use chalk_ir::{
6 cast::Cast, fold::Fold, interner::HasInterner, FloatTy, IntTy, TyVariableKind, UniverseIndex,
7 VariableKind,
8};
6use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; 9use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
7 10
8use super::{DomainGoal, InferenceContext}; 11use super::{DomainGoal, InferenceContext};
9use crate::{ 12use crate::{
10 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, 13 fold_tys, static_lifetime, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds,
11 InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause, 14 DebruijnIndex, FnPointer, FnSubst, InEnvironment, InferenceVar, Interner, Scalar, Substitution,
15 Ty, TyExt, TyKind, WhereClause,
12}; 16};
13 17
14impl<'a> InferenceContext<'a> { 18impl<'a> InferenceContext<'a> {
@@ -33,7 +37,10 @@ where
33} 37}
34 38
35#[derive(Debug)] 39#[derive(Debug)]
36pub(super) struct Canonicalized<T> { 40pub(super) struct Canonicalized<T>
41where
42 T: HasInterner<Interner = Interner>,
43{
37 pub(super) value: Canonical<T>, 44 pub(super) value: Canonical<T>,
38 free_vars: Vec<(InferenceVar, TyVariableKind)>, 45 free_vars: Vec<(InferenceVar, TyVariableKind)>,
39} 46}
@@ -47,11 +54,16 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
47 }) 54 })
48 } 55 }
49 56
50 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { 57 fn do_canonicalize<T: Fold<Interner, Result = T> + HasInterner<Interner = Interner>>(
51 t.fold_binders( 58 &mut self,
52 &mut |ty, binders| match ty.interned(&Interner) { 59 t: T,
60 binders: DebruijnIndex,
61 ) -> T {
62 fold_tys(
63 t,
64 |ty, binders| match ty.kind(&Interner) {
53 &TyKind::InferenceVar(var, kind) => { 65 &TyKind::InferenceVar(var, kind) => {
54 let inner = var.to_inner(); 66 let inner = from_inference_var(var);
55 if self.var_stack.contains(&inner) { 67 if self.var_stack.contains(&inner) {
56 // recursive type 68 // recursive type
57 return self.ctx.table.type_variable_table.fallback_value(var, kind); 69 return self.ctx.table.type_variable_table.fallback_value(var, kind);
@@ -65,7 +77,7 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
65 result 77 result
66 } else { 78 } else {
67 let root = self.ctx.table.var_unification_table.find(inner); 79 let root = self.ctx.table.var_unification_table.find(inner);
68 let position = self.add(InferenceVar::from_inner(root), kind); 80 let position = self.add(to_inference_var(root), kind);
69 TyKind::BoundVar(BoundVar::new(binders, position)).intern(&Interner) 81 TyKind::BoundVar(BoundVar::new(binders, position)).intern(&Interner)
70 } 82 }
71 } 83 }
@@ -75,7 +87,10 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
75 ) 87 )
76 } 88 }
77 89
78 fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { 90 fn into_canonicalized<T: HasInterner<Interner = Interner>>(
91 self,
92 result: T,
93 ) -> Canonicalized<T> {
79 let kinds = self 94 let kinds = self
80 .free_vars 95 .free_vars
81 .iter() 96 .iter()
@@ -102,25 +117,18 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
102 DomainGoal::Holds(wc) => { 117 DomainGoal::Holds(wc) => {
103 DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST)) 118 DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST))
104 } 119 }
120 _ => unimplemented!(),
105 }; 121 };
106 self.into_canonicalized(InEnvironment { goal: result, environment: obligation.environment }) 122 self.into_canonicalized(InEnvironment { goal: result, environment: obligation.environment })
107 } 123 }
108} 124}
109 125
110impl<T> Canonicalized<T> { 126impl<T: HasInterner<Interner = Interner>> Canonicalized<T> {
111 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { 127 pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty {
112 ty.walk_mut_binders( 128 crate::fold_free_vars(ty, |bound, _binders| {
113 &mut |ty, binders| { 129 let (v, k) = self.free_vars[bound.index];
114 if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { 130 TyKind::InferenceVar(v, k).intern(&Interner)
115 if bound.debruijn >= binders { 131 })
116 let (v, k) = self.free_vars[bound.index];
117 *ty = TyKind::InferenceVar(v, k).intern(&Interner);
118 }
119 }
120 },
121 DebruijnIndex::INNERMOST,
122 );
123 ty
124 } 132 }
125 133
126 pub(super) fn apply_solution( 134 pub(super) fn apply_solution(
@@ -129,29 +137,30 @@ impl<T> Canonicalized<T> {
129 solution: Canonical<Substitution>, 137 solution: Canonical<Substitution>,
130 ) { 138 ) {
131 // the solution may contain new variables, which we need to convert to new inference vars 139 // the solution may contain new variables, which we need to convert to new inference vars
132 let new_vars = Substitution( 140 let new_vars = Substitution::from_iter(
133 solution 141 &Interner,
134 .binders 142 solution.binders.iter(&Interner).map(|k| match k.kind {
135 .iter(&Interner) 143 VariableKind::Ty(TyVariableKind::General) => {
136 .map(|k| match k.kind { 144 ctx.table.new_type_var().cast(&Interner)
137 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(), 145 }
138 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(), 146 VariableKind::Ty(TyVariableKind::Integer) => {
139 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(), 147 ctx.table.new_integer_var().cast(&Interner)
140 // HACK: Chalk can sometimes return new lifetime variables. We 148 }
141 // want to just skip them, but to not mess up the indices of 149 VariableKind::Ty(TyVariableKind::Float) => {
142 // other variables, we'll just create a new type variable in 150 ctx.table.new_float_var().cast(&Interner)
143 // their place instead. This should not matter (we never see the 151 }
144 // actual *uses* of the lifetime variable). 152 // Chalk can sometimes return new lifetime variables. We just use the static lifetime everywhere
145 VariableKind::Lifetime => ctx.table.new_type_var(), 153 VariableKind::Lifetime => static_lifetime().cast(&Interner),
146 _ => panic!("const variable in solution"), 154 _ => panic!("const variable in solution"),
147 }) 155 }),
148 .collect(),
149 ); 156 );
150 for (i, ty) in solution.value.into_iter().enumerate() { 157 for (i, ty) in solution.value.iter(&Interner).enumerate() {
151 let (v, k) = self.free_vars[i]; 158 let (v, k) = self.free_vars[i];
152 // eagerly replace projections in the type; we may be getting types 159 // eagerly replace projections in the type; we may be getting types
153 // e.g. from where clauses where this hasn't happened yet 160 // 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)); 161 let ty = ctx.normalize_associated_types_in(
162 new_vars.apply(ty.assert_ty_ref(&Interner).clone(), &Interner),
163 );
155 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); 164 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty);
156 } 165 }
157 } 166 }
@@ -163,22 +172,23 @@ pub fn could_unify(t1: &Ty, t2: &Ty) -> bool {
163 172
164pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> { 173pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
165 let mut table = InferenceTable::new(); 174 let mut table = InferenceTable::new();
166 let vars = Substitution( 175 let vars = Substitution::from_iter(
176 &Interner,
167 tys.binders 177 tys.binders
168 .iter(&Interner) 178 .iter(&Interner)
169 // we always use type vars here because we want everything to 179 // we always use type vars here because we want everything to
170 // fallback to Unknown in the end (kind of hacky, as below) 180 // fallback to Unknown in the end (kind of hacky, as below)
171 .map(|_| table.new_type_var()) 181 .map(|_| table.new_type_var()),
172 .collect(),
173 ); 182 );
174 let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars); 183 let ty1_with_vars = vars.apply(tys.value.0.clone(), &Interner);
175 let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars); 184 let ty2_with_vars = vars.apply(tys.value.1.clone(), &Interner);
176 if !table.unify(&ty1_with_vars, &ty2_with_vars) { 185 if !table.unify(&ty1_with_vars, &ty2_with_vars) {
177 return None; 186 return None;
178 } 187 }
179 // default any type vars that weren't unified back to their original bound vars 188 // default any type vars that weren't unified back to their original bound vars
180 // (kind of hacky) 189 // (kind of hacky)
181 for (i, var) in vars.iter().enumerate() { 190 for (i, var) in vars.iter(&Interner).enumerate() {
191 let var = var.assert_ty_ref(&Interner);
182 if &*table.resolve_ty_shallow(var) == var { 192 if &*table.resolve_ty_shallow(var) == var {
183 table.unify( 193 table.unify(
184 var, 194 var,
@@ -186,11 +196,11 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
186 ); 196 );
187 } 197 }
188 } 198 }
189 Some( 199 Some(Substitution::from_iter(
190 Substitution::builder(tys.binders.len(&Interner)) 200 &Interner,
191 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) 201 vars.iter(&Interner)
192 .build(), 202 .map(|v| table.resolve_ty_completely(v.assert_ty_ref(&Interner).clone())),
193 ) 203 ))
194} 204}
195 205
196#[derive(Clone, Debug)] 206#[derive(Clone, Debug)]
@@ -204,17 +214,17 @@ impl TypeVariableTable {
204 } 214 }
205 215
206 pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) { 216 pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) {
207 self.inner[iv.to_inner().0 as usize].diverging = diverging; 217 self.inner[from_inference_var(iv).0 as usize].diverging = diverging;
208 } 218 }
209 219
210 fn is_diverging(&mut self, iv: InferenceVar) -> bool { 220 fn is_diverging(&mut self, iv: InferenceVar) -> bool {
211 self.inner[iv.to_inner().0 as usize].diverging 221 self.inner[from_inference_var(iv).0 as usize].diverging
212 } 222 }
213 223
214 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { 224 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
215 match kind { 225 match kind {
216 _ if self.inner[iv.to_inner().0 as usize].diverging => TyKind::Never, 226 _ if self.inner[from_inference_var(iv).0 as usize].diverging => TyKind::Never,
217 TyVariableKind::General => TyKind::Unknown, 227 TyVariableKind::General => TyKind::Error,
218 TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)), 228 TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)),
219 TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)), 229 TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)),
220 } 230 }
@@ -231,6 +241,7 @@ pub(crate) struct TypeVariableData {
231pub(crate) struct InferenceTable { 241pub(crate) struct InferenceTable {
232 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>, 242 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>,
233 pub(super) type_variable_table: TypeVariableTable, 243 pub(super) type_variable_table: TypeVariableTable,
244 pub(super) revision: u32,
234} 245}
235 246
236impl InferenceTable { 247impl InferenceTable {
@@ -238,6 +249,7 @@ impl InferenceTable {
238 InferenceTable { 249 InferenceTable {
239 var_unification_table: InPlaceUnificationTable::new(), 250 var_unification_table: InPlaceUnificationTable::new(),
240 type_variable_table: TypeVariableTable { inner: Vec::new() }, 251 type_variable_table: TypeVariableTable { inner: Vec::new() },
252 revision: 0,
241 } 253 }
242 } 254 }
243 255
@@ -245,7 +257,7 @@ impl InferenceTable {
245 self.type_variable_table.push(TypeVariableData { diverging }); 257 self.type_variable_table.push(TypeVariableData { diverging });
246 let key = self.var_unification_table.new_key(TypeVarValue::Unknown); 258 let key = self.var_unification_table.new_key(TypeVarValue::Unknown);
247 assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); 259 assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1);
248 TyKind::InferenceVar(InferenceVar::from_inner(key), kind).intern(&Interner) 260 TyKind::InferenceVar(to_inference_var(key), kind).intern(&Interner)
249 } 261 }
250 262
251 pub(crate) fn new_type_var(&mut self) -> Ty { 263 pub(crate) fn new_type_var(&mut self) -> Ty {
@@ -282,7 +294,9 @@ impl InferenceTable {
282 substs2: &Substitution, 294 substs2: &Substitution,
283 depth: usize, 295 depth: usize,
284 ) -> bool { 296 ) -> bool {
285 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) 297 substs1.iter(&Interner).zip(substs2.iter(&Interner)).all(|(t1, t2)| {
298 self.unify_inner(t1.assert_ty_ref(&Interner), t2.assert_ty_ref(&Interner), depth)
299 })
286 } 300 }
287 301
288 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 302 fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
@@ -297,12 +311,12 @@ impl InferenceTable {
297 let ty1 = self.resolve_ty_shallow(ty1); 311 let ty1 = self.resolve_ty_shallow(ty1);
298 let ty2 = self.resolve_ty_shallow(ty2); 312 let ty2 = self.resolve_ty_shallow(ty2);
299 if ty1.equals_ctor(&ty2) { 313 if ty1.equals_ctor(&ty2) {
300 match (ty1.interned(&Interner), ty2.interned(&Interner)) { 314 match (ty1.kind(&Interner), ty2.kind(&Interner)) {
301 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) 315 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2))
302 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) 316 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2))
303 | ( 317 | (
304 TyKind::Function(FnPointer { substs: substs1, .. }), 318 TyKind::Function(FnPointer { substitution: FnSubst(substs1), .. }),
305 TyKind::Function(FnPointer { substs: substs2, .. }), 319 TyKind::Function(FnPointer { substitution: FnSubst(substs2), .. }),
306 ) 320 )
307 | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2)) 321 | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2))
308 | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2)) 322 | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2))
@@ -310,9 +324,11 @@ impl InferenceTable {
310 | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => { 324 | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => {
311 self.unify_substs(substs1, substs2, depth + 1) 325 self.unify_substs(substs1, substs2, depth + 1)
312 } 326 }
313 (TyKind::Ref(_, ty1), TyKind::Ref(_, ty2)) 327 (TyKind::Array(ty1, c1), TyKind::Array(ty2, c2)) if c1 == c2 => {
328 self.unify_inner(ty1, ty2, depth + 1)
329 }
330 (TyKind::Ref(_, _, ty1), TyKind::Ref(_, _, ty2))
314 | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2)) 331 | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2))
315 | (TyKind::Array(ty1), TyKind::Array(ty2))
316 | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1), 332 | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1),
317 _ => true, /* we checked equals_ctor already */ 333 _ => true, /* we checked equals_ctor already */
318 } 334 }
@@ -322,8 +338,8 @@ impl InferenceTable {
322 } 338 }
323 339
324 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 340 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
325 match (ty1.interned(&Interner), ty2.interned(&Interner)) { 341 match (ty1.kind(&Interner), ty2.kind(&Interner)) {
326 (TyKind::Unknown, _) | (_, TyKind::Unknown) => true, 342 (TyKind::Error, _) | (_, TyKind::Error) => true,
327 343
328 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, 344 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true,
329 345
@@ -360,7 +376,14 @@ impl InferenceTable {
360 == self.type_variable_table.is_diverging(*tv2) => 376 == self.type_variable_table.is_diverging(*tv2) =>
361 { 377 {
362 // both type vars are unknown since we tried to resolve them 378 // both type vars are unknown since we tried to resolve them
363 self.var_unification_table.union(tv1.to_inner(), tv2.to_inner()); 379 if !self
380 .var_unification_table
381 .unioned(from_inference_var(*tv1), from_inference_var(*tv2))
382 {
383 self.var_unification_table
384 .union(from_inference_var(*tv1), from_inference_var(*tv2));
385 self.revision += 1;
386 }
364 true 387 true
365 } 388 }
366 389
@@ -395,9 +418,10 @@ impl InferenceTable {
395 ) => { 418 ) => {
396 // the type var is unknown since we tried to resolve it 419 // the type var is unknown since we tried to resolve it
397 self.var_unification_table.union_value( 420 self.var_unification_table.union_value(
398 tv.to_inner(), 421 from_inference_var(*tv),
399 TypeVarValue::Known(other.clone().intern(&Interner)), 422 TypeVarValue::Known(other.clone().intern(&Interner)),
400 ); 423 );
424 self.revision += 1;
401 true 425 true
402 } 426 }
403 427
@@ -447,9 +471,9 @@ impl InferenceTable {
447 if i > 0 { 471 if i > 0 {
448 cov_mark::hit!(type_var_resolves_to_int_var); 472 cov_mark::hit!(type_var_resolves_to_int_var);
449 } 473 }
450 match ty.interned(&Interner) { 474 match ty.kind(&Interner) {
451 TyKind::InferenceVar(tv, _) => { 475 TyKind::InferenceVar(tv, _) => {
452 let inner = tv.to_inner(); 476 let inner = from_inference_var(*tv);
453 match self.var_unification_table.inlined_probe_value(inner).known() { 477 match self.var_unification_table.inlined_probe_value(inner).known() {
454 Some(known_ty) => { 478 Some(known_ty) => {
455 // The known_ty can't be a type var itself 479 // The known_ty can't be a type var itself
@@ -470,55 +494,63 @@ impl InferenceTable {
470 /// be resolved as far as possible, i.e. contain no type variables with 494 /// be resolved as far as possible, i.e. contain no type variables with
471 /// known type. 495 /// known type.
472 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 496 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) { 497 fold_tys(
474 &TyKind::InferenceVar(tv, kind) => { 498 ty,
475 let inner = tv.to_inner(); 499 |ty, _| match ty.kind(&Interner) {
476 if tv_stack.contains(&inner) { 500 &TyKind::InferenceVar(tv, kind) => {
477 cov_mark::hit!(type_var_cycles_resolve_as_possible); 501 let inner = from_inference_var(tv);
478 // recursive type 502 if tv_stack.contains(&inner) {
479 return self.type_variable_table.fallback_value(tv, kind); 503 cov_mark::hit!(type_var_cycles_resolve_as_possible);
480 } 504 // recursive type
481 if let Some(known_ty) = 505 return self.type_variable_table.fallback_value(tv, kind);
482 self.var_unification_table.inlined_probe_value(inner).known() 506 }
483 { 507 if let Some(known_ty) =
484 // known_ty may contain other variables that are known by now 508 self.var_unification_table.inlined_probe_value(inner).known()
485 tv_stack.push(inner); 509 {
486 let result = self.resolve_ty_as_possible_inner(tv_stack, known_ty.clone()); 510 // known_ty may contain other variables that are known by now
487 tv_stack.pop(); 511 tv_stack.push(inner);
488 result 512 let result = self.resolve_ty_as_possible_inner(tv_stack, known_ty.clone());
489 } else { 513 tv_stack.pop();
490 ty 514 result
515 } else {
516 ty
517 }
491 } 518 }
492 } 519 _ => ty,
493 _ => ty, 520 },
494 }) 521 DebruijnIndex::INNERMOST,
522 )
495 } 523 }
496 524
497 /// Resolves the type completely; type variables without known type are 525 /// Resolves the type completely; type variables without known type are
498 /// replaced by TyKind::Unknown. 526 /// replaced by TyKind::Unknown.
499 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 527 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
500 ty.fold(&mut |ty| match ty.interned(&Interner) { 528 fold_tys(
501 &TyKind::InferenceVar(tv, kind) => { 529 ty,
502 let inner = tv.to_inner(); 530 |ty, _| match ty.kind(&Interner) {
503 if tv_stack.contains(&inner) { 531 &TyKind::InferenceVar(tv, kind) => {
504 cov_mark::hit!(type_var_cycles_resolve_completely); 532 let inner = from_inference_var(tv);
505 // recursive type 533 if tv_stack.contains(&inner) {
506 return self.type_variable_table.fallback_value(tv, kind); 534 cov_mark::hit!(type_var_cycles_resolve_completely);
507 } 535 // recursive type
508 if let Some(known_ty) = 536 return self.type_variable_table.fallback_value(tv, kind);
509 self.var_unification_table.inlined_probe_value(inner).known() 537 }
510 { 538 if let Some(known_ty) =
511 // known_ty may contain other variables that are known by now 539 self.var_unification_table.inlined_probe_value(inner).known()
512 tv_stack.push(inner); 540 {
513 let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone()); 541 // known_ty may contain other variables that are known by now
514 tv_stack.pop(); 542 tv_stack.push(inner);
515 result 543 let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone());
516 } else { 544 tv_stack.pop();
517 self.type_variable_table.fallback_value(tv, kind) 545 result
546 } else {
547 self.type_variable_table.fallback_value(tv, kind)
548 }
518 } 549 }
519 } 550 _ => ty,
520 _ => ty, 551 },
521 }) 552 DebruijnIndex::INNERMOST,
553 )
522 } 554 }
523} 555}
524 556
@@ -542,6 +574,14 @@ impl UnifyKey for TypeVarId {
542 } 574 }
543} 575}
544 576
577fn from_inference_var(var: InferenceVar) -> TypeVarId {
578 TypeVarId(var.index())
579}
580
581fn to_inference_var(TypeVarId(index): TypeVarId) -> InferenceVar {
582 index.into()
583}
584
545/// The value of a type variable: either we already know the type, or we don't 585/// The value of a type variable: either we already know the type, or we don't
546/// know it yet. 586/// know it yet.
547#[derive(Clone, PartialEq, Eq, Debug)] 587#[derive(Clone, PartialEq, Eq, Debug)]
diff --git a/crates/hir_ty/src/traits/chalk/interner.rs b/crates/hir_ty/src/interner.rs
index 94e94a26d..a1656115d 100644
--- a/crates/hir_ty/src/traits/chalk/interner.rs
+++ b/crates/hir_ty/src/interner.rs
@@ -1,61 +1,83 @@
1//! Implementation of the Chalk `Interner` trait, which allows customizing the 1//! Implementation of the Chalk `Interner` trait, which allows customizing the
2//! representation of the various objects Chalk deals with (types, goals etc.). 2//! representation of the various objects Chalk deals with (types, goals etc.).
3 3
4use super::tls; 4use crate::{chalk_db, tls, GenericArg};
5use base_db::salsa::InternId; 5use base_db::salsa::InternId;
6use chalk_ir::{GenericArg, Goal, GoalData}; 6use chalk_ir::{Goal, GoalData};
7use hir_def::TypeAliasId; 7use hir_def::{
8 intern::{impl_internable, InternStorage, Internable, Interned},
9 TypeAliasId,
10};
8use smallvec::SmallVec; 11use smallvec::SmallVec;
9use std::{fmt, sync::Arc}; 12use std::{fmt, sync::Arc};
10 13
11#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] 14#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
12pub struct Interner; 15pub struct Interner;
13 16
14pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>; 17#[derive(PartialEq, Eq, Hash, Debug)]
15pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>; 18pub struct InternedWrapper<T>(T);
16pub(crate) type TraitId = chalk_ir::TraitId<Interner>; 19
17pub(crate) type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>; 20impl<T> std::ops::Deref for InternedWrapper<T> {
18pub(crate) type AdtId = chalk_ir::AdtId<Interner>; 21 type Target = T;
19pub(crate) type StructDatum = chalk_solve::rust_ir::AdtDatum<Interner>; 22
20pub(crate) type ImplId = chalk_ir::ImplId<Interner>; 23 fn deref(&self) -> &Self::Target {
21pub(crate) type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>; 24 &self.0
22pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>; 25 }
23pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; 26}
24pub(crate) type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; 27
25pub(crate) type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; 28impl_internable!(
26pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; 29 InternedWrapper<Vec<chalk_ir::VariableKind<Interner>>>,
27pub(crate) type Variances = chalk_ir::Variances<Interner>; 30 InternedWrapper<SmallVec<[GenericArg; 2]>>,
31 InternedWrapper<chalk_ir::TyData<Interner>>,
32 InternedWrapper<chalk_ir::LifetimeData<Interner>>,
33 InternedWrapper<chalk_ir::ConstData<Interner>>,
34 InternedWrapper<Vec<chalk_ir::CanonicalVarKind<Interner>>>,
35 InternedWrapper<Vec<chalk_ir::ProgramClause<Interner>>>,
36 InternedWrapper<Vec<chalk_ir::QuantifiedWhereClause<Interner>>>,
37 InternedWrapper<Vec<chalk_ir::Variance>>,
38);
28 39
29impl chalk_ir::interner::Interner for Interner { 40impl chalk_ir::interner::Interner for Interner {
30 type InternedType = Arc<chalk_ir::TyData<Self>>; 41 type InternedType = Interned<InternedWrapper<chalk_ir::TyData<Interner>>>;
31 type InternedLifetime = chalk_ir::LifetimeData<Self>; 42 type InternedLifetime = Interned<InternedWrapper<chalk_ir::LifetimeData<Self>>>;
32 type InternedConst = Arc<chalk_ir::ConstData<Self>>; 43 type InternedConst = Interned<InternedWrapper<chalk_ir::ConstData<Self>>>;
33 type InternedConcreteConst = (); 44 type InternedConcreteConst = ();
34 type InternedGenericArg = chalk_ir::GenericArgData<Self>; 45 type InternedGenericArg = chalk_ir::GenericArgData<Self>;
35 type InternedGoal = Arc<GoalData<Self>>; 46 type InternedGoal = Arc<GoalData<Self>>;
36 type InternedGoals = Vec<Goal<Self>>; 47 type InternedGoals = Vec<Goal<Self>>;
37 type InternedSubstitution = SmallVec<[GenericArg<Self>; 2]>; 48 type InternedSubstitution = Interned<InternedWrapper<SmallVec<[GenericArg; 2]>>>;
38 type InternedProgramClause = Arc<chalk_ir::ProgramClauseData<Self>>; 49 type InternedProgramClause = chalk_ir::ProgramClauseData<Self>;
39 type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>; 50 type InternedProgramClauses = Interned<InternedWrapper<Vec<chalk_ir::ProgramClause<Self>>>>;
40 type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; 51 type InternedQuantifiedWhereClauses =
41 type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>; 52 Interned<InternedWrapper<Vec<chalk_ir::QuantifiedWhereClause<Self>>>>;
42 type InternedCanonicalVarKinds = Vec<chalk_ir::CanonicalVarKind<Self>>; 53 type InternedVariableKinds = Interned<InternedWrapper<Vec<chalk_ir::VariableKind<Interner>>>>;
54 type InternedCanonicalVarKinds =
55 Interned<InternedWrapper<Vec<chalk_ir::CanonicalVarKind<Self>>>>;
43 type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>; 56 type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>;
44 type InternedVariances = Arc<[chalk_ir::Variance]>; 57 type InternedVariances = Interned<InternedWrapper<Vec<chalk_ir::Variance>>>;
45 type DefId = InternId; 58 type DefId = InternId;
46 type InternedAdtId = hir_def::AdtId; 59 type InternedAdtId = hir_def::AdtId;
47 type Identifier = TypeAliasId; 60 type Identifier = TypeAliasId;
48 type FnAbi = (); 61 type FnAbi = ();
49 62
50 fn debug_adt_id(type_kind_id: AdtId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> { 63 fn debug_adt_id(
64 type_kind_id: chalk_db::AdtId,
65 fmt: &mut fmt::Formatter<'_>,
66 ) -> Option<fmt::Result> {
51 tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt))) 67 tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt)))
52 } 68 }
53 69
54 fn debug_trait_id(type_kind_id: TraitId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> { 70 fn debug_trait_id(
71 type_kind_id: chalk_db::TraitId,
72 fmt: &mut fmt::Formatter<'_>,
73 ) -> Option<fmt::Result> {
55 tls::with_current_program(|prog| Some(prog?.debug_trait_id(type_kind_id, fmt))) 74 tls::with_current_program(|prog| Some(prog?.debug_trait_id(type_kind_id, fmt)))
56 } 75 }
57 76
58 fn debug_assoc_type_id(id: AssocTypeId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> { 77 fn debug_assoc_type_id(
78 id: chalk_db::AssocTypeId,
79 fmt: &mut fmt::Formatter<'_>,
80 ) -> Option<fmt::Result> {
59 tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt))) 81 tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt)))
60 } 82 }
61 83
@@ -99,7 +121,7 @@ impl chalk_ir::interner::Interner for Interner {
99 } 121 }
100 122
101 fn debug_generic_arg( 123 fn debug_generic_arg(
102 parameter: &GenericArg<Interner>, 124 parameter: &GenericArg,
103 fmt: &mut fmt::Formatter<'_>, 125 fmt: &mut fmt::Formatter<'_>,
104 ) -> Option<fmt::Result> { 126 ) -> Option<fmt::Result> {
105 tls::with_current_program(|prog| Some(prog?.debug_generic_arg(parameter, fmt))) 127 tls::with_current_program(|prog| Some(prog?.debug_generic_arg(parameter, fmt)))
@@ -192,59 +214,58 @@ impl chalk_ir::interner::Interner for Interner {
192 tls::with_current_program(|prog| Some(prog?.debug_quantified_where_clauses(clauses, fmt))) 214 tls::with_current_program(|prog| Some(prog?.debug_quantified_where_clauses(clauses, fmt)))
193 } 215 }
194 216
195 fn intern_ty(&self, kind: chalk_ir::TyKind<Self>) -> Arc<chalk_ir::TyData<Self>> { 217 fn intern_ty(&self, kind: chalk_ir::TyKind<Self>) -> Self::InternedType {
196 let flags = kind.compute_flags(self); 218 let flags = kind.compute_flags(self);
197 Arc::new(chalk_ir::TyData { kind, flags }) 219 Interned::new(InternedWrapper(chalk_ir::TyData { kind, flags }))
198 } 220 }
199 221
200 fn ty_data<'a>(&self, ty: &'a Arc<chalk_ir::TyData<Self>>) -> &'a chalk_ir::TyData<Self> { 222 fn ty_data<'a>(&self, ty: &'a Self::InternedType) -> &'a chalk_ir::TyData<Self> {
201 ty 223 &ty.0
202 } 224 }
203 225
204 fn intern_lifetime( 226 fn intern_lifetime(&self, lifetime: chalk_ir::LifetimeData<Self>) -> Self::InternedLifetime {
205 &self, 227 Interned::new(InternedWrapper(lifetime))
206 lifetime: chalk_ir::LifetimeData<Self>,
207 ) -> chalk_ir::LifetimeData<Self> {
208 lifetime
209 } 228 }
210 229
211 fn lifetime_data<'a>( 230 fn lifetime_data<'a>(
212 &self, 231 &self,
213 lifetime: &'a chalk_ir::LifetimeData<Self>, 232 lifetime: &'a Self::InternedLifetime,
214 ) -> &'a chalk_ir::LifetimeData<Self> { 233 ) -> &'a chalk_ir::LifetimeData<Self> {
215 lifetime 234 &lifetime.0
216 } 235 }
217 236
218 fn intern_const(&self, constant: chalk_ir::ConstData<Self>) -> Arc<chalk_ir::ConstData<Self>> { 237 fn intern_const(&self, constant: chalk_ir::ConstData<Self>) -> Self::InternedConst {
219 Arc::new(constant) 238 Interned::new(InternedWrapper(constant))
220 } 239 }
221 240
222 fn const_data<'a>( 241 fn const_data<'a>(&self, constant: &'a Self::InternedConst) -> &'a chalk_ir::ConstData<Self> {
223 &self, 242 &constant.0
224 constant: &'a Arc<chalk_ir::ConstData<Self>>,
225 ) -> &'a chalk_ir::ConstData<Self> {
226 constant
227 } 243 }
228 244
229 fn const_eq(&self, _ty: &Arc<chalk_ir::TyData<Self>>, _c1: &(), _c2: &()) -> bool { 245 fn const_eq(
246 &self,
247 _ty: &Self::InternedType,
248 _c1: &Self::InternedConcreteConst,
249 _c2: &Self::InternedConcreteConst,
250 ) -> bool {
230 true 251 true
231 } 252 }
232 253
233 fn intern_generic_arg( 254 fn intern_generic_arg(
234 &self, 255 &self,
235 parameter: chalk_ir::GenericArgData<Self>, 256 parameter: chalk_ir::GenericArgData<Self>,
236 ) -> chalk_ir::GenericArgData<Self> { 257 ) -> Self::InternedGenericArg {
237 parameter 258 parameter
238 } 259 }
239 260
240 fn generic_arg_data<'a>( 261 fn generic_arg_data<'a>(
241 &self, 262 &self,
242 parameter: &'a chalk_ir::GenericArgData<Self>, 263 parameter: &'a Self::InternedGenericArg,
243 ) -> &'a chalk_ir::GenericArgData<Self> { 264 ) -> &'a chalk_ir::GenericArgData<Self> {
244 parameter 265 parameter
245 } 266 }
246 267
247 fn intern_goal(&self, goal: GoalData<Self>) -> Arc<GoalData<Self>> { 268 fn intern_goal(&self, goal: GoalData<Self>) -> Self::InternedGoal {
248 Arc::new(goal) 269 Arc::new(goal)
249 } 270 }
250 271
@@ -255,38 +276,38 @@ impl chalk_ir::interner::Interner for Interner {
255 data.into_iter().collect() 276 data.into_iter().collect()
256 } 277 }
257 278
258 fn goal_data<'a>(&self, goal: &'a Arc<GoalData<Self>>) -> &'a GoalData<Self> { 279 fn goal_data<'a>(&self, goal: &'a Self::InternedGoal) -> &'a GoalData<Self> {
259 goal 280 goal
260 } 281 }
261 282
262 fn goals_data<'a>(&self, goals: &'a Vec<Goal<Interner>>) -> &'a [Goal<Interner>] { 283 fn goals_data<'a>(&self, goals: &'a Self::InternedGoals) -> &'a [Goal<Interner>] {
263 goals 284 goals
264 } 285 }
265 286
266 fn intern_substitution<E>( 287 fn intern_substitution<E>(
267 &self, 288 &self,
268 data: impl IntoIterator<Item = Result<GenericArg<Self>, E>>, 289 data: impl IntoIterator<Item = Result<GenericArg, E>>,
269 ) -> Result<Self::InternedSubstitution, E> { 290 ) -> Result<Self::InternedSubstitution, E> {
270 data.into_iter().collect() 291 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
271 } 292 }
272 293
273 fn substitution_data<'a>( 294 fn substitution_data<'a>(
274 &self, 295 &self,
275 substitution: &'a Self::InternedSubstitution, 296 substitution: &'a Self::InternedSubstitution,
276 ) -> &'a [GenericArg<Self>] { 297 ) -> &'a [GenericArg] {
277 substitution 298 &substitution.as_ref().0
278 } 299 }
279 300
280 fn intern_program_clause( 301 fn intern_program_clause(
281 &self, 302 &self,
282 data: chalk_ir::ProgramClauseData<Self>, 303 data: chalk_ir::ProgramClauseData<Self>,
283 ) -> Arc<chalk_ir::ProgramClauseData<Self>> { 304 ) -> Self::InternedProgramClause {
284 Arc::new(data) 305 data
285 } 306 }
286 307
287 fn program_clause_data<'a>( 308 fn program_clause_data<'a>(
288 &self, 309 &self,
289 clause: &'a Arc<chalk_ir::ProgramClauseData<Self>>, 310 clause: &'a Self::InternedProgramClause,
290 ) -> &'a chalk_ir::ProgramClauseData<Self> { 311 ) -> &'a chalk_ir::ProgramClauseData<Self> {
291 clause 312 clause
292 } 313 }
@@ -294,13 +315,13 @@ impl chalk_ir::interner::Interner for Interner {
294 fn intern_program_clauses<E>( 315 fn intern_program_clauses<E>(
295 &self, 316 &self,
296 data: impl IntoIterator<Item = Result<chalk_ir::ProgramClause<Self>, E>>, 317 data: impl IntoIterator<Item = Result<chalk_ir::ProgramClause<Self>, E>>,
297 ) -> Result<Arc<[chalk_ir::ProgramClause<Self>]>, E> { 318 ) -> Result<Self::InternedProgramClauses, E> {
298 data.into_iter().collect() 319 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
299 } 320 }
300 321
301 fn program_clauses_data<'a>( 322 fn program_clauses_data<'a>(
302 &self, 323 &self,
303 clauses: &'a Arc<[chalk_ir::ProgramClause<Self>]>, 324 clauses: &'a Self::InternedProgramClauses,
304 ) -> &'a [chalk_ir::ProgramClause<Self>] { 325 ) -> &'a [chalk_ir::ProgramClause<Self>] {
305 &clauses 326 &clauses
306 } 327 }
@@ -309,7 +330,7 @@ impl chalk_ir::interner::Interner for Interner {
309 &self, 330 &self,
310 data: impl IntoIterator<Item = Result<chalk_ir::QuantifiedWhereClause<Self>, E>>, 331 data: impl IntoIterator<Item = Result<chalk_ir::QuantifiedWhereClause<Self>, E>>,
311 ) -> Result<Self::InternedQuantifiedWhereClauses, E> { 332 ) -> Result<Self::InternedQuantifiedWhereClauses, E> {
312 data.into_iter().collect() 333 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
313 } 334 }
314 335
315 fn quantified_where_clauses_data<'a>( 336 fn quantified_where_clauses_data<'a>(
@@ -323,21 +344,21 @@ impl chalk_ir::interner::Interner for Interner {
323 &self, 344 &self,
324 data: impl IntoIterator<Item = Result<chalk_ir::VariableKind<Self>, E>>, 345 data: impl IntoIterator<Item = Result<chalk_ir::VariableKind<Self>, E>>,
325 ) -> Result<Self::InternedVariableKinds, E> { 346 ) -> Result<Self::InternedVariableKinds, E> {
326 data.into_iter().collect() 347 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
327 } 348 }
328 349
329 fn variable_kinds_data<'a>( 350 fn variable_kinds_data<'a>(
330 &self, 351 &self,
331 parameter_kinds: &'a Self::InternedVariableKinds, 352 parameter_kinds: &'a Self::InternedVariableKinds,
332 ) -> &'a [chalk_ir::VariableKind<Self>] { 353 ) -> &'a [chalk_ir::VariableKind<Self>] {
333 &parameter_kinds 354 &parameter_kinds.as_ref().0
334 } 355 }
335 356
336 fn intern_canonical_var_kinds<E>( 357 fn intern_canonical_var_kinds<E>(
337 &self, 358 &self,
338 data: impl IntoIterator<Item = Result<chalk_ir::CanonicalVarKind<Self>, E>>, 359 data: impl IntoIterator<Item = Result<chalk_ir::CanonicalVarKind<Self>, E>>,
339 ) -> Result<Self::InternedCanonicalVarKinds, E> { 360 ) -> Result<Self::InternedCanonicalVarKinds, E> {
340 data.into_iter().collect() 361 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
341 } 362 }
342 363
343 fn canonical_var_kinds_data<'a>( 364 fn canonical_var_kinds_data<'a>(
@@ -377,7 +398,7 @@ impl chalk_ir::interner::Interner for Interner {
377 &self, 398 &self,
378 data: impl IntoIterator<Item = Result<chalk_ir::Variance, E>>, 399 data: impl IntoIterator<Item = Result<chalk_ir::Variance, E>>,
379 ) -> Result<Self::InternedVariances, E> { 400 ) -> Result<Self::InternedVariances, E> {
380 data.into_iter().collect() 401 Ok(Interned::new(InternedWrapper(data.into_iter().collect::<Result<_, _>>()?)))
381 } 402 }
382 403
383 fn variances_data<'a>( 404 fn variances_data<'a>(
@@ -391,3 +412,12 @@ impl chalk_ir::interner::Interner for Interner {
391impl chalk_ir::interner::HasInterner for Interner { 412impl chalk_ir::interner::HasInterner for Interner {
392 type Interner = Self; 413 type Interner = Self;
393} 414}
415
416#[macro_export]
417macro_rules! has_interner {
418 ($t:ty) => {
419 impl HasInterner for $t {
420 type Interner = crate::Interner;
421 }
422 };
423}
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 6f9c698e6..0505fa4ae 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -1,59 +1,68 @@
1//! The type system. We currently use this to infer types for completion, hover 1//! The type system. We currently use this to infer types for completion, hover
2//! information and various assists. 2//! information and various assists.
3
3#[allow(unused)] 4#[allow(unused)]
4macro_rules! eprintln { 5macro_rules! eprintln {
5 ($($tt:tt)*) => { stdx::eprintln!($($tt)*) }; 6 ($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
6} 7}
7 8
8mod autoderef; 9mod autoderef;
9pub mod primitive; 10mod builder;
10pub mod traits; 11mod chalk_db;
11pub mod method_resolution; 12mod chalk_ext;
12mod op; 13mod infer;
14mod interner;
13mod lower; 15mod lower;
14pub(crate) mod infer; 16mod mapping;
15pub(crate) mod utils; 17mod op;
16mod chalk_cast; 18mod tls;
17 19mod utils;
18pub mod display; 20mod walk;
19pub mod db; 21pub mod db;
20pub mod diagnostics; 22pub mod diagnostics;
23pub mod display;
24pub mod method_resolution;
25pub mod primitive;
26pub mod traits;
21 27
22#[cfg(test)] 28#[cfg(test)]
23mod tests; 29mod tests;
24#[cfg(test)] 30#[cfg(test)]
25mod test_db; 31mod test_db;
26 32
27use std::{iter, mem, ops::Deref, sync::Arc}; 33use std::sync::Arc;
28 34
29use base_db::salsa; 35use chalk_ir::{
30use hir_def::{ 36 fold::{Fold, Shift},
31 builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId, 37 interner::HasInterner,
32 GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, 38 UintTy,
33}; 39};
34use itertools::Itertools; 40use hir_def::{expr::ExprId, type_ref::Rawness, TypeParamId};
35use smallvec::SmallVec;
36 41
37use crate::{ 42use crate::{db::HirDatabase, display::HirDisplay, utils::generics};
38 db::HirDatabase,
39 display::HirDisplay,
40 utils::{generics, make_mut_slice, Generics},
41};
42 43
43pub use autoderef::autoderef; 44pub use autoderef::autoderef;
44pub use infer::{could_unify, InferenceResult, InferenceVar}; 45pub use builder::TyBuilder;
46pub use chalk_ext::*;
47pub use infer::{could_unify, InferenceResult};
48pub use interner::Interner;
45pub use lower::{ 49pub use lower::{
46 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, 50 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
47 TyDefId, TyLoweringContext, ValueTyDefId, 51 TyDefId, TyLoweringContext, ValueTyDefId,
48}; 52};
49pub use traits::{AliasEq, DomainGoal, InEnvironment, TraitEnvironment}; 53pub use mapping::{
54 const_from_placeholder_idx, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
55 from_placeholder_idx, lt_from_placeholder_idx, to_assoc_type_id, to_chalk_trait_id,
56 to_foreign_def_id, to_placeholder_idx,
57};
58pub use traits::TraitEnvironment;
59pub use utils::all_super_traits;
60pub use walk::TypeWalk;
50 61
51pub use chalk_ir::{ 62pub use chalk_ir::{
52 cast::Cast, AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind, 63 cast::Cast, AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind,
53}; 64};
54 65
55pub use crate::traits::chalk::Interner;
56
57pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>; 66pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>;
58pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>; 67pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
59pub type FnDefId = chalk_ir::FnDefId<Interner>; 68pub type FnDefId = chalk_ir::FnDefId<Interner>;
@@ -61,371 +70,56 @@ pub type ClosureId = chalk_ir::ClosureId<Interner>;
61pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; 70pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
62pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; 71pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
63 72
73pub type VariableKind = chalk_ir::VariableKind<Interner>;
74pub type VariableKinds = chalk_ir::VariableKinds<Interner>;
64pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; 75pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;
76pub type Binders<T> = chalk_ir::Binders<T>;
77pub type Substitution = chalk_ir::Substitution<Interner>;
78pub type GenericArg = chalk_ir::GenericArg<Interner>;
79pub type GenericArgData = chalk_ir::GenericArgData<Interner>;
80
81pub type Ty = chalk_ir::Ty<Interner>;
82pub type TyKind = chalk_ir::TyKind<Interner>;
83pub type DynTy = chalk_ir::DynTy<Interner>;
84pub type FnPointer = chalk_ir::FnPointer<Interner>;
85// pub type FnSubst = chalk_ir::FnSubst<Interner>;
86pub use chalk_ir::FnSubst;
87pub type ProjectionTy = chalk_ir::ProjectionTy<Interner>;
88pub type AliasTy = chalk_ir::AliasTy<Interner>;
89pub type OpaqueTy = chalk_ir::OpaqueTy<Interner>;
90pub type InferenceVar = chalk_ir::InferenceVar;
91
92pub type Lifetime = chalk_ir::Lifetime<Interner>;
93pub type LifetimeData = chalk_ir::LifetimeData<Interner>;
94pub type LifetimeOutlives = chalk_ir::LifetimeOutlives<Interner>;
95
96pub type Const = chalk_ir::Const<Interner>;
97pub type ConstData = chalk_ir::ConstData<Interner>;
98pub type ConstValue = chalk_ir::ConstValue<Interner>;
99pub type ConcreteConst = chalk_ir::ConcreteConst<Interner>;
65 100
66pub type ChalkTraitId = chalk_ir::TraitId<Interner>; 101pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
67 102pub type TraitRef = chalk_ir::TraitRef<Interner>;
68#[derive(Clone, PartialEq, Eq, Debug, Hash)] 103pub type QuantifiedWhereClause = Binders<WhereClause>;
69pub enum Lifetime { 104pub type QuantifiedWhereClauses = chalk_ir::QuantifiedWhereClauses<Interner>;
70 Parameter(LifetimeParamId), 105pub type Canonical<T> = chalk_ir::Canonical<T>;
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 {
104 pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
105 TraitRef {
106 trait_id: to_chalk_trait_id(self.trait_(db)),
107 substitution: self.substitution.clone(),
108 }
109 }
110
111 pub fn self_type_parameter(&self) -> &Ty {
112 &self.substitution[0]
113 }
114
115 fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
116 match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container {
117 AssocContainerId::TraitId(it) => it,
118 _ => panic!("projection ty without parent trait"),
119 }
120 }
121}
122
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 106
143pub type FnSig = chalk_ir::FnSig<Interner>; 107pub type FnSig = chalk_ir::FnSig<Interner>;
144 108
145#[derive(Clone, PartialEq, Eq, Debug, Hash)] 109pub type InEnvironment<T> = chalk_ir::InEnvironment<T>;
146pub struct FnPointer { 110pub type DomainGoal = chalk_ir::DomainGoal<Interner>;
147 pub num_args: usize, 111pub type AliasEq = chalk_ir::AliasEq<Interner>;
148 pub sig: FnSig, 112pub type Solution = chalk_solve::Solution<Interner>;
149 pub substs: Substitution, 113pub type ConstrainedSubst = chalk_ir::ConstrainedSubst<Interner>;
150} 114pub type Guidance = chalk_solve::Guidance<Interner>;
151 115pub type WhereClause = chalk_ir::WhereClause<Interner>;
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 116
220 /// This represents a placeholder for an opaque type in situations where we 117// FIXME: get rid of this
221 /// don't know the hidden type (i.e. currently almost always). This is 118pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution {
222 /// analogous to the `AssociatedType` type constructor. 119 Substitution::from_iter(
223 /// It is also used as the type of async block, with one type parameter 120 &Interner,
224 /// representing the Future::Output type. 121 s.as_slice(&Interner)[..std::cmp::min(s.len(&Interner), n)].iter().cloned(),
225 OpaqueType(OpaqueTyId, Substitution), 122 )
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 {
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 {
359 Substitution({
360 let mut v = SmallVec::new();
361 v.push(ty);
362 v
363 })
364 }
365
366 pub fn prefix(&self, n: usize) -> Substitution {
367 Substitution(self.0[..std::cmp::min(self.0.len(), n)].into())
368 }
369
370 pub fn suffix(&self, n: usize) -> Substitution {
371 Substitution(self.0[self.0.len() - std::cmp::min(self.0.len(), n)..].into())
372 }
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 )
413 }
414
415 pub fn build_for_def(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder {
416 let def = def.into();
417 let params = generics(db.upcast(), def);
418 let param_count = params.len();
419 Substitution::builder(param_count)
420 }
421
422 pub(crate) fn build_for_generics(generic_params: &Generics) -> SubstsBuilder {
423 Substitution::builder(generic_params.len())
424 }
425
426 fn builder(param_count: usize) -> SubstsBuilder {
427 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count }
428 }
429} 123}
430 124
431/// Return an index of a parameter in the generic type parameter list by it's id. 125/// Return an index of a parameter in the generic type parameter list by it's id.
@@ -433,244 +127,39 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> {
433 generics(db.upcast(), id.parent).param_idx(id) 127 generics(db.upcast(), id.parent).param_idx(id)
434} 128}
435 129
436#[derive(Debug, Clone)] 130pub(crate) fn wrap_empty_binders<T>(value: T) -> Binders<T>
437pub struct SubstsBuilder { 131where
438 vec: Vec<Ty>, 132 T: Fold<Interner, Result = T> + HasInterner<Interner = Interner>,
439 param_count: usize, 133{
440} 134 Binders::empty(&Interner, value.shifted_in_from(&Interner, DebruijnIndex::ONE))
441 135}
442impl SubstsBuilder { 136
443 pub fn build(self) -> Substitution { 137pub(crate) fn make_only_type_binders<T: HasInterner<Interner = Interner>>(
444 assert_eq!(self.vec.len(), self.param_count); 138 num_vars: usize,
445 Substitution(self.vec.into()) 139 value: T,
446 } 140) -> Binders<T> {
447 141 Binders::new(
448 pub fn push(mut self, ty: Ty) -> Self { 142 VariableKinds::from_iter(
449 self.vec.push(ty); 143 &Interner,
450 self 144 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
451 } 145 .take(num_vars),
452 146 ),
453 fn remaining(&self) -> usize { 147 value,
454 self.param_count - self.vec.len() 148 )
455 } 149}
456 150
457 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { 151// FIXME: get rid of this
458 self.fill( 152pub fn make_canonical<T: HasInterner<Interner = Interner>>(
459 (starting_from..) 153 value: T,
460 .map(|idx| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)), 154 kinds: impl IntoIterator<Item = TyVariableKind>,
155) -> Canonical<T> {
156 let kinds = kinds.into_iter().map(|tk| {
157 chalk_ir::CanonicalVarKind::new(
158 chalk_ir::VariableKind::Ty(tk),
159 chalk_ir::UniverseIndex::ROOT,
461 ) 160 )
462 } 161 });
463 162 Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) }
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> {
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
502 where
503 T: TypeWalk,
504 {
505 Self { num_binders: 0, value: value.shift_bound_vars(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 }
533}
534
535impl<T: TypeWalk> Binders<T> {
536 /// Substitutes all variables.
537 pub fn subst(self, subst: &Substitution) -> T {
538 assert_eq!(subst.len(), self.num_binders);
539 self.value.subst_bound_vars(subst)
540 }
541}
542
543impl<T: TypeWalk> TypeWalk for Binders<T> {
544 fn walk(&self, f: &mut impl FnMut(&Ty)) {
545 self.value.walk(f);
546 }
547
548 fn walk_mut_binders(
549 &mut self,
550 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
551 binders: DebruijnIndex,
552 ) {
553 self.value.walk_mut_binders(f, binders.shifted_in())
554 }
555}
556
557/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.
558#[derive(Clone, PartialEq, Eq, Debug, Hash)]
559pub struct TraitRef {
560 pub trait_id: ChalkTraitId,
561 pub substitution: Substitution,
562}
563
564impl TraitRef {
565 pub fn self_type_parameter(&self) -> &Ty {
566 &self.substitution[0]
567 }
568
569 pub fn hir_trait_id(&self) -> TraitId {
570 from_chalk_trait_id(self.trait_id)
571 }
572}
573
574impl TypeWalk for TraitRef {
575 fn walk(&self, f: &mut impl FnMut(&Ty)) {
576 self.substitution.walk(f);
577 }
578
579 fn walk_mut_binders(
580 &mut self,
581 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
582 binders: DebruijnIndex,
583 ) {
584 self.substitution.walk_mut_binders(f, binders);
585 }
586}
587
588/// Like `generics::WherePredicate`, but with resolved types: A condition on the
589/// parameters of a generic item.
590#[derive(Debug, Clone, PartialEq, Eq, Hash)]
591pub enum WhereClause {
592 /// The given trait needs to be implemented for its type parameters.
593 Implemented(TraitRef),
594 /// An associated type bindings like in `Iterator<Item = T>`.
595 AliasEq(AliasEq),
596}
597
598impl WhereClause {
599 pub fn is_implemented(&self) -> bool {
600 matches!(self, WhereClause::Implemented(_))
601 }
602
603 pub fn trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> {
604 match self {
605 WhereClause::Implemented(tr) => Some(tr.clone()),
606 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(proj), .. }) => {
607 Some(proj.trait_ref(db))
608 }
609 WhereClause::AliasEq(_) => None,
610 }
611 }
612}
613
614impl TypeWalk for WhereClause {
615 fn walk(&self, f: &mut impl FnMut(&Ty)) {
616 match self {
617 WhereClause::Implemented(trait_ref) => trait_ref.walk(f),
618 WhereClause::AliasEq(alias_eq) => alias_eq.walk(f),
619 }
620 }
621
622 fn walk_mut_binders(
623 &mut self,
624 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
625 binders: DebruijnIndex,
626 ) {
627 match self {
628 WhereClause::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders),
629 WhereClause::AliasEq(alias_eq) => alias_eq.walk_mut_binders(f, binders),
630 }
631 }
632}
633
634pub type QuantifiedWhereClause = Binders<WhereClause>;
635
636#[derive(Debug, Clone, PartialEq, Eq, Hash)]
637pub struct QuantifiedWhereClauses(Arc<[QuantifiedWhereClause]>);
638
639impl QuantifiedWhereClauses {
640 pub fn from_iter(
641 _interner: &Interner,
642 elements: impl IntoIterator<Item = QuantifiedWhereClause>,
643 ) -> Self {
644 QuantifiedWhereClauses(elements.into_iter().collect())
645 }
646
647 pub fn interned(&self) -> &Arc<[QuantifiedWhereClause]> {
648 &self.0
649 }
650}
651
652/// Basically a claim (currently not validated / checked) that the contained
653/// type / trait ref contains no inference variables; any inference variables it
654/// contained have been replaced by bound variables, and `kinds` tells us how
655/// many there are and whether they were normal or float/int variables. This is
656/// used to erase irrelevant differences between types before using them in
657/// queries.
658#[derive(Debug, Clone, PartialEq, Eq, Hash)]
659pub struct Canonical<T> {
660 pub value: T,
661 pub binders: CanonicalVarKinds,
662}
663
664impl<T> Canonical<T> {
665 pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self {
666 let kinds = kinds.into_iter().map(|tk| {
667 chalk_ir::CanonicalVarKind::new(
668 chalk_ir::VariableKind::Ty(tk),
669 chalk_ir::UniverseIndex::ROOT,
670 )
671 });
672 Self { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) }
673 }
674} 163}
675 164
676/// A function signature as seen by type inference: Several parameter types and 165/// A function signature as seen by type inference: Several parameter types and
@@ -681,6 +170,8 @@ pub struct CallableSig {
681 is_varargs: bool, 170 is_varargs: bool,
682} 171}
683 172
173has_interner!(CallableSig);
174
684/// A polymorphic function signature. 175/// A polymorphic function signature.
685pub type PolyFnSig = Binders<CallableSig>; 176pub type PolyFnSig = Binders<CallableSig>;
686 177
@@ -692,23 +183,21 @@ impl CallableSig {
692 183
693 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { 184 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
694 CallableSig { 185 CallableSig {
695 // FIXME: what to do about lifetime params? 186 // FIXME: what to do about lifetime params? -> return PolyFnSig
696 params_and_return: fn_ptr 187 params_and_return: fn_ptr
697 .substs 188 .substitution
698 .clone() 189 .clone()
699 .shift_bound_vars_out(DebruijnIndex::ONE) 190 .shifted_out_to(&Interner, DebruijnIndex::ONE)
700 .interned(&Interner) 191 .expect("unexpected lifetime vars in fn ptr")
192 .0
193 .as_slice(&Interner)
701 .iter() 194 .iter()
702 .cloned() 195 .map(|arg| arg.assert_ty_ref(&Interner).clone())
703 .collect(), 196 .collect(),
704 is_varargs: fn_ptr.sig.variadic, 197 is_varargs: fn_ptr.sig.variadic,
705 } 198 }
706 } 199 }
707 200
708 pub fn from_substs(substs: &Substitution) -> CallableSig {
709 CallableSig { params_and_return: substs.iter().cloned().collect(), is_varargs: false }
710 }
711
712 pub fn params(&self) -> &[Ty] { 201 pub fn params(&self) -> &[Ty] {
713 &self.params_and_return[0..self.params_and_return.len() - 1] 202 &self.params_and_return[0..self.params_and_return.len() - 1]
714 } 203 }
@@ -718,516 +207,20 @@ impl CallableSig {
718 } 207 }
719} 208}
720 209
721impl TypeWalk for CallableSig { 210impl Fold<Interner> for CallableSig {
722 fn walk(&self, f: &mut impl FnMut(&Ty)) { 211 type Result = CallableSig;
723 for t in self.params_and_return.iter() {
724 t.walk(f);
725 }
726 }
727
728 fn walk_mut_binders(
729 &mut self,
730 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
731 binders: DebruijnIndex,
732 ) {
733 for t in make_mut_slice(&mut self.params_and_return) {
734 t.walk_mut_binders(f, binders);
735 }
736 }
737}
738
739impl Ty {
740 pub fn unit() -> Self {
741 TyKind::Tuple(0, Substitution::empty()).intern(&Interner)
742 }
743
744 pub fn adt_ty(adt: hir_def::AdtId, substs: Substitution) -> Ty {
745 TyKind::Adt(AdtId(adt), substs).intern(&Interner)
746 }
747
748 pub fn fn_ptr(sig: CallableSig) -> Self {
749 TyKind::Function(FnPointer {
750 num_args: sig.params().len(),
751 sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs },
752 substs: Substitution::from_iter(&Interner, sig.params_and_return.iter().cloned()),
753 })
754 .intern(&Interner)
755 }
756
757 pub fn builtin(builtin: BuiltinType) -> Self {
758 match builtin {
759 BuiltinType::Char => TyKind::Scalar(Scalar::Char).intern(&Interner),
760 BuiltinType::Bool => TyKind::Scalar(Scalar::Bool).intern(&Interner),
761 BuiltinType::Str => TyKind::Str.intern(&Interner),
762 BuiltinType::Int(t) => {
763 TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))).intern(&Interner)
764 }
765 BuiltinType::Uint(t) => {
766 TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))).intern(&Interner)
767 }
768 BuiltinType::Float(t) => {
769 TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))).intern(&Interner)
770 }
771 }
772 }
773
774 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
775 match self.interned(&Interner) {
776 TyKind::Ref(mutability, ty) => Some((ty, *mutability)),
777 _ => None,
778 }
779 }
780
781 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
782 match self.interned(&Interner) {
783 TyKind::Ref(mutability, ty) => Some((ty, Rawness::Ref, *mutability)),
784 TyKind::Raw(mutability, ty) => Some((ty, Rawness::RawPtr, *mutability)),
785 _ => None,
786 }
787 }
788
789 pub fn strip_references(&self) -> &Ty {
790 let mut t: &Ty = self;
791
792 while let TyKind::Ref(_mutability, ty) = t.interned(&Interner) {
793 t = ty;
794 }
795
796 t
797 }
798
799 pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)> {
800 match self.interned(&Interner) {
801 TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),
802 _ => None,
803 }
804 }
805
806 pub fn as_tuple(&self) -> Option<&Substitution> {
807 match self.interned(&Interner) {
808 TyKind::Tuple(_, substs) => Some(substs),
809 _ => None,
810 }
811 }
812 212
813 pub fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId> { 213 fn fold_with<'i>(
814 match *self.interned(&Interner) { 214 self,
815 TyKind::Adt(AdtId(adt), ..) => Some(adt.into()), 215 folder: &mut dyn chalk_ir::fold::Folder<'i, Interner>,
816 TyKind::FnDef(callable, ..) => { 216 outer_binder: DebruijnIndex,
817 Some(db.lookup_intern_callable_def(callable.into()).into()) 217 ) -> chalk_ir::Fallible<Self::Result>
818 }
819 TyKind::AssociatedType(type_alias, ..) => Some(from_assoc_type_id(type_alias).into()),
820 TyKind::ForeignType(type_alias, ..) => Some(from_foreign_def_id(type_alias).into()),
821 _ => None,
822 }
823 }
824
825 pub fn is_never(&self) -> bool {
826 matches!(self.interned(&Interner), TyKind::Never)
827 }
828
829 pub fn is_unknown(&self) -> bool {
830 matches!(self.interned(&Interner), TyKind::Unknown)
831 }
832
833 pub fn equals_ctor(&self, other: &Ty) -> bool {
834 match (self.interned(&Interner), other.interned(&Interner)) {
835 (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2,
836 (TyKind::Slice(_), TyKind::Slice(_)) | (TyKind::Array(_), TyKind::Array(_)) => true,
837 (TyKind::FnDef(def_id, ..), TyKind::FnDef(def_id2, ..)) => def_id == def_id2,
838 (TyKind::OpaqueType(ty_id, ..), TyKind::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
839 (TyKind::AssociatedType(ty_id, ..), TyKind::AssociatedType(ty_id2, ..)) => {
840 ty_id == ty_id2
841 }
842 (TyKind::ForeignType(ty_id, ..), TyKind::ForeignType(ty_id2, ..)) => ty_id == ty_id2,
843 (TyKind::Closure(id1, _), TyKind::Closure(id2, _)) => id1 == id2,
844 (TyKind::Ref(mutability, ..), TyKind::Ref(mutability2, ..))
845 | (TyKind::Raw(mutability, ..), TyKind::Raw(mutability2, ..)) => {
846 mutability == mutability2
847 }
848 (
849 TyKind::Function(FnPointer { num_args, sig, .. }),
850 TyKind::Function(FnPointer { num_args: num_args2, sig: sig2, .. }),
851 ) => num_args == num_args2 && sig == sig2,
852 (TyKind::Tuple(cardinality, _), TyKind::Tuple(cardinality2, _)) => {
853 cardinality == cardinality2
854 }
855 (TyKind::Str, TyKind::Str) | (TyKind::Never, TyKind::Never) => true,
856 (TyKind::Scalar(scalar), TyKind::Scalar(scalar2)) => scalar == scalar2,
857 _ => false,
858 }
859 }
860
861 /// If this is a `dyn Trait` type, this returns the `Trait` part.
862 fn dyn_trait_ref(&self) -> Option<&TraitRef> {
863 match self.interned(&Interner) {
864 TyKind::Dyn(dyn_ty) => {
865 dyn_ty.bounds.value.interned().get(0).and_then(|b| match b.skip_binders() {
866 WhereClause::Implemented(trait_ref) => Some(trait_ref),
867 _ => None,
868 })
869 }
870 _ => None,
871 }
872 }
873
874 /// If this is a `dyn Trait`, returns that trait.
875 pub fn dyn_trait(&self) -> Option<TraitId> {
876 self.dyn_trait_ref().map(|it| it.trait_id).map(from_chalk_trait_id)
877 }
878
879 fn builtin_deref(&self) -> Option<Ty> {
880 match self.interned(&Interner) {
881 TyKind::Ref(.., ty) => Some(ty.clone()),
882 TyKind::Raw(.., ty) => Some(ty.clone()),
883 _ => None,
884 }
885 }
886
887 pub fn callable_def(&self, db: &dyn HirDatabase) -> Option<CallableDefId> {
888 match self.interned(&Interner) {
889 &TyKind::FnDef(def, ..) => Some(db.lookup_intern_callable_def(def.into())),
890 _ => None,
891 }
892 }
893
894 pub fn as_fn_def(&self, db: &dyn HirDatabase) -> Option<FunctionId> {
895 if let Some(CallableDefId::FunctionId(func)) = self.callable_def(db) {
896 Some(func)
897 } else {
898 None
899 }
900 }
901
902 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
903 match self.interned(&Interner) {
904 TyKind::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
905 TyKind::FnDef(def, parameters) => {
906 let callable_def = db.lookup_intern_callable_def((*def).into());
907 let sig = db.callable_item_signature(callable_def);
908 Some(sig.subst(&parameters))
909 }
910 TyKind::Closure(.., substs) => {
911 let sig_param = &substs[0];
912 sig_param.callable_sig(db)
913 }
914 _ => None,
915 }
916 }
917
918 /// Returns the type parameters of this type if it has some (i.e. is an ADT
919 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
920 pub fn substs(&self) -> Option<&Substitution> {
921 match self.interned(&Interner) {
922 TyKind::Adt(_, substs)
923 | TyKind::FnDef(_, substs)
924 | TyKind::Function(FnPointer { substs, .. })
925 | TyKind::Tuple(_, substs)
926 | TyKind::OpaqueType(_, substs)
927 | TyKind::AssociatedType(_, substs)
928 | TyKind::Closure(.., substs) => Some(substs),
929 _ => None,
930 }
931 }
932
933 fn substs_mut(&mut self) -> Option<&mut Substitution> {
934 match self.interned_mut() {
935 TyKind::Adt(_, substs)
936 | TyKind::FnDef(_, substs)
937 | TyKind::Function(FnPointer { substs, .. })
938 | TyKind::Tuple(_, substs)
939 | TyKind::OpaqueType(_, substs)
940 | TyKind::AssociatedType(_, substs)
941 | TyKind::Closure(.., substs) => Some(substs),
942 _ => None,
943 }
944 }
945
946 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> {
947 match self.interned(&Interner) {
948 TyKind::OpaqueType(opaque_ty_id, ..) => {
949 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
950 ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
951 let krate = def.module(db.upcast()).krate();
952 if let Some(future_trait) = db
953 .lang_item(krate, "future_trait".into())
954 .and_then(|item| item.as_trait())
955 {
956 // This is only used by type walking.
957 // Parameters will be walked outside, and projection predicate is not used.
958 // So just provide the Future trait.
959 let impl_bound = Binders::new(
960 0,
961 WhereClause::Implemented(TraitRef {
962 trait_id: to_chalk_trait_id(future_trait),
963 substitution: Substitution::empty(),
964 }),
965 );
966 Some(vec![impl_bound])
967 } else {
968 None
969 }
970 }
971 ImplTraitId::ReturnTypeImplTrait(..) => None,
972 }
973 }
974 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
975 let predicates = match db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into())
976 {
977 ImplTraitId::ReturnTypeImplTrait(func, idx) => {
978 db.return_type_impl_traits(func).map(|it| {
979 let data = (*it)
980 .as_ref()
981 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
982 data.subst(&opaque_ty.substitution)
983 })
984 }
985 // It always has an parameter for Future::Output type.
986 ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(),
987 };
988
989 predicates.map(|it| it.value)
990 }
991 TyKind::Placeholder(idx) => {
992 let id = from_placeholder_idx(db, *idx);
993 let generic_params = db.generic_params(id.parent);
994 let param_data = &generic_params.types[id.local_id];
995 match param_data.provenance {
996 hir_def::generics::TypeParamProvenance::ArgumentImplTrait => {
997 let substs = Substitution::type_params(db, id.parent);
998 let predicates = db
999 .generic_predicates(id.parent)
1000 .into_iter()
1001 .map(|pred| pred.clone().subst(&substs))
1002 .filter(|wc| match &wc.skip_binders() {
1003 WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
1004 WhereClause::AliasEq(AliasEq {
1005 alias: AliasTy::Projection(proj),
1006 ty: _,
1007 }) => proj.self_type_parameter() == self,
1008 _ => false,
1009 })
1010 .collect_vec();
1011
1012 Some(predicates)
1013 }
1014 _ => None,
1015 }
1016 }
1017 _ => None,
1018 }
1019 }
1020
1021 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> {
1022 match self.interned(&Interner) {
1023 TyKind::AssociatedType(id, ..) => {
1024 match from_assoc_type_id(*id).lookup(db.upcast()).container {
1025 AssocContainerId::TraitId(trait_id) => Some(trait_id),
1026 _ => None,
1027 }
1028 }
1029 TyKind::Alias(AliasTy::Projection(projection_ty)) => {
1030 match from_assoc_type_id(projection_ty.associated_ty_id)
1031 .lookup(db.upcast())
1032 .container
1033 {
1034 AssocContainerId::TraitId(trait_id) => Some(trait_id),
1035 _ => None,
1036 }
1037 }
1038 _ => None,
1039 }
1040 }
1041}
1042
1043/// This allows walking structures that contain types to do something with those
1044/// types, similar to Chalk's `Fold` trait.
1045pub trait TypeWalk {
1046 fn walk(&self, f: &mut impl FnMut(&Ty));
1047 fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
1048 self.walk_mut_binders(&mut |ty, _binders| f(ty), DebruijnIndex::INNERMOST);
1049 }
1050 /// Walk the type, counting entered binders.
1051 ///
1052 /// `TyKind::Bound` variables use DeBruijn indexing, which means that 0 refers
1053 /// to the innermost binder, 1 to the next, etc.. So when we want to
1054 /// substitute a certain bound variable, we can't just walk the whole type
1055 /// and blindly replace each instance of a certain index; when we 'enter'
1056 /// things that introduce new bound variables, we have to keep track of
1057 /// that. Currently, the only thing that introduces bound variables on our
1058 /// side are `TyKind::Dyn` and `TyKind::Opaque`, which each introduce a bound
1059 /// variable for the self type.
1060 fn walk_mut_binders(
1061 &mut self,
1062 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
1063 binders: DebruijnIndex,
1064 );
1065
1066 fn fold_binders(
1067 mut self,
1068 f: &mut impl FnMut(Ty, DebruijnIndex) -> Ty,
1069 binders: DebruijnIndex,
1070 ) -> Self
1071 where
1072 Self: Sized,
1073 {
1074 self.walk_mut_binders(
1075 &mut |ty_mut, binders| {
1076 let ty = mem::replace(ty_mut, TyKind::Unknown.intern(&Interner));
1077 *ty_mut = f(ty, binders);
1078 },
1079 binders,
1080 );
1081 self
1082 }
1083
1084 fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Self
1085 where
1086 Self: Sized,
1087 {
1088 self.walk_mut(&mut |ty_mut| {
1089 let ty = mem::replace(ty_mut, TyKind::Unknown.intern(&Interner));
1090 *ty_mut = f(ty);
1091 });
1092 self
1093 }
1094
1095 /// Substitutes `TyKind::Bound` vars with the given substitution.
1096 fn subst_bound_vars(self, substs: &Substitution) -> Self
1097 where
1098 Self: Sized,
1099 {
1100 self.subst_bound_vars_at_depth(substs, DebruijnIndex::INNERMOST)
1101 }
1102
1103 /// Substitutes `TyKind::Bound` vars with the given substitution.
1104 fn subst_bound_vars_at_depth(mut self, substs: &Substitution, depth: DebruijnIndex) -> Self
1105 where
1106 Self: Sized,
1107 {
1108 self.walk_mut_binders(
1109 &mut |ty, binders| {
1110 if let &mut TyKind::BoundVar(bound) = ty.interned_mut() {
1111 if bound.debruijn >= binders {
1112 *ty = substs.0[bound.index].clone().shift_bound_vars(binders);
1113 }
1114 }
1115 },
1116 depth,
1117 );
1118 self
1119 }
1120
1121 /// Shifts up debruijn indices of `TyKind::Bound` vars by `n`.
1122 fn shift_bound_vars(self, n: DebruijnIndex) -> Self
1123 where
1124 Self: Sized,
1125 {
1126 self.fold_binders(
1127 &mut |ty, binders| match ty.interned(&Interner) {
1128 TyKind::BoundVar(bound) if bound.debruijn >= binders => {
1129 TyKind::BoundVar(bound.shifted_in_from(n)).intern(&Interner)
1130 }
1131 _ => ty,
1132 },
1133 DebruijnIndex::INNERMOST,
1134 )
1135 }
1136
1137 /// Shifts debruijn indices of `TyKind::Bound` vars out (down) by `n`.
1138 fn shift_bound_vars_out(self, n: DebruijnIndex) -> Self
1139 where 218 where
1140 Self: Sized + std::fmt::Debug, 219 Interner: 'i,
1141 { 220 {
1142 self.fold_binders( 221 let vec = self.params_and_return.to_vec();
1143 &mut |ty, binders| match ty.interned(&Interner) { 222 let folded = vec.fold_with(folder, outer_binder)?;
1144 TyKind::BoundVar(bound) if bound.debruijn >= binders => { 223 Ok(CallableSig { params_and_return: folded.into(), is_varargs: self.is_varargs })
1145 TyKind::BoundVar(bound.shifted_out_to(n).unwrap_or(bound.clone()))
1146 .intern(&Interner)
1147 }
1148 _ => ty,
1149 },
1150 DebruijnIndex::INNERMOST,
1151 )
1152 }
1153}
1154
1155impl TypeWalk for Ty {
1156 fn walk(&self, f: &mut impl FnMut(&Ty)) {
1157 match self.interned(&Interner) {
1158 TyKind::Alias(AliasTy::Projection(p_ty)) => {
1159 for t in p_ty.substitution.iter() {
1160 t.walk(f);
1161 }
1162 }
1163 TyKind::Alias(AliasTy::Opaque(o_ty)) => {
1164 for t in o_ty.substitution.iter() {
1165 t.walk(f);
1166 }
1167 }
1168 TyKind::Dyn(dyn_ty) => {
1169 for p in dyn_ty.bounds.value.interned().iter() {
1170 p.walk(f);
1171 }
1172 }
1173 TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => {
1174 ty.walk(f);
1175 }
1176 _ => {
1177 if let Some(substs) = self.substs() {
1178 for t in substs.iter() {
1179 t.walk(f);
1180 }
1181 }
1182 }
1183 }
1184 f(self);
1185 }
1186
1187 fn walk_mut_binders(
1188 &mut self,
1189 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
1190 binders: DebruijnIndex,
1191 ) {
1192 match self.interned_mut() {
1193 TyKind::Alias(AliasTy::Projection(p_ty)) => {
1194 p_ty.substitution.walk_mut_binders(f, binders);
1195 }
1196 TyKind::Dyn(dyn_ty) => {
1197 for p in make_mut_slice(&mut dyn_ty.bounds.value.0) {
1198 p.walk_mut_binders(f, binders.shifted_in());
1199 }
1200 }
1201 TyKind::Alias(AliasTy::Opaque(o_ty)) => {
1202 o_ty.substitution.walk_mut_binders(f, binders);
1203 }
1204 TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => {
1205 ty.walk_mut_binders(f, binders);
1206 }
1207 _ => {
1208 if let Some(substs) = self.substs_mut() {
1209 substs.walk_mut_binders(f, binders);
1210 }
1211 }
1212 }
1213 f(self, binders);
1214 }
1215}
1216
1217impl<T: TypeWalk> TypeWalk for Vec<T> {
1218 fn walk(&self, f: &mut impl FnMut(&Ty)) {
1219 for t in self {
1220 t.walk(f);
1221 }
1222 }
1223 fn walk_mut_binders(
1224 &mut self,
1225 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
1226 binders: DebruijnIndex,
1227 ) {
1228 for t in self {
1229 t.walk_mut_binders(f, binders);
1230 }
1231 } 224 }
1232} 225}
1233 226
@@ -1242,45 +235,75 @@ pub struct ReturnTypeImplTraits {
1242 pub(crate) impl_traits: Vec<ReturnTypeImplTrait>, 235 pub(crate) impl_traits: Vec<ReturnTypeImplTrait>,
1243} 236}
1244 237
238has_interner!(ReturnTypeImplTraits);
239
1245#[derive(Clone, PartialEq, Eq, Debug, Hash)] 240#[derive(Clone, PartialEq, Eq, Debug, Hash)]
1246pub(crate) struct ReturnTypeImplTrait { 241pub(crate) struct ReturnTypeImplTrait {
1247 pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>, 242 pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>,
1248} 243}
1249 244
1250pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { 245pub fn static_lifetime() -> Lifetime {
1251 chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id)) 246 LifetimeData::Static.intern(&Interner)
1252} 247}
1253 248
1254pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId { 249pub fn dummy_usize_const() -> Const {
1255 salsa::InternKey::from_intern_id(id.0) 250 let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner);
1256} 251 chalk_ir::ConstData {
1257 252 ty: usize_ty,
1258pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId { 253 value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }),
1259 chalk_ir::AssocTypeId(salsa::InternKey::as_intern_id(&id)) 254 }
255 .intern(&Interner)
1260} 256}
1261 257
1262pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId { 258pub(crate) fn fold_free_vars<T: HasInterner<Interner = Interner> + Fold<Interner>>(
1263 salsa::InternKey::from_intern_id(id.0) 259 t: T,
1264} 260 f: impl FnMut(BoundVar, DebruijnIndex) -> Ty,
261) -> T::Result {
262 use chalk_ir::{fold::Folder, Fallible};
263 struct FreeVarFolder<F>(F);
264 impl<'i, F: FnMut(BoundVar, DebruijnIndex) -> Ty + 'i> Folder<'i, Interner> for FreeVarFolder<F> {
265 fn as_dyn(&mut self) -> &mut dyn Folder<'i, Interner> {
266 self
267 }
1265 268
1266pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeParamId { 269 fn interner(&self) -> &'i Interner {
1267 assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); 270 &Interner
1268 let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); 271 }
1269 db.lookup_intern_type_param_id(interned_id)
1270}
1271 272
1272pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderIndex { 273 fn fold_free_var_ty(
1273 let interned_id = db.intern_type_param_id(id); 274 &mut self,
1274 PlaceholderIndex { 275 bound_var: BoundVar,
1275 ui: chalk_ir::UniverseIndex::ROOT, 276 outer_binder: DebruijnIndex,
1276 idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(), 277 ) -> Fallible<Ty> {
278 Ok(self.0(bound_var, outer_binder))
279 }
1277 } 280 }
281 t.fold_with(&mut FreeVarFolder(f), DebruijnIndex::INNERMOST).expect("fold failed unexpectedly")
1278} 282}
1279 283
1280pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId { 284pub(crate) fn fold_tys<T: HasInterner<Interner = Interner> + Fold<Interner>>(
1281 chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id)) 285 t: T,
1282} 286 f: impl FnMut(Ty, DebruijnIndex) -> Ty,
287 binders: DebruijnIndex,
288) -> T::Result {
289 use chalk_ir::{
290 fold::{Folder, SuperFold},
291 Fallible,
292 };
293 struct TyFolder<F>(F);
294 impl<'i, F: FnMut(Ty, DebruijnIndex) -> Ty + 'i> Folder<'i, Interner> for TyFolder<F> {
295 fn as_dyn(&mut self) -> &mut dyn Folder<'i, Interner> {
296 self
297 }
298
299 fn interner(&self) -> &'i Interner {
300 &Interner
301 }
1283 302
1284pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId { 303 fn fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Fallible<Ty> {
1285 salsa::InternKey::from_intern_id(id.0) 304 let ty = ty.super_fold_with(self.as_dyn(), outer_binder)?;
305 Ok(self.0(ty, outer_binder))
306 }
307 }
308 t.fold_with(&mut TyFolder(f), binders).expect("fold failed unexpectedly")
1286} 309}
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index c87789d45..a035686bc 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -8,14 +8,14 @@
8use std::{iter, sync::Arc}; 8use std::{iter, sync::Arc};
9 9
10use base_db::CrateId; 10use base_db::CrateId;
11use chalk_ir::{cast::Cast, Mutability, Safety}; 11use chalk_ir::{cast::Cast, fold::Shift, interner::HasInterner, Mutability, Safety};
12use hir_def::{ 12use hir_def::{
13 adt::StructKind, 13 adt::StructKind,
14 builtin_type::BuiltinType, 14 builtin_type::BuiltinType,
15 generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget}, 15 generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget},
16 path::{GenericArg, Path, PathSegment, PathSegments}, 16 path::{GenericArg, Path, PathSegment, PathSegments},
17 resolver::{HasResolver, Resolver, TypeNs}, 17 resolver::{HasResolver, Resolver, TypeNs},
18 type_ref::{TypeBound, TypeRef}, 18 type_ref::{TraitRef as HirTraitRef, TypeBound, TypeRef},
19 AdtId, AssocContainerId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, 19 AdtId, AssocContainerId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId,
20 GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId, 20 GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
21 TypeAliasId, TypeParamId, UnionId, VariantId, 21 TypeAliasId, TypeParamId, UnionId, VariantId,
@@ -27,16 +27,16 @@ use stdx::impl_from;
27 27
28use crate::{ 28use crate::{
29 db::HirDatabase, 29 db::HirDatabase,
30 to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx, 30 dummy_usize_const,
31 traits::chalk::{Interner, ToChalk}, 31 mapping::ToChalk,
32 static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
32 utils::{ 33 utils::{
33 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, 34 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics,
34 variant_data,
35 }, 35 },
36 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig, 36 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
37 ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, 37 FnSubst, ImplTraitId, Interner, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
38 ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty, 38 QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution,
39 TyKind, TypeWalk, WhereClause, 39 TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
40}; 40};
41 41
42#[derive(Debug)] 42#[derive(Debug)]
@@ -146,7 +146,7 @@ impl<'a> TyLoweringContext<'a> {
146 self.lower_ty_ext(type_ref).0 146 self.lower_ty_ext(type_ref).0
147 } 147 }
148 148
149 fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) { 149 pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
150 let mut res = None; 150 let mut res = None;
151 let ty = match type_ref { 151 let ty = match type_ref {
152 TypeRef::Never => TyKind::Never.intern(&Interner), 152 TypeRef::Never => TyKind::Never.intern(&Interner),
@@ -166,7 +166,7 @@ impl<'a> TyLoweringContext<'a> {
166 } 166 }
167 TypeRef::Array(inner) => { 167 TypeRef::Array(inner) => {
168 let inner_ty = self.lower_ty(inner); 168 let inner_ty = self.lower_ty(inner);
169 TyKind::Array(inner_ty).intern(&Interner) 169 TyKind::Array(inner_ty, dummy_usize_const()).intern(&Interner)
170 } 170 }
171 TypeRef::Slice(inner) => { 171 TypeRef::Slice(inner) => {
172 let inner_ty = self.lower_ty(inner); 172 let inner_ty = self.lower_ty(inner);
@@ -174,15 +174,19 @@ impl<'a> TyLoweringContext<'a> {
174 } 174 }
175 TypeRef::Reference(inner, _, mutability) => { 175 TypeRef::Reference(inner, _, mutability) => {
176 let inner_ty = self.lower_ty(inner); 176 let inner_ty = self.lower_ty(inner);
177 TyKind::Ref(lower_to_chalk_mutability(*mutability), inner_ty).intern(&Interner) 177 let lifetime = static_lifetime();
178 TyKind::Ref(lower_to_chalk_mutability(*mutability), lifetime, inner_ty)
179 .intern(&Interner)
178 } 180 }
179 TypeRef::Placeholder => TyKind::Unknown.intern(&Interner), 181 TypeRef::Placeholder => TyKind::Error.intern(&Interner),
180 TypeRef::Fn(params, is_varargs) => { 182 TypeRef::Fn(params, is_varargs) => {
181 let substs = Substitution(params.iter().map(|tr| self.lower_ty(tr)).collect()); 183 let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
184 Substitution::from_iter(&Interner, params.iter().map(|tr| ctx.lower_ty(tr)))
185 });
182 TyKind::Function(FnPointer { 186 TyKind::Function(FnPointer {
183 num_args: substs.len() - 1, 187 num_binders: 0, // FIXME lower `for<'a> fn()` correctly
184 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs }, 188 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
185 substs, 189 substitution: FnSubst(substs),
186 }) 190 })
187 .intern(&Interner) 191 .intern(&Interner)
188 } 192 }
@@ -195,8 +199,8 @@ impl<'a> TyLoweringContext<'a> {
195 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)), 199 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
196 ) 200 )
197 }); 201 });
198 let bounds = Binders::new(1, bounds); 202 let bounds = crate::make_only_type_binders(1, bounds);
199 TyKind::Dyn(DynTy { bounds }).intern(&Interner) 203 TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(&Interner)
200 } 204 }
201 TypeRef::ImplTrait(bounds) => { 205 TypeRef::ImplTrait(bounds) => {
202 match self.impl_trait_mode { 206 match self.impl_trait_mode {
@@ -208,9 +212,9 @@ impl<'a> TyLoweringContext<'a> {
208 // this dance is to make sure the data is in the right 212 // this dance is to make sure the data is in the right
209 // place even if we encounter more opaque types while 213 // place even if we encounter more opaque types while
210 // lowering the bounds 214 // lowering the bounds
211 self.opaque_type_data 215 self.opaque_type_data.borrow_mut().push(ReturnTypeImplTrait {
212 .borrow_mut() 216 bounds: crate::make_only_type_binders(1, Vec::new()),
213 .push(ReturnTypeImplTrait { bounds: Binders::new(1, Vec::new()) }); 217 });
214 // We don't want to lower the bounds inside the binders 218 // We don't want to lower the bounds inside the binders
215 // we're currently in, because they don't end up inside 219 // we're currently in, because they don't end up inside
216 // those binders. E.g. when we have `impl Trait<impl 220 // those binders. E.g. when we have `impl Trait<impl
@@ -233,7 +237,7 @@ impl<'a> TyLoweringContext<'a> {
233 let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx); 237 let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx);
234 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into(); 238 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
235 let generics = generics(self.db.upcast(), func.into()); 239 let generics = generics(self.db.upcast(), func.into());
236 let parameters = Substitution::bound_vars(&generics, self.in_binders); 240 let parameters = generics.bound_vars_subst(self.in_binders);
237 TyKind::Alias(AliasTy::Opaque(OpaqueTy { 241 TyKind::Alias(AliasTy::Opaque(OpaqueTy {
238 opaque_ty_id, 242 opaque_ty_id,
239 substitution: parameters, 243 substitution: parameters,
@@ -252,12 +256,12 @@ impl<'a> TyLoweringContext<'a> {
252 data.provenance == TypeParamProvenance::ArgumentImplTrait 256 data.provenance == TypeParamProvenance::ArgumentImplTrait
253 }) 257 })
254 .nth(idx as usize) 258 .nth(idx as usize)
255 .map_or(TyKind::Unknown, |(id, _)| { 259 .map_or(TyKind::Error, |(id, _)| {
256 TyKind::Placeholder(to_placeholder_idx(self.db, id)) 260 TyKind::Placeholder(to_placeholder_idx(self.db, id))
257 }); 261 });
258 param.intern(&Interner) 262 param.intern(&Interner)
259 } else { 263 } else {
260 TyKind::Unknown.intern(&Interner) 264 TyKind::Error.intern(&Interner)
261 } 265 }
262 } 266 }
263 ImplTraitLoweringMode::Variable => { 267 ImplTraitLoweringMode::Variable => {
@@ -279,11 +283,11 @@ impl<'a> TyLoweringContext<'a> {
279 } 283 }
280 ImplTraitLoweringMode::Disallowed => { 284 ImplTraitLoweringMode::Disallowed => {
281 // FIXME: report error 285 // FIXME: report error
282 TyKind::Unknown.intern(&Interner) 286 TyKind::Error.intern(&Interner)
283 } 287 }
284 } 288 }
285 } 289 }
286 TypeRef::Error => TyKind::Unknown.intern(&Interner), 290 TypeRef::Error => TyKind::Error.intern(&Interner),
287 }; 291 };
288 (ty, res) 292 (ty, res)
289 } 293 }
@@ -327,7 +331,7 @@ impl<'a> TyLoweringContext<'a> {
327 (self.select_associated_type(res, segment), None) 331 (self.select_associated_type(res, segment), None)
328 } else if remaining_segments.len() > 1 { 332 } else if remaining_segments.len() > 1 {
329 // FIXME report error (ambiguous associated type) 333 // FIXME report error (ambiguous associated type)
330 (TyKind::Unknown.intern(&Interner), None) 334 (TyKind::Error.intern(&Interner), None)
331 } else { 335 } else {
332 (ty, res) 336 (ty, res)
333 } 337 }
@@ -371,21 +375,24 @@ impl<'a> TyLoweringContext<'a> {
371 } 375 }
372 None => { 376 None => {
373 // FIXME: report error (associated type not found) 377 // FIXME: report error (associated type not found)
374 TyKind::Unknown.intern(&Interner) 378 TyKind::Error.intern(&Interner)
375 } 379 }
376 } 380 }
377 } else if remaining_segments.len() > 1 { 381 } else if remaining_segments.len() > 1 {
378 // FIXME report error (ambiguous associated type) 382 // FIXME report error (ambiguous associated type)
379 TyKind::Unknown.intern(&Interner) 383 TyKind::Error.intern(&Interner)
380 } else { 384 } else {
381 let dyn_ty = DynTy { 385 let dyn_ty = DynTy {
382 bounds: Binders::new( 386 bounds: crate::make_only_type_binders(
383 1, 387 1,
384 QuantifiedWhereClauses::from_iter( 388 QuantifiedWhereClauses::from_iter(
385 &Interner, 389 &Interner,
386 Some(Binders::wrap_empty(WhereClause::Implemented(trait_ref))), 390 Some(crate::wrap_empty_binders(WhereClause::Implemented(
391 trait_ref,
392 ))),
387 ), 393 ),
388 ), 394 ),
395 lifetime: static_lifetime(),
389 }; 396 };
390 TyKind::Dyn(dyn_ty).intern(&Interner) 397 TyKind::Dyn(dyn_ty).intern(&Interner)
391 }; 398 };
@@ -410,26 +417,18 @@ impl<'a> TyLoweringContext<'a> {
410 TypeNs::SelfType(impl_id) => { 417 TypeNs::SelfType(impl_id) => {
411 let generics = generics(self.db.upcast(), impl_id.into()); 418 let generics = generics(self.db.upcast(), impl_id.into());
412 let substs = match self.type_param_mode { 419 let substs = match self.type_param_mode {
413 TypeParamLoweringMode::Placeholder => { 420 TypeParamLoweringMode::Placeholder => generics.type_params_subst(self.db),
414 Substitution::type_params_for_generics(self.db, &generics) 421 TypeParamLoweringMode::Variable => generics.bound_vars_subst(self.in_binders),
415 }
416 TypeParamLoweringMode::Variable => {
417 Substitution::bound_vars(&generics, self.in_binders)
418 }
419 }; 422 };
420 self.db.impl_self_ty(impl_id).subst(&substs) 423 self.db.impl_self_ty(impl_id).substitute(&Interner, &substs)
421 } 424 }
422 TypeNs::AdtSelfType(adt) => { 425 TypeNs::AdtSelfType(adt) => {
423 let generics = generics(self.db.upcast(), adt.into()); 426 let generics = generics(self.db.upcast(), adt.into());
424 let substs = match self.type_param_mode { 427 let substs = match self.type_param_mode {
425 TypeParamLoweringMode::Placeholder => { 428 TypeParamLoweringMode::Placeholder => generics.type_params_subst(self.db),
426 Substitution::type_params_for_generics(self.db, &generics) 429 TypeParamLoweringMode::Variable => generics.bound_vars_subst(self.in_binders),
427 }
428 TypeParamLoweringMode::Variable => {
429 Substitution::bound_vars(&generics, self.in_binders)
430 }
431 }; 430 };
432 self.db.ty(adt.into()).subst(&substs) 431 self.db.ty(adt.into()).substitute(&Interner, &substs)
433 } 432 }
434 433
435 TypeNs::AdtId(it) => self.lower_path_inner(resolved_segment, it.into(), infer_args), 434 TypeNs::AdtId(it) => self.lower_path_inner(resolved_segment, it.into(), infer_args),
@@ -440,7 +439,7 @@ impl<'a> TyLoweringContext<'a> {
440 self.lower_path_inner(resolved_segment, it.into(), infer_args) 439 self.lower_path_inner(resolved_segment, it.into(), infer_args)
441 } 440 }
442 // FIXME: report error 441 // FIXME: report error
443 TypeNs::EnumVariantId(_) => return (TyKind::Unknown.intern(&Interner), None), 442 TypeNs::EnumVariantId(_) => return (TyKind::Error.intern(&Interner), None),
444 }; 443 };
445 self.lower_ty_relative_path(ty, Some(resolution), remaining_segments) 444 self.lower_ty_relative_path(ty, Some(resolution), remaining_segments)
446 } 445 }
@@ -454,7 +453,7 @@ impl<'a> TyLoweringContext<'a> {
454 let (resolution, remaining_index) = 453 let (resolution, remaining_index) =
455 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) { 454 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
456 Some(it) => it, 455 Some(it) => it,
457 None => return (TyKind::Unknown.intern(&Interner), None), 456 None => return (TyKind::Error.intern(&Interner), None),
458 }; 457 };
459 let (resolved_segment, remaining_segments) = match remaining_index { 458 let (resolved_segment, remaining_segments) = match remaining_index {
460 None => ( 459 None => (
@@ -477,19 +476,20 @@ impl<'a> TyLoweringContext<'a> {
477 TypeParamLoweringMode::Placeholder => { 476 TypeParamLoweringMode::Placeholder => {
478 // if we're lowering to placeholders, we have to put 477 // if we're lowering to placeholders, we have to put
479 // them in now 478 // them in now
480 let s = Substitution::type_params( 479 let generics = generics(
481 self.db, 480 self.db.upcast(),
482 self.resolver.generic_def().expect( 481 self.resolver.generic_def().expect(
483 "there should be generics if there's a generic param", 482 "there should be generics if there's a generic param",
484 ), 483 ),
485 ); 484 );
486 t.substitution.clone().subst_bound_vars(&s) 485 let s = generics.type_params_subst(self.db);
486 s.apply(t.substitution.clone(), &Interner)
487 } 487 }
488 TypeParamLoweringMode::Variable => t.substitution.clone(), 488 TypeParamLoweringMode::Variable => t.substitution.clone(),
489 }; 489 };
490 // We need to shift in the bound vars, since 490 // We need to shift in the bound vars, since
491 // associated_type_shorthand_candidates does not do that 491 // associated_type_shorthand_candidates does not do that
492 let substs = substs.shift_bound_vars(self.in_binders); 492 let substs = substs.shifted_in_from(&Interner, self.in_binders);
493 // FIXME handle type parameters on the segment 493 // FIXME handle type parameters on the segment
494 return Some( 494 return Some(
495 TyKind::Alias(AliasTy::Projection(ProjectionTy { 495 TyKind::Alias(AliasTy::Projection(ProjectionTy {
@@ -504,9 +504,9 @@ impl<'a> TyLoweringContext<'a> {
504 }, 504 },
505 ); 505 );
506 506
507 ty.unwrap_or(TyKind::Unknown.intern(&Interner)) 507 ty.unwrap_or(TyKind::Error.intern(&Interner))
508 } else { 508 } else {
509 TyKind::Unknown.intern(&Interner) 509 TyKind::Error.intern(&Interner)
510 } 510 }
511 } 511 }
512 512
@@ -522,7 +522,7 @@ impl<'a> TyLoweringContext<'a> {
522 TyDefId::TypeAliasId(it) => Some(it.into()), 522 TyDefId::TypeAliasId(it) => Some(it.into()),
523 }; 523 };
524 let substs = self.substs_from_path_segment(segment, generic_def, infer_args, None); 524 let substs = self.substs_from_path_segment(segment, generic_def, infer_args, None);
525 self.db.ty(typeable).subst(&substs) 525 self.db.ty(typeable).substitute(&Interner, &substs)
526 } 526 }
527 527
528 /// Collect generic arguments from a path into a `Substs`. See also 528 /// Collect generic arguments from a path into a `Substs`. See also
@@ -575,13 +575,13 @@ impl<'a> TyLoweringContext<'a> {
575 def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split()); 575 def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split());
576 let total_len = parent_params + self_params + type_params + impl_trait_params; 576 let total_len = parent_params + self_params + type_params + impl_trait_params;
577 577
578 substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(parent_params)); 578 substs.extend(iter::repeat(TyKind::Error.intern(&Interner)).take(parent_params));
579 579
580 let fill_self_params = || { 580 let fill_self_params = || {
581 substs.extend( 581 substs.extend(
582 explicit_self_ty 582 explicit_self_ty
583 .into_iter() 583 .into_iter()
584 .chain(iter::repeat(TyKind::Unknown.intern(&Interner))) 584 .chain(iter::repeat(TyKind::Error.intern(&Interner)))
585 .take(self_params), 585 .take(self_params),
586 ) 586 )
587 }; 587 };
@@ -625,8 +625,8 @@ impl<'a> TyLoweringContext<'a> {
625 625
626 for default_ty in defaults.iter().skip(substs.len()) { 626 for default_ty in defaults.iter().skip(substs.len()) {
627 // each default can depend on the previous parameters 627 // each default can depend on the previous parameters
628 let substs_so_far = Substitution(substs.clone().into()); 628 let substs_so_far = Substitution::from_iter(&Interner, substs.clone());
629 substs.push(default_ty.clone().subst(&substs_so_far)); 629 substs.push(default_ty.clone().substitute(&Interner, &substs_so_far));
630 } 630 }
631 } 631 }
632 } 632 }
@@ -634,11 +634,11 @@ impl<'a> TyLoweringContext<'a> {
634 // add placeholders for args that were not provided 634 // add placeholders for args that were not provided
635 // FIXME: emit diagnostics in contexts where this is not allowed 635 // FIXME: emit diagnostics in contexts where this is not allowed
636 for _ in substs.len()..total_len { 636 for _ in substs.len()..total_len {
637 substs.push(TyKind::Unknown.intern(&Interner)); 637 substs.push(TyKind::Error.intern(&Interner));
638 } 638 }
639 assert_eq!(substs.len(), total_len); 639 assert_eq!(substs.len(), total_len);
640 640
641 Substitution(substs.into()) 641 Substitution::from_iter(&Interner, substs)
642 } 642 }
643 643
644 fn lower_trait_ref_from_path( 644 fn lower_trait_ref_from_path(
@@ -667,14 +667,10 @@ impl<'a> TyLoweringContext<'a> {
667 667
668 fn lower_trait_ref( 668 fn lower_trait_ref(
669 &self, 669 &self,
670 type_ref: &TypeRef, 670 trait_ref: &HirTraitRef,
671 explicit_self_ty: Option<Ty>, 671 explicit_self_ty: Option<Ty>,
672 ) -> Option<TraitRef> { 672 ) -> Option<TraitRef> {
673 let path = match type_ref { 673 self.lower_trait_ref_from_path(&trait_ref.path, explicit_self_ty)
674 TypeRef::Path(path) => path,
675 _ => return None,
676 };
677 self.lower_trait_ref_from_path(path, explicit_self_ty)
678 } 674 }
679 675
680 fn trait_ref_substs_from_path( 676 fn trait_ref_substs_from_path(
@@ -730,7 +726,7 @@ impl<'a> TyLoweringContext<'a> {
730 let trait_ref = match bound { 726 let trait_ref = match bound {
731 TypeBound::Path(path) => { 727 TypeBound::Path(path) => {
732 bindings = self.lower_trait_ref_from_path(path, Some(self_ty)); 728 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
733 bindings.clone().map(WhereClause::Implemented).map(|b| Binders::wrap_empty(b)) 729 bindings.clone().map(WhereClause::Implemented).map(|b| crate::wrap_empty_binders(b))
734 } 730 }
735 TypeBound::Lifetime(_) => None, 731 TypeBound::Lifetime(_) => None,
736 TypeBound::Error => None, 732 TypeBound::Error => None,
@@ -777,7 +773,7 @@ impl<'a> TyLoweringContext<'a> {
777 let ty = self.lower_ty(type_ref); 773 let ty = self.lower_ty(type_ref);
778 let alias_eq = 774 let alias_eq =
779 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty }; 775 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
780 preds.push(Binders::wrap_empty(WhereClause::AliasEq(alias_eq))); 776 preds.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
781 } 777 }
782 for bound in &binding.bounds { 778 for bound in &binding.bounds {
783 preds.extend(self.lower_type_bound( 779 preds.extend(self.lower_type_bound(
@@ -797,7 +793,7 @@ impl<'a> TyLoweringContext<'a> {
797 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { 793 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
798 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)).collect() 794 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)).collect()
799 }); 795 });
800 ReturnTypeImplTrait { bounds: Binders::new(1, predicates) } 796 ReturnTypeImplTrait { bounds: crate::make_only_type_binders(1, predicates) }
801 } 797 }
802} 798}
803 799
@@ -825,58 +821,57 @@ pub fn associated_type_shorthand_candidates<R>(
825 res: TypeNs, 821 res: TypeNs,
826 mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>, 822 mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
827) -> Option<R> { 823) -> Option<R> {
828 let traits_from_env: Vec<_> = match res { 824 let mut search = |t| {
829 TypeNs::SelfType(impl_id) => match db.impl_trait(impl_id) { 825 for t in all_super_trait_refs(db, t) {
830 None => vec![], 826 let data = db.trait_data(t.hir_trait_id());
831 // FIXME: how to correctly handle higher-ranked bounds here? 827
832 Some(trait_ref) => vec![trait_ref.value.shift_bound_vars_out(DebruijnIndex::ONE)], 828 for (name, assoc_id) in &data.items {
833 }, 829 if let AssocItemId::TypeAliasId(alias) = assoc_id {
830 if let Some(result) = cb(name, &t, *alias) {
831 return Some(result);
832 }
833 }
834 }
835 }
836 None
837 };
838
839 match res {
840 TypeNs::SelfType(impl_id) => search(
841 // we're _in_ the impl -- the binders get added back later. Correct,
842 // but it would be nice to make this more explicit
843 db.impl_trait(impl_id)?.into_value_and_skipped_binders().0,
844 ),
834 TypeNs::GenericParam(param_id) => { 845 TypeNs::GenericParam(param_id) => {
835 let predicates = db.generic_predicates_for_param(param_id); 846 let predicates = db.generic_predicates_for_param(param_id);
836 let mut traits_: Vec<_> = predicates 847 let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() {
837 .iter() 848 // FIXME: how to correctly handle higher-ranked bounds here?
838 .filter_map(|pred| match &pred.value.value { 849 WhereClause::Implemented(tr) => search(
839 // FIXME: how to correctly handle higher-ranked bounds here? 850 tr.clone()
840 WhereClause::Implemented(tr) => { 851 .shifted_out_to(&Interner, DebruijnIndex::ONE)
841 Some(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE)) 852 .expect("FIXME unexpected higher-ranked trait bound"),
842 } 853 ),
843 _ => None, 854 _ => None,
844 }) 855 });
845 .collect(); 856 if let res @ Some(_) = res {
857 return res;
858 }
846 // Handle `Self::Type` referring to own associated type in trait definitions 859 // Handle `Self::Type` referring to own associated type in trait definitions
847 if let GenericDefId::TraitId(trait_id) = param_id.parent { 860 if let GenericDefId::TraitId(trait_id) = param_id.parent {
848 let generics = generics(db.upcast(), trait_id.into()); 861 let generics = generics(db.upcast(), trait_id.into());
849 if generics.params.types[param_id.local_id].provenance 862 if generics.params.types[param_id.local_id].provenance
850 == TypeParamProvenance::TraitSelf 863 == TypeParamProvenance::TraitSelf
851 { 864 {
852 let trait_ref = TraitRef { 865 let trait_ref = TyBuilder::trait_ref(db, trait_id)
853 trait_id: to_chalk_trait_id(trait_id), 866 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
854 substitution: Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST), 867 .build();
855 }; 868 return search(trait_ref);
856 traits_.push(trait_ref);
857 } 869 }
858 } 870 }
859 traits_ 871 None
860 }
861 _ => vec![],
862 };
863
864 for t in traits_from_env.into_iter().flat_map(move |t| all_super_trait_refs(db, t)) {
865 let data = db.trait_data(t.hir_trait_id());
866
867 for (name, assoc_id) in &data.items {
868 match assoc_id {
869 AssocItemId::TypeAliasId(alias) => {
870 if let Some(result) = cb(name, &t, *alias) {
871 return Some(result);
872 }
873 }
874 AssocItemId::FunctionId(_) | AssocItemId::ConstId(_) => {}
875 }
876 } 872 }
873 _ => None,
877 } 874 }
878
879 None
880} 875}
881 876
882/// Build the type of all specific fields of a struct or enum variant. 877/// Build the type of all specific fields of a struct or enum variant.
@@ -884,7 +879,7 @@ pub(crate) fn field_types_query(
884 db: &dyn HirDatabase, 879 db: &dyn HirDatabase,
885 variant_id: VariantId, 880 variant_id: VariantId,
886) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>> { 881) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>> {
887 let var_data = variant_data(db.upcast(), variant_id); 882 let var_data = variant_id.variant_data(db.upcast());
888 let (resolver, def): (_, GenericDefId) = match variant_id { 883 let (resolver, def): (_, GenericDefId) = match variant_id {
889 VariantId::StructId(it) => (it.resolver(db.upcast()), it.into()), 884 VariantId::StructId(it) => (it.resolver(db.upcast()), it.into()),
890 VariantId::UnionId(it) => (it.resolver(db.upcast()), it.into()), 885 VariantId::UnionId(it) => (it.resolver(db.upcast()), it.into()),
@@ -895,7 +890,7 @@ pub(crate) fn field_types_query(
895 let ctx = 890 let ctx =
896 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 891 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
897 for (field_id, field_data) in var_data.fields().iter() { 892 for (field_id, field_data) in var_data.fields().iter() {
898 res.insert(field_id, Binders::new(generics.len(), ctx.lower_ty(&field_data.type_ref))) 893 res.insert(field_id, make_binders(&generics, ctx.lower_ty(&field_data.type_ref)))
899 } 894 }
900 Arc::new(res) 895 Arc::new(res)
901} 896}
@@ -929,9 +924,7 @@ pub(crate) fn generic_predicates_for_param_query(
929 }, 924 },
930 WherePredicate::Lifetime { .. } => false, 925 WherePredicate::Lifetime { .. } => false,
931 }) 926 })
932 .flat_map(|pred| { 927 .flat_map(|pred| ctx.lower_where_predicate(pred, true).map(|p| make_binders(&generics, p)))
933 ctx.lower_where_predicate(pred, true).map(|p| Binders::new(generics.len(), p))
934 })
935 .collect() 928 .collect()
936} 929}
937 930
@@ -955,10 +948,10 @@ pub(crate) fn trait_environment_query(
955 for pred in resolver.where_predicates_in_scope() { 948 for pred in resolver.where_predicates_in_scope() {
956 for pred in ctx.lower_where_predicate(pred, false) { 949 for pred in ctx.lower_where_predicate(pred, false) {
957 if let WhereClause::Implemented(tr) = &pred.skip_binders() { 950 if let WhereClause::Implemented(tr) = &pred.skip_binders() {
958 traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id())); 951 traits_in_scope
952 .push((tr.self_type_parameter(&Interner).clone(), tr.hir_trait_id()));
959 } 953 }
960 let program_clause: chalk_ir::ProgramClause<Interner> = 954 let program_clause: chalk_ir::ProgramClause<Interner> = pred.clone().cast(&Interner);
961 pred.clone().to_chalk(db).cast(&Interner);
962 clauses.push(program_clause.into_from_env_clause(&Interner)); 955 clauses.push(program_clause.into_from_env_clause(&Interner));
963 } 956 }
964 } 957 }
@@ -978,10 +971,10 @@ pub(crate) fn trait_environment_query(
978 // function default implementations (and hypothetical code 971 // function default implementations (and hypothetical code
979 // inside consts or type aliases) 972 // inside consts or type aliases)
980 cov_mark::hit!(trait_self_implements_self); 973 cov_mark::hit!(trait_self_implements_self);
981 let substs = Substitution::type_params(db, trait_id); 974 let substs = TyBuilder::type_params_subst(db, trait_id);
982 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs }; 975 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
983 let pred = WhereClause::Implemented(trait_ref); 976 let pred = WhereClause::Implemented(trait_ref);
984 let program_clause: chalk_ir::ProgramClause<Interner> = pred.to_chalk(db).cast(&Interner); 977 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(&Interner);
985 clauses.push(program_clause.into_from_env_clause(&Interner)); 978 clauses.push(program_clause.into_from_env_clause(&Interner));
986 } 979 }
987 980
@@ -1001,9 +994,7 @@ pub(crate) fn generic_predicates_query(
1001 let generics = generics(db.upcast(), def); 994 let generics = generics(db.upcast(), def);
1002 resolver 995 resolver
1003 .where_predicates_in_scope() 996 .where_predicates_in_scope()
1004 .flat_map(|pred| { 997 .flat_map(|pred| ctx.lower_where_predicate(pred, false).map(|p| make_binders(&generics, p)))
1005 ctx.lower_where_predicate(pred, false).map(|p| Binders::new(generics.len(), p))
1006 })
1007 .collect() 998 .collect()
1008} 999}
1009 1000
@@ -1022,25 +1013,21 @@ pub(crate) fn generic_defaults_query(
1022 .enumerate() 1013 .enumerate()
1023 .map(|(idx, (_, p))| { 1014 .map(|(idx, (_, p))| {
1024 let mut ty = 1015 let mut ty =
1025 p.default.as_ref().map_or(TyKind::Unknown.intern(&Interner), |t| ctx.lower_ty(t)); 1016 p.default.as_ref().map_or(TyKind::Error.intern(&Interner), |t| ctx.lower_ty(t));
1026 1017
1027 // Each default can only refer to previous parameters. 1018 // Each default can only refer to previous parameters.
1028 ty.walk_mut_binders( 1019 ty = crate::fold_free_vars(ty, |bound, binders| {
1029 &mut |ty, binders| match ty.interned_mut() { 1020 if bound.index >= idx && bound.debruijn == DebruijnIndex::INNERMOST {
1030 TyKind::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => { 1021 // type variable default referring to parameter coming
1031 if *index >= idx { 1022 // after it. This is forbidden (FIXME: report
1032 // type variable default referring to parameter coming 1023 // diagnostic)
1033 // after it. This is forbidden (FIXME: report 1024 TyKind::Error.intern(&Interner)
1034 // diagnostic) 1025 } else {
1035 *ty = TyKind::Unknown.intern(&Interner); 1026 bound.shifted_in_from(binders).to_ty(&Interner)
1036 } 1027 }
1037 } 1028 });
1038 _ => {}
1039 },
1040 DebruijnIndex::INNERMOST,
1041 );
1042 1029
1043 Binders::new(idx, ty) 1030 crate::make_only_type_binders(idx, ty)
1044 }) 1031 })
1045 .collect(); 1032 .collect();
1046 1033
@@ -1053,23 +1040,22 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1053 let ctx_params = TyLoweringContext::new(db, &resolver) 1040 let ctx_params = TyLoweringContext::new(db, &resolver)
1054 .with_impl_trait_mode(ImplTraitLoweringMode::Variable) 1041 .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
1055 .with_type_param_mode(TypeParamLoweringMode::Variable); 1042 .with_type_param_mode(TypeParamLoweringMode::Variable);
1056 let params = data.params.iter().map(|tr| (&ctx_params).lower_ty(tr)).collect::<Vec<_>>(); 1043 let params = data.params.iter().map(|tr| ctx_params.lower_ty(tr)).collect::<Vec<_>>();
1057 let ctx_ret = TyLoweringContext::new(db, &resolver) 1044 let ctx_ret = TyLoweringContext::new(db, &resolver)
1058 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) 1045 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1059 .with_type_param_mode(TypeParamLoweringMode::Variable); 1046 .with_type_param_mode(TypeParamLoweringMode::Variable);
1060 let ret = (&ctx_ret).lower_ty(&data.ret_type); 1047 let ret = ctx_ret.lower_ty(&data.ret_type);
1061 let generics = generics(db.upcast(), def.into()); 1048 let generics = generics(db.upcast(), def.into());
1062 let num_binders = generics.len(); 1049 make_binders(&generics, CallableSig::from_params_and_return(params, ret, data.is_varargs()))
1063 Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs))
1064} 1050}
1065 1051
1066/// Build the declared type of a function. This should not need to look at the 1052/// Build the declared type of a function. This should not need to look at the
1067/// function body. 1053/// function body.
1068fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { 1054fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1069 let generics = generics(db.upcast(), def.into()); 1055 let generics = generics(db.upcast(), def.into());
1070 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); 1056 let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST);
1071 Binders::new( 1057 make_binders(
1072 substs.len(), 1058 &generics,
1073 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner), 1059 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner),
1074 ) 1060 )
1075} 1061}
@@ -1082,7 +1068,7 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
1082 let ctx = 1068 let ctx =
1083 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1069 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1084 1070
1085 Binders::new(generics.len(), ctx.lower_ty(&data.type_ref)) 1071 make_binders(&generics, ctx.lower_ty(&data.type_ref))
1086} 1072}
1087 1073
1088/// Build the declared type of a static. 1074/// Build the declared type of a static.
@@ -1091,7 +1077,7 @@ fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
1091 let resolver = def.resolver(db.upcast()); 1077 let resolver = def.resolver(db.upcast());
1092 let ctx = TyLoweringContext::new(db, &resolver); 1078 let ctx = TyLoweringContext::new(db, &resolver);
1093 1079
1094 Binders::new(0, ctx.lower_ty(&data.type_ref)) 1080 Binders::empty(&Interner, ctx.lower_ty(&data.type_ref))
1095} 1081}
1096 1082
1097fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig { 1083fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig {
@@ -1101,8 +1087,8 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
1101 let ctx = 1087 let ctx =
1102 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1088 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1103 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>(); 1089 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1104 let ret = type_for_adt(db, def.into()); 1090 let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
1105 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) 1091 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1106} 1092}
1107 1093
1108/// Build the type of a tuple struct constructor. 1094/// Build the type of a tuple struct constructor.
@@ -1112,9 +1098,9 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T
1112 return type_for_adt(db, def.into()); 1098 return type_for_adt(db, def.into());
1113 } 1099 }
1114 let generics = generics(db.upcast(), def.into()); 1100 let generics = generics(db.upcast(), def.into());
1115 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); 1101 let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST);
1116 Binders::new( 1102 make_binders(
1117 substs.len(), 1103 &generics,
1118 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner), 1104 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner),
1119 ) 1105 )
1120} 1106}
@@ -1127,8 +1113,8 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
1127 let ctx = 1113 let ctx =
1128 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1114 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1129 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>(); 1115 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1130 let ret = type_for_adt(db, def.parent.into()); 1116 let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
1131 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) 1117 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1132} 1118}
1133 1119
1134/// Build the type of a tuple enum variant constructor. 1120/// Build the type of a tuple enum variant constructor.
@@ -1139,17 +1125,18 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
1139 return type_for_adt(db, def.parent.into()); 1125 return type_for_adt(db, def.parent.into());
1140 } 1126 }
1141 let generics = generics(db.upcast(), def.parent.into()); 1127 let generics = generics(db.upcast(), def.parent.into());
1142 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); 1128 let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST);
1143 Binders::new( 1129 make_binders(
1144 substs.len(), 1130 &generics,
1145 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner), 1131 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner),
1146 ) 1132 )
1147} 1133}
1148 1134
1149fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { 1135fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1150 let generics = generics(db.upcast(), adt.into()); 1136 let generics = generics(db.upcast(), adt.into());
1151 let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST); 1137 let b = TyBuilder::adt(db, adt);
1152 Binders::new(substs.len(), Ty::adt_ty(adt, substs)) 1138 let ty = b.fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build();
1139 make_binders(&generics, ty)
1153} 1140}
1154 1141
1155fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { 1142fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
@@ -1158,11 +1145,11 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1158 let ctx = 1145 let ctx =
1159 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1146 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1160 if db.type_alias_data(t).is_extern { 1147 if db.type_alias_data(t).is_extern {
1161 Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner)) 1148 Binders::empty(&Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(&Interner))
1162 } else { 1149 } else {
1163 let type_ref = &db.type_alias_data(t).type_ref; 1150 let type_ref = &db.type_alias_data(t).type_ref;
1164 let inner = ctx.lower_ty(type_ref.as_ref().unwrap_or(&TypeRef::Error)); 1151 let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error));
1165 Binders::new(generics.len(), inner) 1152 make_binders(&generics, inner)
1166 } 1153 }
1167} 1154}
1168 1155
@@ -1221,19 +1208,21 @@ impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for V
1221/// namespace. 1208/// namespace.
1222pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> { 1209pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> {
1223 match def { 1210 match def {
1224 TyDefId::BuiltinType(it) => Binders::new(0, Ty::builtin(it)), 1211 TyDefId::BuiltinType(it) => Binders::empty(&Interner, TyBuilder::builtin(it)),
1225 TyDefId::AdtId(it) => type_for_adt(db, it), 1212 TyDefId::AdtId(it) => type_for_adt(db, it),
1226 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), 1213 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
1227 } 1214 }
1228} 1215}
1229 1216
1230pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> { 1217pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> {
1231 let num_binders = match *def { 1218 let generics = match *def {
1232 TyDefId::BuiltinType(_) => 0, 1219 TyDefId::BuiltinType(_) => {
1233 TyDefId::AdtId(it) => generics(db.upcast(), it.into()).len(), 1220 return Binders::empty(&Interner, TyKind::Error.intern(&Interner))
1234 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()).len(), 1221 }
1222 TyDefId::AdtId(it) => generics(db.upcast(), it.into()),
1223 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()),
1235 }; 1224 };
1236 Binders::new(num_binders, TyKind::Unknown.intern(&Interner)) 1225 make_binders(&generics, TyKind::Error.intern(&Interner))
1237} 1226}
1238 1227
1239pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> { 1228pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
@@ -1253,7 +1242,7 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde
1253 let generics = generics(db.upcast(), impl_id.into()); 1242 let generics = generics(db.upcast(), impl_id.into());
1254 let ctx = 1243 let ctx =
1255 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1244 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1256 Binders::new(generics.len(), ctx.lower_ty(&impl_data.target_type)) 1245 make_binders(&generics, ctx.lower_ty(&impl_data.self_ty))
1257} 1246}
1258 1247
1259pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { 1248pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
@@ -1271,7 +1260,7 @@ pub(crate) fn impl_self_ty_recover(
1271 impl_id: &ImplId, 1260 impl_id: &ImplId,
1272) -> Binders<Ty> { 1261) -> Binders<Ty> {
1273 let generics = generics(db.upcast(), (*impl_id).into()); 1262 let generics = generics(db.upcast(), (*impl_id).into());
1274 Binders::new(generics.len(), TyKind::Unknown.intern(&Interner)) 1263 make_binders(&generics, TyKind::Error.intern(&Interner))
1275} 1264}
1276 1265
1277pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { 1266pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
@@ -1279,9 +1268,9 @@ pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<
1279 let resolver = impl_id.resolver(db.upcast()); 1268 let resolver = impl_id.resolver(db.upcast());
1280 let ctx = 1269 let ctx =
1281 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1270 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1282 let self_ty = db.impl_self_ty(impl_id); 1271 let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
1283 let target_trait = impl_data.target_trait.as_ref()?; 1272 let target_trait = impl_data.target_trait.as_ref()?;
1284 Some(Binders::new(self_ty.num_binders, ctx.lower_trait_ref(target_trait, Some(self_ty.value))?)) 1273 Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?))
1285} 1274}
1286 1275
1287pub(crate) fn return_type_impl_traits( 1276pub(crate) fn return_type_impl_traits(
@@ -1296,13 +1285,12 @@ pub(crate) fn return_type_impl_traits(
1296 .with_type_param_mode(TypeParamLoweringMode::Variable); 1285 .with_type_param_mode(TypeParamLoweringMode::Variable);
1297 let _ret = (&ctx_ret).lower_ty(&data.ret_type); 1286 let _ret = (&ctx_ret).lower_ty(&data.ret_type);
1298 let generics = generics(db.upcast(), def.into()); 1287 let generics = generics(db.upcast(), def.into());
1299 let num_binders = generics.len();
1300 let return_type_impl_traits = 1288 let return_type_impl_traits =
1301 ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() }; 1289 ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() };
1302 if return_type_impl_traits.impl_traits.is_empty() { 1290 if return_type_impl_traits.impl_traits.is_empty() {
1303 None 1291 None
1304 } else { 1292 } else {
1305 Some(Arc::new(Binders::new(num_binders, return_type_impl_traits))) 1293 Some(Arc::new(make_binders(&generics, return_type_impl_traits)))
1306 } 1294 }
1307} 1295}
1308 1296
@@ -1312,3 +1300,7 @@ pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mut
1312 hir_def::type_ref::Mutability::Mut => Mutability::Mut, 1300 hir_def::type_ref::Mutability::Mut => Mutability::Mut,
1313 } 1301 }
1314} 1302}
1303
1304fn make_binders<T: HasInterner<Interner = Interner>>(generics: &Generics, value: T) -> Binders<T> {
1305 crate::make_only_type_binders(generics.len(), value)
1306}
diff --git a/crates/hir_ty/src/mapping.rs b/crates/hir_ty/src/mapping.rs
new file mode 100644
index 000000000..5e86fafe5
--- /dev/null
+++ b/crates/hir_ty/src/mapping.rs
@@ -0,0 +1,154 @@
1//! This module contains the implementations of the `ToChalk` trait, which
2//! handles conversion between our data types and their corresponding types in
3//! Chalk (in both directions); plus some helper functions for more specialized
4//! conversions.
5
6use chalk_solve::rust_ir;
7
8use base_db::salsa::{self, InternKey};
9use hir_def::{ConstParamId, LifetimeParamId, TraitId, TypeAliasId, TypeParamId};
10
11use crate::{
12 chalk_db, db::HirDatabase, AssocTypeId, CallableDefId, ChalkTraitId, FnDefId, ForeignDefId,
13 Interner, OpaqueTyId, PlaceholderIndex,
14};
15
16pub(crate) trait ToChalk {
17 type Chalk;
18 fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk;
19 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self;
20}
21
22pub(crate) fn from_chalk<T, ChalkT>(db: &dyn HirDatabase, chalk: ChalkT) -> T
23where
24 T: ToChalk<Chalk = ChalkT>,
25{
26 T::from_chalk(db, chalk)
27}
28
29impl ToChalk for hir_def::ImplId {
30 type Chalk = chalk_db::ImplId;
31
32 fn to_chalk(self, _db: &dyn HirDatabase) -> chalk_db::ImplId {
33 chalk_ir::ImplId(self.as_intern_id())
34 }
35
36 fn from_chalk(_db: &dyn HirDatabase, impl_id: chalk_db::ImplId) -> hir_def::ImplId {
37 InternKey::from_intern_id(impl_id.0)
38 }
39}
40
41impl ToChalk for CallableDefId {
42 type Chalk = FnDefId;
43
44 fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId {
45 db.intern_callable_def(self).into()
46 }
47
48 fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDefId {
49 db.lookup_intern_callable_def(fn_def_id.into())
50 }
51}
52
53pub(crate) struct TypeAliasAsValue(pub(crate) TypeAliasId);
54
55impl ToChalk for TypeAliasAsValue {
56 type Chalk = chalk_db::AssociatedTyValueId;
57
58 fn to_chalk(self, _db: &dyn HirDatabase) -> chalk_db::AssociatedTyValueId {
59 rust_ir::AssociatedTyValueId(self.0.as_intern_id())
60 }
61
62 fn from_chalk(
63 _db: &dyn HirDatabase,
64 assoc_ty_value_id: chalk_db::AssociatedTyValueId,
65 ) -> TypeAliasAsValue {
66 TypeAliasAsValue(TypeAliasId::from_intern_id(assoc_ty_value_id.0))
67 }
68}
69
70impl From<FnDefId> for crate::db::InternedCallableDefId {
71 fn from(fn_def_id: FnDefId) -> Self {
72 InternKey::from_intern_id(fn_def_id.0)
73 }
74}
75
76impl From<crate::db::InternedCallableDefId> for FnDefId {
77 fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self {
78 chalk_ir::FnDefId(callable_def_id.as_intern_id())
79 }
80}
81
82impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId {
83 fn from(id: OpaqueTyId) -> Self {
84 InternKey::from_intern_id(id.0)
85 }
86}
87
88impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId {
89 fn from(id: crate::db::InternedOpaqueTyId) -> Self {
90 chalk_ir::OpaqueTyId(id.as_intern_id())
91 }
92}
93
94impl From<chalk_ir::ClosureId<Interner>> for crate::db::InternedClosureId {
95 fn from(id: chalk_ir::ClosureId<Interner>) -> Self {
96 Self::from_intern_id(id.0)
97 }
98}
99
100impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> {
101 fn from(id: crate::db::InternedClosureId) -> Self {
102 chalk_ir::ClosureId(id.as_intern_id())
103 }
104}
105
106pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId {
107 chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id))
108}
109
110pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId {
111 salsa::InternKey::from_intern_id(id.0)
112}
113
114pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId {
115 chalk_ir::AssocTypeId(salsa::InternKey::as_intern_id(&id))
116}
117
118pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId {
119 salsa::InternKey::from_intern_id(id.0)
120}
121
122pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeParamId {
123 assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT);
124 let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx));
125 db.lookup_intern_type_param_id(interned_id)
126}
127
128pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderIndex {
129 let interned_id = db.intern_type_param_id(id);
130 PlaceholderIndex {
131 ui: chalk_ir::UniverseIndex::ROOT,
132 idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(),
133 }
134}
135
136pub fn lt_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> LifetimeParamId {
137 assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT);
138 let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx));
139 db.lookup_intern_lifetime_param_id(interned_id)
140}
141
142pub fn const_from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> ConstParamId {
143 assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT);
144 let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx));
145 db.lookup_intern_const_param_id(interned_id)
146}
147
148pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId {
149 chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id))
150}
151
152pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId {
153 salsa::InternKey::from_intern_id(id.0)
154}
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index bf7d5eded..3693e3284 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -8,8 +8,8 @@ use arrayvec::ArrayVec;
8use base_db::CrateId; 8use base_db::CrateId;
9use chalk_ir::{cast::Cast, Mutability, UniverseIndex}; 9use chalk_ir::{cast::Cast, Mutability, UniverseIndex};
10use hir_def::{ 10use hir_def::{
11 lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, 11 lang_item::LangItemTarget, nameres::DefMap, AssocContainerId, AssocItemId, FunctionId,
12 ImplId, Lookup, ModuleId, TraitId, 12 GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId,
13}; 13};
14use hir_expand::name::Name; 14use hir_expand::name::Name;
15use rustc_hash::{FxHashMap, FxHashSet}; 15use rustc_hash::{FxHashMap, FxHashSet};
@@ -19,52 +19,91 @@ use crate::{
19 db::HirDatabase, 19 db::HirDatabase,
20 from_foreign_def_id, 20 from_foreign_def_id,
21 primitive::{self, FloatTy, IntTy, UintTy}, 21 primitive::{self, FloatTy, IntTy, UintTy},
22 to_chalk_trait_id, 22 static_lifetime,
23 utils::all_super_traits, 23 utils::all_super_traits,
24 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, 24 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, ForeignDefId, InEnvironment, Interner,
25 InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, 25 Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyExt, TyKind,
26 TypeWalk,
27}; 26};
28 27
29/// This is used as a key for indexing impls. 28/// This is used as a key for indexing impls.
30#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 29#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
31pub enum TyFingerprint { 30pub enum TyFingerprint {
31 // These are lang item impls:
32 Str, 32 Str,
33 Slice, 33 Slice,
34 Array, 34 Array,
35 Never, 35 Never,
36 RawPtr(Mutability), 36 RawPtr(Mutability),
37 Scalar(Scalar), 37 Scalar(Scalar),
38 // These can have user-defined impls:
38 Adt(hir_def::AdtId), 39 Adt(hir_def::AdtId),
39 Dyn(TraitId), 40 Dyn(TraitId),
40 Tuple(usize),
41 ForeignType(ForeignDefId), 41 ForeignType(ForeignDefId),
42 FnPtr(usize, FnSig), 42 // These only exist for trait impls
43 Unit,
44 Unnameable,
45 Function(u32),
43} 46}
44 47
45impl TyFingerprint { 48impl TyFingerprint {
46 /// Creates a TyFingerprint for looking up an impl. Only certain types can 49 /// Creates a TyFingerprint for looking up an inherent impl. Only certain
47 /// have impls: if we have some `struct S`, we can have an `impl S`, but not 50 /// types can have inherent impls: if we have some `struct S`, we can have
48 /// `impl &S`. Hence, this will return `None` for reference types and such. 51 /// an `impl S`, but not `impl &S`. Hence, this will return `None` for
49 pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> { 52 /// reference types and such.
50 let fp = match *ty.interned(&Interner) { 53 pub fn for_inherent_impl(ty: &Ty) -> Option<TyFingerprint> {
54 let fp = match ty.kind(&Interner) {
51 TyKind::Str => TyFingerprint::Str, 55 TyKind::Str => TyFingerprint::Str,
52 TyKind::Never => TyFingerprint::Never, 56 TyKind::Never => TyFingerprint::Never,
53 TyKind::Slice(..) => TyFingerprint::Slice, 57 TyKind::Slice(..) => TyFingerprint::Slice,
54 TyKind::Array(..) => TyFingerprint::Array, 58 TyKind::Array(..) => TyFingerprint::Array,
55 TyKind::Scalar(scalar) => TyFingerprint::Scalar(scalar), 59 TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
56 TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt), 60 TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
57 TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), 61 TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
58 TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), 62 TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
59 TyKind::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id),
60 TyKind::Function(FnPointer { num_args, sig, .. }) => {
61 TyFingerprint::FnPtr(num_args, sig)
62 }
63 TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, 63 TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
64 _ => return None, 64 _ => return None,
65 }; 65 };
66 Some(fp) 66 Some(fp)
67 } 67 }
68
69 /// Creates a TyFingerprint for looking up a trait impl.
70 pub fn for_trait_impl(ty: &Ty) -> Option<TyFingerprint> {
71 let fp = match ty.kind(&Interner) {
72 TyKind::Str => TyFingerprint::Str,
73 TyKind::Never => TyFingerprint::Never,
74 TyKind::Slice(..) => TyFingerprint::Slice,
75 TyKind::Array(..) => TyFingerprint::Array,
76 TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
77 TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
78 TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
79 TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
80 TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
81 TyKind::Ref(_, _, ty) => return TyFingerprint::for_trait_impl(ty),
82 TyKind::Tuple(_, subst) => {
83 let first_ty = subst.interned().get(0).map(|arg| arg.assert_ty_ref(&Interner));
84 if let Some(ty) = first_ty {
85 return TyFingerprint::for_trait_impl(ty);
86 } else {
87 TyFingerprint::Unit
88 }
89 }
90 TyKind::AssociatedType(_, _)
91 | TyKind::OpaqueType(_, _)
92 | TyKind::FnDef(_, _)
93 | TyKind::Closure(_, _)
94 | TyKind::Generator(..)
95 | TyKind::GeneratorWitness(..) => TyFingerprint::Unnameable,
96 TyKind::Function(fn_ptr) => {
97 TyFingerprint::Function(fn_ptr.substitution.0.len(&Interner) as u32)
98 }
99 TyKind::Alias(_)
100 | TyKind::Placeholder(_)
101 | TyKind::BoundVar(_)
102 | TyKind::InferenceVar(_, _)
103 | TyKind::Error => return None,
104 };
105 Some(fp)
106 }
68} 107}
69 108
70pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ 109pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
@@ -100,25 +139,38 @@ impl TraitImpls {
100 let mut impls = Self { map: FxHashMap::default() }; 139 let mut impls = Self { map: FxHashMap::default() };
101 140
102 let crate_def_map = db.crate_def_map(krate); 141 let crate_def_map = db.crate_def_map(krate);
103 for (_module_id, module_data) in crate_def_map.modules() { 142 collect_def_map(db, &crate_def_map, &mut impls);
104 for impl_id in module_data.scope.impls() { 143
105 let target_trait = match db.impl_trait(impl_id) { 144 return Arc::new(impls);
106 Some(tr) => tr.value.hir_trait_id(), 145
107 None => continue, 146 fn collect_def_map(db: &dyn HirDatabase, def_map: &DefMap, impls: &mut TraitImpls) {
108 }; 147 for (_module_id, module_data) in def_map.modules() {
109 let self_ty = db.impl_self_ty(impl_id); 148 for impl_id in module_data.scope.impls() {
110 let self_ty_fp = TyFingerprint::for_impl(&self_ty.value); 149 let target_trait = match db.impl_trait(impl_id) {
111 impls 150 Some(tr) => tr.skip_binders().hir_trait_id(),
112 .map 151 None => continue,
113 .entry(target_trait) 152 };
114 .or_default() 153 let self_ty = db.impl_self_ty(impl_id);
115 .entry(self_ty_fp) 154 let self_ty_fp = TyFingerprint::for_trait_impl(self_ty.skip_binders());
116 .or_default() 155 impls
117 .push(impl_id); 156 .map
157 .entry(target_trait)
158 .or_default()
159 .entry(self_ty_fp)
160 .or_default()
161 .push(impl_id);
162 }
163
164 // To better support custom derives, collect impls in all unnamed const items.
165 // const _: () = { ... };
166 for konst in module_data.scope.unnamed_consts() {
167 let body = db.body(konst.into());
168 for (_, block_def_map) in body.blocks(db.upcast()) {
169 collect_def_map(db, &block_def_map, impls);
170 }
171 }
118 } 172 }
119 } 173 }
120
121 Arc::new(impls)
122 } 174 }
123 175
124 pub(crate) fn trait_impls_in_deps_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> { 176 pub(crate) fn trait_impls_in_deps_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
@@ -144,10 +196,13 @@ impl TraitImpls {
144 } 196 }
145 197
146 /// Queries all trait impls for the given type. 198 /// Queries all trait impls for the given type.
147 pub fn for_self_ty(&self, fp: TyFingerprint) -> impl Iterator<Item = ImplId> + '_ { 199 pub fn for_self_ty_without_blanket_impls(
200 &self,
201 fp: TyFingerprint,
202 ) -> impl Iterator<Item = ImplId> + '_ {
148 self.map 203 self.map
149 .values() 204 .values()
150 .flat_map(move |impls| impls.get(&None).into_iter().chain(impls.get(&Some(fp)))) 205 .flat_map(move |impls| impls.get(&Some(fp)).into_iter())
151 .flat_map(|it| it.iter().copied()) 206 .flat_map(|it| it.iter().copied())
152 } 207 }
153 208
@@ -202,17 +257,22 @@ impl InherentImpls {
202 } 257 }
203 258
204 let self_ty = db.impl_self_ty(impl_id); 259 let self_ty = db.impl_self_ty(impl_id);
205 if let Some(fp) = TyFingerprint::for_impl(&self_ty.value) { 260 let fp = TyFingerprint::for_inherent_impl(self_ty.skip_binders());
261 if let Some(fp) = fp {
206 map.entry(fp).or_default().push(impl_id); 262 map.entry(fp).or_default().push(impl_id);
207 } 263 }
264 // `fp` should only be `None` in error cases (either erroneous code or incomplete name resolution)
208 } 265 }
209 } 266 }
210 267
268 // NOTE: We're not collecting inherent impls from unnamed consts here, we intentionally only
269 // support trait impls there.
270
211 Arc::new(Self { map }) 271 Arc::new(Self { map })
212 } 272 }
213 273
214 pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] { 274 pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] {
215 match TyFingerprint::for_impl(self_ty) { 275 match TyFingerprint::for_inherent_impl(self_ty) {
216 Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]), 276 Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]),
217 None => &[], 277 None => &[],
218 } 278 }
@@ -223,15 +283,14 @@ impl InherentImpls {
223 } 283 }
224} 284}
225 285
226impl Ty { 286pub fn def_crates(
227 pub fn def_crates( 287 db: &dyn HirDatabase,
228 &self, 288 ty: &Ty,
229 db: &dyn HirDatabase, 289 cur_crate: CrateId,
230 cur_crate: CrateId, 290) -> Option<ArrayVec<CrateId, 2>> {
231 ) -> Option<ArrayVec<CrateId, 2>> { 291 // Types like slice can have inherent impls in several crates, (core and alloc).
232 // Types like slice can have inherent impls in several crates, (core and alloc). 292 // The corresponding impls are marked with lang items, so we can use them to find the required crates.
233 // The corresponding impls are marked with lang items, so we can use them to find the required crates. 293 macro_rules! lang_item_crate {
234 macro_rules! lang_item_crate {
235 ($($name:expr),+ $(,)?) => {{ 294 ($($name:expr),+ $(,)?) => {{
236 let mut v = ArrayVec::<LangItemTarget, 2>::new(); 295 let mut v = ArrayVec::<LangItemTarget, 2>::new();
237 $( 296 $(
@@ -241,51 +300,50 @@ impl Ty {
241 }}; 300 }};
242 } 301 }
243 302
244 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); 303 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect());
245 304
246 let lang_item_targets = match self.interned(&Interner) { 305 let lang_item_targets = match ty.kind(&Interner) {
247 TyKind::Adt(AdtId(def_id), _) => { 306 TyKind::Adt(AdtId(def_id), _) => {
248 return mod_to_crate_ids(def_id.module(db.upcast())); 307 return mod_to_crate_ids(def_id.module(db.upcast()));
249 } 308 }
250 TyKind::ForeignType(id) => { 309 TyKind::Foreign(id) => {
251 return mod_to_crate_ids( 310 return mod_to_crate_ids(
252 from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()), 311 from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()),
253 ); 312 );
254 } 313 }
255 TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"), 314 TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
256 TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"), 315 TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"),
257 TyKind::Scalar(Scalar::Float(f)) => match f { 316 TyKind::Scalar(Scalar::Float(f)) => match f {
258 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 317 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
259 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), 318 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
260 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), 319 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
261 }, 320 },
262 &TyKind::Scalar(Scalar::Int(t)) => { 321 &TyKind::Scalar(Scalar::Int(t)) => {
263 lang_item_crate!(primitive::int_ty_to_string(t)) 322 lang_item_crate!(primitive::int_ty_to_string(t))
264 } 323 }
265 &TyKind::Scalar(Scalar::Uint(t)) => { 324 &TyKind::Scalar(Scalar::Uint(t)) => {
266 lang_item_crate!(primitive::uint_ty_to_string(t)) 325 lang_item_crate!(primitive::uint_ty_to_string(t))
267 } 326 }
268 TyKind::Str => lang_item_crate!("str_alloc", "str"), 327 TyKind::Str => lang_item_crate!("str_alloc", "str"),
269 TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"), 328 TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"),
270 TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), 329 TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"),
271 TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), 330 TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"),
272 TyKind::Dyn(_) => { 331 TyKind::Dyn(_) => {
273 return self.dyn_trait().and_then(|trait_| { 332 return ty.dyn_trait().and_then(|trait_| {
274 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) 333 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast()))
275 }); 334 });
276 } 335 }
277 _ => return None, 336 _ => return None,
278 }; 337 };
279 let res = lang_item_targets 338 let res = lang_item_targets
280 .into_iter() 339 .into_iter()
281 .filter_map(|it| match it { 340 .filter_map(|it| match it {
282 LangItemTarget::ImplDefId(it) => Some(it), 341 LangItemTarget::ImplDefId(it) => Some(it),
283 _ => None, 342 _ => None,
284 }) 343 })
285 .map(|it| it.lookup(db.upcast()).container.krate()) 344 .map(|it| it.lookup(db.upcast()).container.krate())
286 .collect(); 345 .collect();
287 Some(res) 346 Some(res)
288 }
289} 347}
290 348
291/// Look up the method with the given name, returning the actual autoderefed 349/// Look up the method with the given name, returning the actual autoderefed
@@ -454,7 +512,8 @@ fn iterate_method_candidates_with_autoref(
454 } 512 }
455 let refed = Canonical { 513 let refed = Canonical {
456 binders: deref_chain[0].binders.clone(), 514 binders: deref_chain[0].binders.clone(),
457 value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner), 515 value: TyKind::Ref(Mutability::Not, static_lifetime(), deref_chain[0].value.clone())
516 .intern(&Interner),
458 }; 517 };
459 if iterate_method_candidates_by_receiver( 518 if iterate_method_candidates_by_receiver(
460 &refed, 519 &refed,
@@ -471,7 +530,8 @@ fn iterate_method_candidates_with_autoref(
471 } 530 }
472 let ref_muted = Canonical { 531 let ref_muted = Canonical {
473 binders: deref_chain[0].binders.clone(), 532 binders: deref_chain[0].binders.clone(),
474 value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner), 533 value: TyKind::Ref(Mutability::Mut, static_lifetime(), deref_chain[0].value.clone())
534 .intern(&Interner),
475 }; 535 };
476 if iterate_method_candidates_by_receiver( 536 if iterate_method_candidates_by_receiver(
477 &ref_muted, 537 &ref_muted,
@@ -563,7 +623,7 @@ fn iterate_trait_method_candidates(
563 // if ty is `dyn Trait`, the trait doesn't need to be in scope 623 // if ty is `dyn Trait`, the trait doesn't need to be in scope
564 let inherent_trait = 624 let inherent_trait =
565 self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); 625 self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
566 let env_traits = if let TyKind::Placeholder(_) = self_ty.value.interned(&Interner) { 626 let env_traits = if let TyKind::Placeholder(_) = self_ty.value.kind(&Interner) {
567 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope 627 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
568 env.traits_in_scope_from_clauses(&self_ty.value) 628 env.traits_in_scope_from_clauses(&self_ty.value)
569 .flat_map(|t| all_super_traits(db.upcast(), t)) 629 .flat_map(|t| all_super_traits(db.upcast(), t))
@@ -593,6 +653,7 @@ fn iterate_trait_method_candidates(
593 } 653 }
594 } 654 }
595 known_implemented = true; 655 known_implemented = true;
656 // FIXME: we shouldn't be ignoring the binders here
596 if callback(&self_ty.value, *item) { 657 if callback(&self_ty.value, *item) {
597 return true; 658 return true;
598 } 659 }
@@ -610,7 +671,7 @@ fn iterate_inherent_methods(
610 visible_from_module: Option<ModuleId>, 671 visible_from_module: Option<ModuleId>,
611 callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, 672 callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
612) -> bool { 673) -> bool {
613 let def_crates = match self_ty.value.def_crates(db, krate) { 674 let def_crates = match def_crates(db, &self_ty.value, krate) {
614 Some(k) => k, 675 Some(k) => k,
615 None => return false, 676 None => return false,
616 }; 677 };
@@ -675,7 +736,7 @@ fn is_valid_candidate(
675 } 736 }
676 } 737 }
677 if let Some(receiver_ty) = receiver_ty { 738 if let Some(receiver_ty) = receiver_ty {
678 if !data.has_self_param { 739 if !data.has_self_param() {
679 return false; 740 return false;
680 } 741 }
681 let transformed_receiver_ty = match transform_receiver_ty(db, m, self_ty) { 742 let transformed_receiver_ty = match transform_receiver_ty(db, m, self_ty) {
@@ -710,48 +771,44 @@ pub(crate) fn inherent_impl_substs(
710) -> Option<Substitution> { 771) -> Option<Substitution> {
711 // we create a var for each type parameter of the impl; we need to keep in 772 // we create a var for each type parameter of the impl; we need to keep in
712 // mind here that `self_ty` might have vars of its own 773 // mind here that `self_ty` might have vars of its own
713 let vars = Substitution::build_for_def(db, impl_id) 774 let self_ty_vars = self_ty.binders.len(&Interner);
714 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner)) 775 let vars = TyBuilder::subst_for_def(db, impl_id)
776 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty_vars)
715 .build(); 777 .build();
716 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); 778 let self_ty_with_vars = db.impl_self_ty(impl_id).substitute(&Interner, &vars);
717 let mut kinds = self_ty.binders.interned().to_vec(); 779 let mut kinds = self_ty.binders.interned().to_vec();
718 kinds.extend( 780 kinds.extend(
719 iter::repeat(chalk_ir::WithKind::new( 781 iter::repeat(chalk_ir::WithKind::new(
720 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), 782 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
721 UniverseIndex::ROOT, 783 UniverseIndex::ROOT,
722 )) 784 ))
723 .take(vars.len()), 785 .take(vars.len(&Interner)),
724 ); 786 );
725 let tys = Canonical { 787 let tys = Canonical {
726 binders: CanonicalVarKinds::from_iter(&Interner, kinds), 788 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
727 value: (self_ty_with_vars, self_ty.value.clone()), 789 value: (self_ty_with_vars, self_ty.value.clone()),
728 }; 790 };
729 let substs = super::infer::unify(&tys); 791 let substs = super::infer::unify(&tys)?;
730 // We only want the substs for the vars we added, not the ones from self_ty. 792 // We only want the substs for the vars we added, not the ones from self_ty.
731 // Also, if any of the vars we added are still in there, we replace them by 793 // Also, if any of the vars we added are still in there, we replace them by
732 // Unknown. I think this can only really happen if self_ty contained 794 // Unknown. I think this can only really happen if self_ty contained
733 // Unknown, and in that case we want the result to contain Unknown in those 795 // Unknown, and in that case we want the result to contain Unknown in those
734 // places again. 796 // places again.
735 substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.binders.len(&Interner))) 797 let suffix =
798 Substitution::from_iter(&Interner, substs.iter(&Interner).cloned().skip(self_ty_vars));
799 Some(fallback_bound_vars(suffix, self_ty_vars))
736} 800}
737 801
738/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past 802/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
739/// num_vars_to_keep) by `TyKind::Unknown`. 803/// num_vars_to_keep) by `TyKind::Unknown`.
740fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { 804fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution {
741 s.fold_binders( 805 crate::fold_free_vars(s, |bound, binders| {
742 &mut |ty, binders| { 806 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
743 if let TyKind::BoundVar(bound) = ty.interned(&Interner) { 807 TyKind::Error.intern(&Interner)
744 if bound.index >= num_vars_to_keep && bound.debruijn >= binders { 808 } else {
745 TyKind::Unknown.intern(&Interner) 809 bound.shifted_in_from(binders).to_ty(&Interner)
746 } else { 810 }
747 ty 811 })
748 }
749 } else {
750 ty
751 }
752 },
753 DebruijnIndex::INNERMOST,
754 )
755} 812}
756 813
757fn transform_receiver_ty( 814fn transform_receiver_ty(
@@ -760,13 +817,13 @@ fn transform_receiver_ty(
760 self_ty: &Canonical<Ty>, 817 self_ty: &Canonical<Ty>,
761) -> Option<Ty> { 818) -> Option<Ty> {
762 let substs = match function_id.lookup(db.upcast()).container { 819 let substs = match function_id.lookup(db.upcast()).container {
763 AssocContainerId::TraitId(_) => Substitution::build_for_def(db, function_id) 820 AssocContainerId::TraitId(_) => TyBuilder::subst_for_def(db, function_id)
764 .push(self_ty.value.clone()) 821 .push(self_ty.value.clone())
765 .fill_with_unknown() 822 .fill_with_unknown()
766 .build(), 823 .build(),
767 AssocContainerId::ImplId(impl_id) => { 824 AssocContainerId::ImplId(impl_id) => {
768 let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?; 825 let impl_substs = inherent_impl_substs(db, impl_id, &self_ty)?;
769 Substitution::build_for_def(db, function_id) 826 TyBuilder::subst_for_def(db, function_id)
770 .use_parent_substs(&impl_substs) 827 .use_parent_substs(&impl_substs)
771 .fill_with_unknown() 828 .fill_with_unknown()
772 .build() 829 .build()
@@ -774,7 +831,7 @@ fn transform_receiver_ty(
774 AssocContainerId::ModuleId(_) => unreachable!(), 831 AssocContainerId::ModuleId(_) => unreachable!(),
775 }; 832 };
776 let sig = db.callable_item_signature(function_id.into()); 833 let sig = db.callable_item_signature(function_id.into());
777 Some(sig.value.params()[0].clone().subst_bound_vars(&substs)) 834 Some(sig.map(|s| s.params()[0].clone()).substitute(&Interner, &substs))
778} 835}
779 836
780pub fn implements_trait( 837pub fn implements_trait(
@@ -800,7 +857,7 @@ pub fn implements_trait_unique(
800 let goal = generic_implements_goal(db, env, trait_, ty.clone()); 857 let goal = generic_implements_goal(db, env, trait_, ty.clone());
801 let solution = db.trait_solve(krate, goal); 858 let solution = db.trait_solve(krate, goal);
802 859
803 matches!(solution, Some(crate::traits::Solution::Unique(_))) 860 matches!(solution, Some(crate::Solution::Unique(_)))
804} 861}
805 862
806/// This creates Substs for a trait with the given Self type and type variables 863/// This creates Substs for a trait with the given Self type and type variables
@@ -812,7 +869,7 @@ fn generic_implements_goal(
812 self_ty: Canonical<Ty>, 869 self_ty: Canonical<Ty>,
813) -> Canonical<InEnvironment<super::DomainGoal>> { 870) -> Canonical<InEnvironment<super::DomainGoal>> {
814 let mut kinds = self_ty.binders.interned().to_vec(); 871 let mut kinds = self_ty.binders.interned().to_vec();
815 let substs = super::Substitution::build_for_def(db, trait_) 872 let trait_ref = TyBuilder::trait_ref(db, trait_)
816 .push(self_ty.value) 873 .push(self_ty.value)
817 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) 874 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
818 .build(); 875 .build();
@@ -821,13 +878,12 @@ fn generic_implements_goal(
821 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), 878 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
822 UniverseIndex::ROOT, 879 UniverseIndex::ROOT,
823 )) 880 ))
824 .take(substs.len() - 1), 881 .take(trait_ref.substitution.len(&Interner) - 1),
825 ); 882 );
826 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
827 let obligation = trait_ref.cast(&Interner); 883 let obligation = trait_ref.cast(&Interner);
828 Canonical { 884 Canonical {
829 binders: CanonicalVarKinds::from_iter(&Interner, kinds), 885 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
830 value: InEnvironment::new(env.env.clone(), obligation), 886 value: InEnvironment::new(&env.env, obligation),
831 } 887 }
832} 888}
833 889
@@ -838,8 +894,8 @@ fn autoderef_method_receiver(
838) -> Vec<Canonical<Ty>> { 894) -> Vec<Canonical<Ty>> {
839 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); 895 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect();
840 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) 896 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
841 if let Some(TyKind::Array(parameters)) = 897 if let Some(TyKind::Array(parameters, _)) =
842 deref_chain.last().map(|ty| ty.value.interned(&Interner)) 898 deref_chain.last().map(|ty| ty.value.kind(&Interner))
843 { 899 {
844 let kinds = deref_chain.last().unwrap().binders.clone(); 900 let kinds = deref_chain.last().unwrap().binders.clone();
845 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); 901 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner);
diff --git a/crates/hir_ty/src/op.rs b/crates/hir_ty/src/op.rs
index 527c5cbbd..0222de2bc 100644
--- a/crates/hir_ty/src/op.rs
+++ b/crates/hir_ty/src/op.rs
@@ -2,29 +2,63 @@
2use chalk_ir::TyVariableKind; 2use chalk_ir::TyVariableKind;
3use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; 3use hir_def::expr::{ArithOp, BinaryOp, CmpOp};
4 4
5use crate::{Interner, Scalar, Ty, TyKind}; 5use crate::{Interner, Scalar, Ty, TyBuilder, TyKind};
6 6
7pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { 7pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
8 match op { 8 match op {
9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => TyKind::Scalar(Scalar::Bool).intern(&Interner), 9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
10 BinaryOp::Assignment { .. } => Ty::unit(), 10 BinaryOp::Assignment { .. } => TyBuilder::unit(),
11 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => { 11 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => {
12 match lhs_ty.interned(&Interner) { 12 // all integer combinations are valid here
13 if matches!(
14 lhs_ty.kind(&Interner),
13 TyKind::Scalar(Scalar::Int(_)) 15 TyKind::Scalar(Scalar::Int(_))
14 | TyKind::Scalar(Scalar::Uint(_)) 16 | TyKind::Scalar(Scalar::Uint(_))
15 | TyKind::Scalar(Scalar::Float(_)) => lhs_ty, 17 | TyKind::InferenceVar(_, TyVariableKind::Integer)
16 TyKind::InferenceVar(_, TyVariableKind::Integer) 18 ) && matches!(
17 | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty, 19 rhs_ty.kind(&Interner),
18 _ => TyKind::Unknown.intern(&Interner), 20 TyKind::Scalar(Scalar::Int(_))
21 | TyKind::Scalar(Scalar::Uint(_))
22 | TyKind::InferenceVar(_, TyVariableKind::Integer)
23 ) {
24 lhs_ty
25 } else {
26 TyKind::Error.intern(&Interner)
19 } 27 }
20 } 28 }
21 BinaryOp::ArithOp(_) => match rhs_ty.interned(&Interner) { 29 BinaryOp::ArithOp(_) => match (lhs_ty.kind(&Interner), rhs_ty.kind(&Interner)) {
22 TyKind::Scalar(Scalar::Int(_)) 30 // (int, int) | (uint, uint) | (float, float)
23 | TyKind::Scalar(Scalar::Uint(_)) 31 (TyKind::Scalar(Scalar::Int(_)), TyKind::Scalar(Scalar::Int(_)))
24 | TyKind::Scalar(Scalar::Float(_)) => rhs_ty, 32 | (TyKind::Scalar(Scalar::Uint(_)), TyKind::Scalar(Scalar::Uint(_)))
25 TyKind::InferenceVar(_, TyVariableKind::Integer) 33 | (TyKind::Scalar(Scalar::Float(_)), TyKind::Scalar(Scalar::Float(_))) => rhs_ty,
26 | TyKind::InferenceVar(_, TyVariableKind::Float) => rhs_ty, 34 // ({int}, int) | ({int}, uint)
27 _ => TyKind::Unknown.intern(&Interner), 35 (TyKind::InferenceVar(_, TyVariableKind::Integer), TyKind::Scalar(Scalar::Int(_)))
36 | (TyKind::InferenceVar(_, TyVariableKind::Integer), TyKind::Scalar(Scalar::Uint(_))) => {
37 rhs_ty
38 }
39 // (int, {int}) | (uint, {int})
40 (TyKind::Scalar(Scalar::Int(_)), TyKind::InferenceVar(_, TyVariableKind::Integer))
41 | (TyKind::Scalar(Scalar::Uint(_)), TyKind::InferenceVar(_, TyVariableKind::Integer)) => {
42 lhs_ty
43 }
44 // ({float} | float)
45 (TyKind::InferenceVar(_, TyVariableKind::Float), TyKind::Scalar(Scalar::Float(_))) => {
46 rhs_ty
47 }
48 // (float, {float})
49 (TyKind::Scalar(Scalar::Float(_)), TyKind::InferenceVar(_, TyVariableKind::Float)) => {
50 lhs_ty
51 }
52 // ({int}, {int}) | ({float}, {float})
53 (
54 TyKind::InferenceVar(_, TyVariableKind::Integer),
55 TyKind::InferenceVar(_, TyVariableKind::Integer),
56 )
57 | (
58 TyKind::InferenceVar(_, TyVariableKind::Float),
59 TyKind::InferenceVar(_, TyVariableKind::Float),
60 ) => rhs_ty,
61 _ => TyKind::Error.intern(&Interner),
28 }, 62 },
29 } 63 }
30} 64}
@@ -33,24 +67,24 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
33 match op { 67 match op {
34 BinaryOp::LogicOp(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), 68 BinaryOp::LogicOp(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
35 BinaryOp::Assignment { op: None } => lhs_ty, 69 BinaryOp::Assignment { op: None } => lhs_ty,
36 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty.interned(&Interner) { 70 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty.kind(&Interner) {
37 TyKind::Scalar(_) | TyKind::Str => lhs_ty, 71 TyKind::Scalar(_) | TyKind::Str => lhs_ty,
38 TyKind::InferenceVar(_, TyVariableKind::Integer) 72 TyKind::InferenceVar(_, TyVariableKind::Integer)
39 | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty, 73 | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
40 _ => TyKind::Unknown.intern(&Interner), 74 _ => TyKind::Error.intern(&Interner),
41 }, 75 },
42 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => { 76 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => {
43 TyKind::Unknown.intern(&Interner) 77 TyKind::Error.intern(&Interner)
44 } 78 }
45 BinaryOp::CmpOp(CmpOp::Ord { .. }) 79 BinaryOp::CmpOp(CmpOp::Ord { .. })
46 | BinaryOp::Assignment { op: Some(_) } 80 | BinaryOp::Assignment { op: Some(_) }
47 | BinaryOp::ArithOp(_) => match lhs_ty.interned(&Interner) { 81 | BinaryOp::ArithOp(_) => match lhs_ty.kind(&Interner) {
48 TyKind::Scalar(Scalar::Int(_)) 82 TyKind::Scalar(Scalar::Int(_))
49 | TyKind::Scalar(Scalar::Uint(_)) 83 | TyKind::Scalar(Scalar::Uint(_))
50 | TyKind::Scalar(Scalar::Float(_)) => lhs_ty, 84 | TyKind::Scalar(Scalar::Float(_)) => lhs_ty,
51 TyKind::InferenceVar(_, TyVariableKind::Integer) 85 TyKind::InferenceVar(_, TyVariableKind::Integer)
52 | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty, 86 | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
53 _ => TyKind::Unknown.intern(&Interner), 87 _ => TyKind::Error.intern(&Interner),
54 }, 88 },
55 } 89 }
56} 90}
diff --git a/crates/hir_ty/src/primitive.rs b/crates/hir_ty/src/primitive.rs
index 2449addfb..d7f48c69a 100644
--- a/crates/hir_ty/src/primitive.rs
+++ b/crates/hir_ty/src/primitive.rs
@@ -1,7 +1,4 @@
1//! Defines primitive types, which have a couple of peculiarities: 1//! A few helper functions for dealing with primitives.
2//!
3//! * during type inference, they can be uncertain (ie, `let x = 92;`)
4//! * they don't belong to any particular crate.
5 2
6pub use chalk_ir::{FloatTy, IntTy, UintTy}; 3pub use chalk_ir::{FloatTy, IntTy, UintTy};
7pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint}; 4pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint};
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs
index ad283c1e0..ccfb88c52 100644
--- a/crates/hir_ty/src/tests.rs
+++ b/crates/hir_ty/src/tests.rs
@@ -288,7 +288,7 @@ fn visit_module(
288 } 288 }
289 289
290 fn visit_body(db: &TestDB, body: &Body, cb: &mut dyn FnMut(DefWithBodyId)) { 290 fn visit_body(db: &TestDB, body: &Body, cb: &mut dyn FnMut(DefWithBodyId)) {
291 for def_map in body.block_scopes.iter().filter_map(|block| db.block_def_map(*block)) { 291 for (_, def_map) in body.blocks(db) {
292 for (mod_id, _) in def_map.modules() { 292 for (mod_id, _) in def_map.modules() {
293 visit_module(db, &def_map, mod_id, cb); 293 visit_module(db, &def_map, mod_id, cb);
294 } 294 }
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs
index 3eb01dbd0..b8e373ed8 100644
--- a/crates/hir_ty/src/tests/macros.rs
+++ b/crates/hir_ty/src/tests/macros.rs
@@ -373,6 +373,32 @@ fn recursive_inner_item_macro_rules() {
373} 373}
374 374
375#[test] 375#[test]
376fn infer_macro_defining_block_with_items() {
377 check_infer(
378 r#"
379 macro_rules! foo {
380 () => {{
381 fn bar() -> usize { 0 }
382 bar()
383 }};
384 }
385 fn main() {
386 let _a = foo!();
387 }
388 "#,
389 expect![[r#"
390 !15..18 '{0}': usize
391 !16..17 '0': usize
392 !0..24 '{fnbar...bar()}': usize
393 !18..21 'bar': fn bar() -> usize
394 !18..23 'bar()': usize
395 98..122 '{ ...!(); }': ()
396 108..110 '_a': usize
397 "#]],
398 );
399}
400
401#[test]
376fn infer_type_value_macro_having_same_name() { 402fn infer_type_value_macro_having_same_name() {
377 check_infer( 403 check_infer(
378 r#" 404 r#"
@@ -1039,11 +1065,11 @@ fn macro_in_arm() {
1039 } 1065 }
1040 "#, 1066 "#,
1041 expect![[r#" 1067 expect![[r#"
1068 !0..2 '()': ()
1042 51..110 '{ ... }; }': () 1069 51..110 '{ ... }; }': ()
1043 61..62 'x': u32 1070 61..62 'x': u32
1044 65..107 'match ... }': u32 1071 65..107 'match ... }': u32
1045 71..73 '()': () 1072 71..73 '()': ()
1046 84..91 'unit!()': ()
1047 95..100 '92u32': u32 1073 95..100 '92u32': u32
1048 "#]], 1074 "#]],
1049 ); 1075 );
diff --git a/crates/hir_ty/src/tests/method_resolution.rs b/crates/hir_ty/src/tests/method_resolution.rs
index 61f18b0d2..4b2c82b41 100644
--- a/crates/hir_ty/src/tests/method_resolution.rs
+++ b/crates/hir_ty/src/tests/method_resolution.rs
@@ -1292,3 +1292,25 @@ mod b {
1292 "#]], 1292 "#]],
1293 ) 1293 )
1294} 1294}
1295
1296#[test]
1297fn impl_in_unnamed_const() {
1298 check_types(
1299 r#"
1300struct S;
1301
1302trait Tr {
1303 fn method(&self) -> u16;
1304}
1305
1306const _: () = {
1307 impl Tr for S {}
1308};
1309
1310fn f() {
1311 S.method();
1312 //^^^^^^^^^^ u16
1313}
1314 "#,
1315 );
1316}
diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs
index 85a28e76b..f514b3efe 100644
--- a/crates/hir_ty/src/tests/patterns.rs
+++ b/crates/hir_ty/src/tests/patterns.rs
@@ -1,6 +1,6 @@
1use expect_test::expect; 1use expect_test::expect;
2 2
3use super::{check_infer, check_infer_with_mismatches}; 3use super::{check_infer, check_infer_with_mismatches, check_types};
4 4
5#[test] 5#[test]
6fn infer_pattern() { 6fn infer_pattern() {
@@ -825,3 +825,29 @@ fn foo(foo: Foo) {
825 "#]], 825 "#]],
826 ); 826 );
827} 827}
828
829#[test]
830fn macro_pat() {
831 check_types(
832 r#"
833macro_rules! pat {
834 ($name:ident) => { Enum::Variant1($name) }
835}
836
837enum Enum {
838 Variant1(u8),
839 Variant2,
840}
841
842fn f(e: Enum) {
843 match e {
844 pat!(bind) => {
845 bind;
846 //^^^^ u8
847 }
848 Enum::Variant2 => {}
849 }
850}
851 "#,
852 )
853}
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
index b69f86050..9cd9f473d 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -974,3 +974,41 @@ fn param_overrides_fn() {
974 "#, 974 "#,
975 ) 975 )
976} 976}
977
978#[test]
979fn lifetime_from_chalk_during_deref() {
980 check_types(
981 r#"
982 #[lang = "deref"]
983 pub trait Deref {
984 type Target;
985 }
986
987 struct Box<T: ?Sized> {}
988 impl<T> Deref for Box<T> {
989 type Target = T;
990
991 fn deref(&self) -> &Self::Target {
992 loop {}
993 }
994 }
995
996 trait Iterator {
997 type Item;
998 }
999
1000 pub struct Iter<'a, T: 'a> {
1001 inner: Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>,
1002 }
1003
1004 trait IterTrait<'a, T: 'a>: Iterator<Item = &'a T> {
1005 fn clone_box(&self);
1006 }
1007
1008 fn clone_iter<T>(s: Iter<T>) {
1009 s.inner.clone_box();
1010 //^^^^^^^^^^^^^^^^^^^ ()
1011 }
1012 "#,
1013 )
1014}
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs
index 361cd6302..5948d0bc2 100644
--- a/crates/hir_ty/src/tests/simple.rs
+++ b/crates/hir_ty/src/tests/simple.rs
@@ -1765,6 +1765,24 @@ fn main() {
1765} 1765}
1766 1766
1767#[test] 1767#[test]
1768fn shadowing_primitive_with_inner_items() {
1769 check_types(
1770 r#"
1771struct i32;
1772struct Foo;
1773
1774impl i32 { fn foo(&self) -> Foo { Foo } }
1775
1776fn main() {
1777 fn inner() {}
1778 let x: i32 = i32;
1779 x.foo();
1780 //^ Foo
1781}"#,
1782 );
1783}
1784
1785#[test]
1768fn not_shadowing_primitive_by_module() { 1786fn not_shadowing_primitive_by_module() {
1769 check_types( 1787 check_types(
1770 r#" 1788 r#"
@@ -2564,3 +2582,36 @@ fn f() {
2564 "#, 2582 "#,
2565 ) 2583 )
2566} 2584}
2585
2586#[test]
2587fn infer_type_alias_variant() {
2588 check_infer(
2589 r#"
2590type Qux = Foo;
2591enum Foo {
2592 Bar(i32),
2593 Baz { baz: f32 }
2594}
2595
2596fn f() {
2597 match Foo::Bar(3) {
2598 Qux::Bar(bar) => (),
2599 Qux::Baz { baz } => (),
2600 }
2601}
2602 "#,
2603 expect![[r#"
2604 72..166 '{ ... } }': ()
2605 78..164 'match ... }': ()
2606 84..92 'Foo::Bar': Bar(i32) -> Foo
2607 84..95 'Foo::Bar(3)': Foo
2608 93..94 '3': i32
2609 106..119 'Qux::Bar(bar)': Foo
2610 115..118 'bar': i32
2611 123..125 '()': ()
2612 135..151 'Qux::B... baz }': Foo
2613 146..149 'baz': f32
2614 155..157 '()': ()
2615 "#]],
2616 )
2617}
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index 2ba97f814..ffc7c8ef4 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -263,15 +263,14 @@ mod ops {
263fn infer_from_bound_1() { 263fn infer_from_bound_1() {
264 check_infer( 264 check_infer(
265 r#" 265 r#"
266 trait Trait<T> {} 266trait Trait<T> {}
267 struct S<T>(T); 267struct S<T>(T);
268 impl<U> Trait<U> for S<U> {} 268impl<U> Trait<U> for S<U> {}
269 fn foo<T: Trait<u32>>(t: T) {} 269fn foo<T: Trait<u32>>(t: T) {}
270 fn test() { 270fn test() {
271 let s = S(unknown); 271 let s = S(unknown);
272 foo(s); 272 foo(s);
273 } 273}"#,
274 "#,
275 expect![[r#" 274 expect![[r#"
276 85..86 't': T 275 85..86 't': T
277 91..93 '{}': () 276 91..93 '{}': ()
@@ -291,15 +290,14 @@ fn infer_from_bound_1() {
291fn infer_from_bound_2() { 290fn infer_from_bound_2() {
292 check_infer( 291 check_infer(
293 r#" 292 r#"
294 trait Trait<T> {} 293trait Trait<T> {}
295 struct S<T>(T); 294struct S<T>(T);
296 impl<U> Trait<U> for S<U> {} 295impl<U> Trait<U> for S<U> {}
297 fn foo<U, T: Trait<U>>(t: T) -> U {} 296fn foo<U, T: Trait<U>>(t: T) -> U {}
298 fn test() { 297fn test() {
299 let s = S(unknown); 298 let s = S(unknown);
300 let x: u32 = foo(s); 299 let x: u32 = foo(s);
301 } 300}"#,
302 "#,
303 expect![[r#" 301 expect![[r#"
304 86..87 't': T 302 86..87 't': T
305 97..99 '{}': () 303 97..99 '{}': ()
@@ -321,13 +319,12 @@ fn trait_default_method_self_bound_implements_trait() {
321 cov_mark::check!(trait_self_implements_self); 319 cov_mark::check!(trait_self_implements_self);
322 check_infer( 320 check_infer(
323 r#" 321 r#"
324 trait Trait { 322trait Trait {
325 fn foo(&self) -> i64; 323 fn foo(&self) -> i64;
326 fn bar(&self) -> { 324 fn bar(&self) -> {
327 let x = self.foo(); 325 let x = self.foo();
328 } 326 }
329 } 327}"#,
330 "#,
331 expect![[r#" 328 expect![[r#"
332 26..30 'self': &Self 329 26..30 'self': &Self
333 52..56 'self': &Self 330 52..56 'self': &Self
@@ -343,15 +340,14 @@ fn trait_default_method_self_bound_implements_trait() {
343fn trait_default_method_self_bound_implements_super_trait() { 340fn trait_default_method_self_bound_implements_super_trait() {
344 check_infer( 341 check_infer(
345 r#" 342 r#"
346 trait SuperTrait { 343trait SuperTrait {
347 fn foo(&self) -> i64; 344 fn foo(&self) -> i64;
348 } 345}
349 trait Trait: SuperTrait { 346trait Trait: SuperTrait {
350 fn bar(&self) -> { 347 fn bar(&self) -> {
351 let x = self.foo(); 348 let x = self.foo();
352 } 349 }
353 } 350}"#,
354 "#,
355 expect![[r#" 351 expect![[r#"
356 31..35 'self': &Self 352 31..35 'self': &Self
357 85..89 'self': &Self 353 85..89 'self': &Self
@@ -367,18 +363,17 @@ fn trait_default_method_self_bound_implements_super_trait() {
367fn infer_project_associated_type() { 363fn infer_project_associated_type() {
368 check_infer( 364 check_infer(
369 r#" 365 r#"
370 trait Iterable { 366trait Iterable {
371 type Item; 367 type Item;
372 } 368}
373 struct S; 369struct S;
374 impl Iterable for S { type Item = u32; } 370impl Iterable for S { type Item = u32; }
375 fn test<T: Iterable>() { 371fn test<T: Iterable>() {
376 let x: <S as Iterable>::Item = 1; 372 let x: <S as Iterable>::Item = 1;
377 let y: <T as Iterable>::Item = no_matter; 373 let y: <T as Iterable>::Item = no_matter;
378 let z: T::Item = no_matter; 374 let z: T::Item = no_matter;
379 let a: <T>::Item = no_matter; 375 let a: <T>::Item = no_matter;
380 } 376}"#,
381 "#,
382 expect![[r#" 377 expect![[r#"
383 108..261 '{ ...ter; }': () 378 108..261 '{ ...ter; }': ()
384 118..119 'x': u32 379 118..119 'x': u32
@@ -397,20 +392,19 @@ fn infer_project_associated_type() {
397fn infer_return_associated_type() { 392fn infer_return_associated_type() {
398 check_infer( 393 check_infer(
399 r#" 394 r#"
400 trait Iterable { 395trait Iterable {
401 type Item; 396 type Item;
402 } 397}
403 struct S; 398struct S;
404 impl Iterable for S { type Item = u32; } 399impl Iterable for S { type Item = u32; }
405 fn foo1<T: Iterable>(t: T) -> T::Item {} 400fn foo1<T: Iterable>(t: T) -> T::Item {}
406 fn foo2<T: Iterable>(t: T) -> <T as Iterable>::Item {} 401fn foo2<T: Iterable>(t: T) -> <T as Iterable>::Item {}
407 fn foo3<T: Iterable>(t: T) -> <T>::Item {} 402fn foo3<T: Iterable>(t: T) -> <T>::Item {}
408 fn test() { 403fn test() {
409 let x = foo1(S); 404 let x = foo1(S);
410 let y = foo2(S); 405 let y = foo2(S);
411 let z = foo3(S); 406 let z = foo3(S);
412 } 407}"#,
413 "#,
414 expect![[r#" 408 expect![[r#"
415 106..107 't': T 409 106..107 't': T
416 123..125 '{}': () 410 123..125 '{}': ()
@@ -439,13 +433,12 @@ fn infer_return_associated_type() {
439fn infer_associated_type_bound() { 433fn infer_associated_type_bound() {
440 check_infer( 434 check_infer(
441 r#" 435 r#"
442 trait Iterable { 436trait Iterable {
443 type Item; 437 type Item;
444 } 438}
445 fn test<T: Iterable<Item=u32>>() { 439fn test<T: Iterable<Item=u32>>() {
446 let y: T::Item = unknown; 440 let y: T::Item = unknown;
447 } 441}"#,
448 "#,
449 expect![[r#" 442 expect![[r#"
450 67..100 '{ ...own; }': () 443 67..100 '{ ...own; }': ()
451 77..78 'y': u32 444 77..78 'y': u32
@@ -458,9 +451,8 @@ fn infer_associated_type_bound() {
458fn infer_const_body() { 451fn infer_const_body() {
459 check_infer( 452 check_infer(
460 r#" 453 r#"
461 const A: u32 = 1 + 1; 454const A: u32 = 1 + 1;
462 static B: u64 = { let x = 1; x }; 455static B: u64 = { let x = 1; x };"#,
463 "#,
464 expect![[r#" 456 expect![[r#"
465 15..16 '1': u32 457 15..16 '1': u32
466 15..20 '1 + 1': u32 458 15..20 '1 + 1': u32
@@ -477,13 +469,12 @@ fn infer_const_body() {
477fn tuple_struct_fields() { 469fn tuple_struct_fields() {
478 check_infer( 470 check_infer(
479 r#" 471 r#"
480 struct S(i32, u64); 472struct S(i32, u64);
481 fn test() -> u64 { 473fn test() -> u64 {
482 let a = S(4, 6); 474 let a = S(4, 6);
483 let b = a.0; 475 let b = a.0;
484 a.1 476 a.1
485 } 477}"#,
486 "#,
487 expect![[r#" 478 expect![[r#"
488 37..86 '{ ... a.1 }': u64 479 37..86 '{ ... a.1 }': u64
489 47..48 'a': S 480 47..48 'a': S
@@ -504,13 +495,12 @@ fn tuple_struct_fields() {
504fn tuple_struct_with_fn() { 495fn tuple_struct_with_fn() {
505 check_infer( 496 check_infer(
506 r#" 497 r#"
507 struct S(fn(u32) -> u64); 498struct S(fn(u32) -> u64);
508 fn test() -> u64 { 499fn test() -> u64 {
509 let a = S(|i| 2*i); 500 let a = S(|i| 2*i);
510 let b = a.0(4); 501 let b = a.0(4);
511 a.0(2) 502 a.0(2)
512 } 503}"#,
513 "#,
514 expect![[r#" 504 expect![[r#"
515 43..101 '{ ...0(2) }': u64 505 43..101 '{ ...0(2) }': u64
516 53..54 'a': S 506 53..54 'a': S
@@ -949,27 +939,26 @@ fn test<T: ApplyL>(t: T) {
949fn argument_impl_trait() { 939fn argument_impl_trait() {
950 check_infer_with_mismatches( 940 check_infer_with_mismatches(
951 r#" 941 r#"
952 trait Trait<T> { 942trait Trait<T> {
953 fn foo(&self) -> T; 943 fn foo(&self) -> T;
954 fn foo2(&self) -> i64; 944 fn foo2(&self) -> i64;
955 } 945}
956 fn bar(x: impl Trait<u16>) {} 946fn bar(x: impl Trait<u16>) {}
957 struct S<T>(T); 947struct S<T>(T);
958 impl<T> Trait<T> for S<T> {} 948impl<T> Trait<T> for S<T> {}
959 949
960 fn test(x: impl Trait<u64>, y: &impl Trait<u32>) { 950fn test(x: impl Trait<u64>, y: &impl Trait<u32>) {
961 x; 951 x;
962 y; 952 y;
963 let z = S(1); 953 let z = S(1);
964 bar(z); 954 bar(z);
965 x.foo(); 955 x.foo();
966 y.foo(); 956 y.foo();
967 z.foo(); 957 z.foo();
968 x.foo2(); 958 x.foo2();
969 y.foo2(); 959 y.foo2();
970 z.foo2(); 960 z.foo2();
971 } 961}"#,
972 "#,
973 expect![[r#" 962 expect![[r#"
974 29..33 'self': &Self 963 29..33 'self': &Self
975 54..58 'self': &Self 964 54..58 'self': &Self
@@ -1007,30 +996,29 @@ fn argument_impl_trait() {
1007fn argument_impl_trait_type_args_1() { 996fn argument_impl_trait_type_args_1() {
1008 check_infer_with_mismatches( 997 check_infer_with_mismatches(
1009 r#" 998 r#"
1010 trait Trait {} 999trait Trait {}
1011 trait Foo { 1000trait Foo {
1012 // this function has an implicit Self param, an explicit type param, 1001 // this function has an implicit Self param, an explicit type param,
1013 // and an implicit impl Trait param! 1002 // and an implicit impl Trait param!
1014 fn bar<T>(x: impl Trait) -> T { loop {} } 1003 fn bar<T>(x: impl Trait) -> T { loop {} }
1015 } 1004}
1016 fn foo<T>(x: impl Trait) -> T { loop {} } 1005fn foo<T>(x: impl Trait) -> T { loop {} }
1017 struct S; 1006struct S;
1018 impl Trait for S {} 1007impl Trait for S {}
1019 struct F; 1008struct F;
1020 impl Foo for F {} 1009impl Foo for F {}
1021 1010
1022 fn test() { 1011fn test() {
1023 Foo::bar(S); 1012 Foo::bar(S);
1024 <F as Foo>::bar(S); 1013 <F as Foo>::bar(S);
1025 F::bar(S); 1014 F::bar(S);
1026 Foo::bar::<u32>(S); 1015 Foo::bar::<u32>(S);
1027 <F as Foo>::bar::<u32>(S); 1016 <F as Foo>::bar::<u32>(S);
1028 1017
1029 foo(S); 1018 foo(S);
1030 foo::<u32>(S); 1019 foo::<u32>(S);
1031 foo::<u32, i32>(S); // we should ignore the extraneous i32 1020 foo::<u32, i32>(S); // we should ignore the extraneous i32
1032 } 1021}"#,
1033 "#,
1034 expect![[r#" 1022 expect![[r#"
1035 155..156 'x': impl Trait 1023 155..156 'x': impl Trait
1036 175..186 '{ loop {} }': T 1024 175..186 '{ loop {} }': T
@@ -1073,21 +1061,20 @@ fn argument_impl_trait_type_args_1() {
1073fn argument_impl_trait_type_args_2() { 1061fn argument_impl_trait_type_args_2() {
1074 check_infer_with_mismatches( 1062 check_infer_with_mismatches(
1075 r#" 1063 r#"
1076 trait Trait {} 1064trait Trait {}
1077 struct S; 1065struct S;
1078 impl Trait for S {} 1066impl Trait for S {}
1079 struct F<T>; 1067struct F<T>;
1080 impl<T> F<T> { 1068impl<T> F<T> {
1081 fn foo<U>(self, x: impl Trait) -> (T, U) { loop {} } 1069 fn foo<U>(self, x: impl Trait) -> (T, U) { loop {} }
1082 } 1070}
1083 1071
1084 fn test() { 1072fn test() {
1085 F.foo(S); 1073 F.foo(S);
1086 F::<u32>.foo(S); 1074 F::<u32>.foo(S);
1087 F::<u32>.foo::<i32>(S); 1075 F::<u32>.foo::<i32>(S);
1088 F::<u32>.foo::<i32, u32>(S); // extraneous argument should be ignored 1076 F::<u32>.foo::<i32, u32>(S); // extraneous argument should be ignored
1089 } 1077}"#,
1090 "#,
1091 expect![[r#" 1078 expect![[r#"
1092 87..91 'self': F<T> 1079 87..91 'self': F<T>
1093 93..94 'x': impl Trait 1080 93..94 'x': impl Trait
@@ -1115,15 +1102,14 @@ fn argument_impl_trait_type_args_2() {
1115fn argument_impl_trait_to_fn_pointer() { 1102fn argument_impl_trait_to_fn_pointer() {
1116 check_infer_with_mismatches( 1103 check_infer_with_mismatches(
1117 r#" 1104 r#"
1118 trait Trait {} 1105trait Trait {}
1119 fn foo(x: impl Trait) { loop {} } 1106fn foo(x: impl Trait) { loop {} }
1120 struct S; 1107struct S;
1121 impl Trait for S {} 1108impl Trait for S {}
1122 1109
1123 fn test() { 1110fn test() {
1124 let f: fn(S) -> () = foo; 1111 let f: fn(S) -> () = foo;
1125 } 1112}"#,
1126 "#,
1127 expect![[r#" 1113 expect![[r#"
1128 22..23 'x': impl Trait 1114 22..23 'x': impl Trait
1129 37..48 '{ loop {} }': () 1115 37..48 '{ loop {} }': ()
@@ -1140,24 +1126,23 @@ fn argument_impl_trait_to_fn_pointer() {
1140fn impl_trait() { 1126fn impl_trait() {
1141 check_infer( 1127 check_infer(
1142 r#" 1128 r#"
1143 trait Trait<T> { 1129trait Trait<T> {
1144 fn foo(&self) -> T; 1130 fn foo(&self) -> T;
1145 fn foo2(&self) -> i64; 1131 fn foo2(&self) -> i64;
1146 } 1132}
1147 fn bar() -> impl Trait<u64> {} 1133fn bar() -> impl Trait<u64> {}
1148 1134
1149 fn test(x: impl Trait<u64>, y: &impl Trait<u64>) { 1135fn test(x: impl Trait<u64>, y: &impl Trait<u64>) {
1150 x; 1136 x;
1151 y; 1137 y;
1152 let z = bar(); 1138 let z = bar();
1153 x.foo(); 1139 x.foo();
1154 y.foo(); 1140 y.foo();
1155 z.foo(); 1141 z.foo();
1156 x.foo2(); 1142 x.foo2();
1157 y.foo2(); 1143 y.foo2();
1158 z.foo2(); 1144 z.foo2();
1159 } 1145}"#,
1160 "#,
1161 expect![[r#" 1146 expect![[r#"
1162 29..33 'self': &Self 1147 29..33 'self': &Self
1163 54..58 'self': &Self 1148 54..58 'self': &Self
@@ -1191,16 +1176,15 @@ fn simple_return_pos_impl_trait() {
1191 cov_mark::check!(lower_rpit); 1176 cov_mark::check!(lower_rpit);
1192 check_infer( 1177 check_infer(
1193 r#" 1178 r#"
1194 trait Trait<T> { 1179trait Trait<T> {
1195 fn foo(&self) -> T; 1180 fn foo(&self) -> T;
1196 } 1181}
1197 fn bar() -> impl Trait<u64> { loop {} } 1182fn bar() -> impl Trait<u64> { loop {} }
1198 1183
1199 fn test() { 1184fn test() {
1200 let a = bar(); 1185 let a = bar();
1201 a.foo(); 1186 a.foo();
1202 } 1187}"#,
1203 "#,
1204 expect![[r#" 1188 expect![[r#"
1205 29..33 'self': &Self 1189 29..33 'self': &Self
1206 71..82 '{ loop {} }': ! 1190 71..82 '{ loop {} }': !
@@ -1220,25 +1204,24 @@ fn simple_return_pos_impl_trait() {
1220fn more_return_pos_impl_trait() { 1204fn more_return_pos_impl_trait() {
1221 check_infer( 1205 check_infer(
1222 r#" 1206 r#"
1223 trait Iterator { 1207trait Iterator {
1224 type Item; 1208 type Item;
1225 fn next(&mut self) -> Self::Item; 1209 fn next(&mut self) -> Self::Item;
1226 } 1210}
1227 trait Trait<T> { 1211trait Trait<T> {
1228 fn foo(&self) -> T; 1212 fn foo(&self) -> T;
1229 } 1213}
1230 fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} } 1214fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} }
1231 fn baz<T>(t: T) -> (impl Iterator<Item = impl Trait<T>>, impl Trait<T>) { loop {} } 1215fn baz<T>(t: T) -> (impl Iterator<Item = impl Trait<T>>, impl Trait<T>) { loop {} }
1232 1216
1233 fn test() { 1217fn test() {
1234 let (a, b) = bar(); 1218 let (a, b) = bar();
1235 a.next().foo(); 1219 a.next().foo();
1236 b.foo(); 1220 b.foo();
1237 let (c, d) = baz(1u128); 1221 let (c, d) = baz(1u128);
1238 c.next().foo(); 1222 c.next().foo();
1239 d.foo(); 1223 d.foo();
1240 } 1224}"#,
1241 "#,
1242 expect![[r#" 1225 expect![[r#"
1243 49..53 'self': &mut Self 1226 49..53 'self': &mut Self
1244 101..105 'self': &Self 1227 101..105 'self': &Self
@@ -1279,24 +1262,23 @@ fn more_return_pos_impl_trait() {
1279fn dyn_trait() { 1262fn dyn_trait() {
1280 check_infer( 1263 check_infer(
1281 r#" 1264 r#"
1282 trait Trait<T> { 1265trait Trait<T> {
1283 fn foo(&self) -> T; 1266 fn foo(&self) -> T;
1284 fn foo2(&self) -> i64; 1267 fn foo2(&self) -> i64;
1285 } 1268}
1286 fn bar() -> dyn Trait<u64> {} 1269fn bar() -> dyn Trait<u64> {}
1287 1270
1288 fn test(x: dyn Trait<u64>, y: &dyn Trait<u64>) { 1271fn test(x: dyn Trait<u64>, y: &dyn Trait<u64>) {
1289 x; 1272 x;
1290 y; 1273 y;
1291 let z = bar(); 1274 let z = bar();
1292 x.foo(); 1275 x.foo();
1293 y.foo(); 1276 y.foo();
1294 z.foo(); 1277 z.foo();
1295 x.foo2(); 1278 x.foo2();
1296 y.foo2(); 1279 y.foo2();
1297 z.foo2(); 1280 z.foo2();
1298 } 1281}"#,
1299 "#,
1300 expect![[r#" 1282 expect![[r#"
1301 29..33 'self': &Self 1283 29..33 'self': &Self
1302 54..58 'self': &Self 1284 54..58 'self': &Self
@@ -1329,22 +1311,21 @@ fn dyn_trait() {
1329fn dyn_trait_in_impl() { 1311fn dyn_trait_in_impl() {
1330 check_infer( 1312 check_infer(
1331 r#" 1313 r#"
1332 trait Trait<T, U> { 1314trait Trait<T, U> {
1333 fn foo(&self) -> (T, U); 1315 fn foo(&self) -> (T, U);
1334 } 1316}
1335 struct S<T, U> {} 1317struct S<T, U> {}
1336 impl<T, U> S<T, U> { 1318impl<T, U> S<T, U> {
1337 fn bar(&self) -> &dyn Trait<T, U> { loop {} } 1319 fn bar(&self) -> &dyn Trait<T, U> { loop {} }
1338 } 1320}
1339 trait Trait2<T, U> { 1321trait Trait2<T, U> {
1340 fn baz(&self) -> (T, U); 1322 fn baz(&self) -> (T, U);
1341 } 1323}
1342 impl<T, U> Trait2<T, U> for dyn Trait<T, U> { } 1324impl<T, U> Trait2<T, U> for dyn Trait<T, U> { }
1343 1325
1344 fn test(s: S<u32, i32>) { 1326fn test(s: S<u32, i32>) {
1345 s.bar().baz(); 1327 s.bar().baz();
1346 } 1328}"#,
1347 "#,
1348 expect![[r#" 1329 expect![[r#"
1349 32..36 'self': &Self 1330 32..36 'self': &Self
1350 102..106 'self': &S<T, U> 1331 102..106 'self': &S<T, U>
@@ -1365,20 +1346,19 @@ fn dyn_trait_in_impl() {
1365fn dyn_trait_bare() { 1346fn dyn_trait_bare() {
1366 check_infer( 1347 check_infer(
1367 r#" 1348 r#"
1368 trait Trait { 1349trait Trait {
1369 fn foo(&self) -> u64; 1350 fn foo(&self) -> u64;
1370 } 1351}
1371 fn bar() -> Trait {} 1352fn bar() -> Trait {}
1372 1353
1373 fn test(x: Trait, y: &Trait) -> u64 { 1354fn test(x: Trait, y: &Trait) -> u64 {
1374 x; 1355 x;
1375 y; 1356 y;
1376 let z = bar(); 1357 let z = bar();
1377 x.foo(); 1358 x.foo();
1378 y.foo(); 1359 y.foo();
1379 z.foo(); 1360 z.foo();
1380 } 1361}"#,
1381 "#,
1382 expect![[r#" 1362 expect![[r#"
1383 26..30 'self': &Self 1363 26..30 'self': &Self
1384 60..62 '{}': () 1364 60..62 '{}': ()
@@ -1404,17 +1384,24 @@ fn dyn_trait_bare() {
1404fn weird_bounds() { 1384fn weird_bounds() {
1405 check_infer( 1385 check_infer(
1406 r#" 1386 r#"
1407 trait Trait {} 1387trait Trait {}
1408 fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) {} 1388fn test(
1409 "#, 1389 a: impl Trait + 'lifetime,
1390 b: impl 'lifetime,
1391 c: impl (Trait),
1392 d: impl ('lifetime),
1393 e: impl ?Sized,
1394 f: impl Trait + ?Sized
1395) {}
1396"#,
1410 expect![[r#" 1397 expect![[r#"
1411 23..24 'a': impl Trait 1398 28..29 'a': impl Trait
1412 50..51 'b': impl 1399 59..60 'b': impl
1413 69..70 'c': impl Trait 1400 82..83 'c': impl Trait
1414 86..87 'd': impl 1401 103..104 'd': impl
1415 107..108 'e': impl 1402 128..129 'e': impl
1416 123..124 'f': impl Trait 1403 148..149 'f': impl Trait
1417 147..149 '{}': () 1404 173..175 '{}': ()
1418 "#]], 1405 "#]],
1419 ); 1406 );
1420} 1407}
@@ -1439,27 +1426,26 @@ fn test(x: (impl Trait + UnknownTrait)) {
1439fn assoc_type_bindings() { 1426fn assoc_type_bindings() {
1440 check_infer( 1427 check_infer(
1441 r#" 1428 r#"
1442 trait Trait { 1429trait Trait {
1443 type Type; 1430 type Type;
1444 } 1431}
1445 1432
1446 fn get<T: Trait>(t: T) -> <T as Trait>::Type {} 1433fn get<T: Trait>(t: T) -> <T as Trait>::Type {}
1447 fn get2<U, T: Trait<Type = U>>(t: T) -> U {} 1434fn get2<U, T: Trait<Type = U>>(t: T) -> U {}
1448 fn set<T: Trait<Type = u64>>(t: T) -> T {t} 1435fn set<T: Trait<Type = u64>>(t: T) -> T {t}
1449 1436
1450 struct S<T>; 1437struct S<T>;
1451 impl<T> Trait for S<T> { type Type = T; } 1438impl<T> Trait for S<T> { type Type = T; }
1452 1439
1453 fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) { 1440fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) {
1454 get(x); 1441 get(x);
1455 get2(x); 1442 get2(x);
1456 get(y); 1443 get(y);
1457 get2(y); 1444 get2(y);
1458 get(set(S)); 1445 get(set(S));
1459 get2(set(S)); 1446 get2(set(S));
1460 get2(S::<str>); 1447 get2(S::<str>);
1461 } 1448}"#,
1462 "#,
1463 expect![[r#" 1449 expect![[r#"
1464 49..50 't': T 1450 49..50 't': T
1465 77..79 '{}': () 1451 77..79 '{}': ()
@@ -1546,18 +1532,17 @@ mod iter {
1546fn projection_eq_within_chalk() { 1532fn projection_eq_within_chalk() {
1547 check_infer( 1533 check_infer(
1548 r#" 1534 r#"
1549 trait Trait1 { 1535trait Trait1 {
1550 type Type; 1536 type Type;
1551 } 1537}
1552 trait Trait2<T> { 1538trait Trait2<T> {
1553 fn foo(self) -> T; 1539 fn foo(self) -> T;
1554 } 1540}
1555 impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {} 1541impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {}
1556 1542
1557 fn test<T: Trait1<Type = u32>>(x: T) { 1543fn test<T: Trait1<Type = u32>>(x: T) {
1558 x.foo(); 1544 x.foo();
1559 } 1545}"#,
1560 "#,
1561 expect![[r#" 1546 expect![[r#"
1562 61..65 'self': Self 1547 61..65 'self': Self
1563 163..164 'x': T 1548 163..164 'x': T
@@ -1589,19 +1574,18 @@ fn test<T: foo::Trait>(x: T) {
1589fn super_trait_method_resolution() { 1574fn super_trait_method_resolution() {
1590 check_infer( 1575 check_infer(
1591 r#" 1576 r#"
1592 mod foo { 1577mod foo {
1593 trait SuperTrait { 1578 trait SuperTrait {
1594 fn foo(&self) -> u32 {} 1579 fn foo(&self) -> u32 {}
1595 } 1580 }
1596 } 1581}
1597 trait Trait1: foo::SuperTrait {} 1582trait Trait1: foo::SuperTrait {}
1598 trait Trait2 where Self: foo::SuperTrait {} 1583trait Trait2 where Self: foo::SuperTrait {}
1599 1584
1600 fn test<T: Trait1, U: Trait2>(x: T, y: U) { 1585fn test<T: Trait1, U: Trait2>(x: T, y: U) {
1601 x.foo(); 1586 x.foo();
1602 y.foo(); 1587 y.foo();
1603 } 1588}"#,
1604 "#,
1605 expect![[r#" 1589 expect![[r#"
1606 49..53 'self': &Self 1590 49..53 'self': &Self
1607 62..64 '{}': () 1591 62..64 '{}': ()
@@ -1620,17 +1604,16 @@ fn super_trait_method_resolution() {
1620fn super_trait_impl_trait_method_resolution() { 1604fn super_trait_impl_trait_method_resolution() {
1621 check_infer( 1605 check_infer(
1622 r#" 1606 r#"
1623 mod foo { 1607mod foo {
1624 trait SuperTrait { 1608 trait SuperTrait {
1625 fn foo(&self) -> u32 {} 1609 fn foo(&self) -> u32 {}
1626 } 1610 }
1627 } 1611}
1628 trait Trait1: foo::SuperTrait {} 1612trait Trait1: foo::SuperTrait {}
1629 1613
1630 fn test(x: &impl Trait1) { 1614fn test(x: &impl Trait1) {
1631 x.foo(); 1615 x.foo();
1632 } 1616}"#,
1633 "#,
1634 expect![[r#" 1617 expect![[r#"
1635 49..53 'self': &Self 1618 49..53 'self': &Self
1636 62..64 '{}': () 1619 62..64 '{}': ()
@@ -1667,20 +1650,19 @@ fn super_trait_cycle() {
1667fn super_trait_assoc_type_bounds() { 1650fn super_trait_assoc_type_bounds() {
1668 check_infer( 1651 check_infer(
1669 r#" 1652 r#"
1670 trait SuperTrait { type Type; } 1653trait SuperTrait { type Type; }
1671 trait Trait where Self: SuperTrait {} 1654trait Trait where Self: SuperTrait {}
1672 1655
1673 fn get2<U, T: Trait<Type = U>>(t: T) -> U {} 1656fn get2<U, T: Trait<Type = U>>(t: T) -> U {}
1674 fn set<T: Trait<Type = u64>>(t: T) -> T {t} 1657fn set<T: Trait<Type = u64>>(t: T) -> T {t}
1675 1658
1676 struct S<T>; 1659struct S<T>;
1677 impl<T> SuperTrait for S<T> { type Type = T; } 1660impl<T> SuperTrait for S<T> { type Type = T; }
1678 impl<T> Trait for S<T> {} 1661impl<T> Trait for S<T> {}
1679 1662
1680 fn test() { 1663fn test() {
1681 get2(set(S)); 1664 get2(set(S));
1682 } 1665}"#,
1683 "#,
1684 expect![[r#" 1666 expect![[r#"
1685 102..103 't': T 1667 102..103 't': T
1686 113..115 '{}': () 1668 113..115 '{}': ()
@@ -1701,16 +1683,15 @@ fn super_trait_assoc_type_bounds() {
1701fn fn_trait() { 1683fn fn_trait() {
1702 check_infer_with_mismatches( 1684 check_infer_with_mismatches(
1703 r#" 1685 r#"
1704 trait FnOnce<Args> { 1686trait FnOnce<Args> {
1705 type Output; 1687 type Output;
1706 1688
1707 fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output; 1689 fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output;
1708 } 1690}
1709 1691
1710 fn test<F: FnOnce(u32, u64) -> u128>(f: F) { 1692fn test<F: FnOnce(u32, u64) -> u128>(f: F) {
1711 f.call_once((1, 2)); 1693 f.call_once((1, 2));
1712 } 1694}"#,
1713 "#,
1714 expect![[r#" 1695 expect![[r#"
1715 56..60 'self': Self 1696 56..60 'self': Self
1716 62..66 'args': Args 1697 62..66 'args': Args
@@ -1729,37 +1710,36 @@ fn fn_trait() {
1729fn fn_ptr_and_item() { 1710fn fn_ptr_and_item() {
1730 check_infer_with_mismatches( 1711 check_infer_with_mismatches(
1731 r#" 1712 r#"
1732 #[lang="fn_once"] 1713#[lang="fn_once"]
1733 trait FnOnce<Args> { 1714trait FnOnce<Args> {
1734 type Output; 1715 type Output;
1735 1716
1736 fn call_once(self, args: Args) -> Self::Output; 1717 fn call_once(self, args: Args) -> Self::Output;
1737 } 1718}
1738 1719
1739 trait Foo<T> { 1720trait Foo<T> {
1740 fn foo(&self) -> T; 1721 fn foo(&self) -> T;
1741 } 1722}
1742 1723
1743 struct Bar<T>(T); 1724struct Bar<T>(T);
1744 1725
1745 impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> { 1726impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> {
1746 fn foo(&self) -> (A1, R) { loop {} } 1727 fn foo(&self) -> (A1, R) { loop {} }
1747 } 1728}
1748 1729
1749 enum Opt<T> { None, Some(T) } 1730enum Opt<T> { None, Some(T) }
1750 impl<T> Opt<T> { 1731impl<T> Opt<T> {
1751 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> { loop {} } 1732 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> { loop {} }
1752 } 1733}
1753 1734
1754 fn test() { 1735fn test() {
1755 let bar: Bar<fn(u8) -> u32>; 1736 let bar: Bar<fn(u8) -> u32>;
1756 bar.foo(); 1737 bar.foo();
1757 1738
1758 let opt: Opt<u8>; 1739 let opt: Opt<u8>;
1759 let f: fn(u8) -> u32; 1740 let f: fn(u8) -> u32;
1760 opt.map(f); 1741 opt.map(f);
1761 } 1742}"#,
1762 "#,
1763 expect![[r#" 1743 expect![[r#"
1764 74..78 'self': Self 1744 74..78 'self': Self
1765 80..84 'args': Args 1745 80..84 'args': Args
@@ -1790,46 +1770,45 @@ fn fn_ptr_and_item() {
1790fn fn_trait_deref_with_ty_default() { 1770fn fn_trait_deref_with_ty_default() {
1791 check_infer( 1771 check_infer(
1792 r#" 1772 r#"
1793 #[lang = "deref"] 1773#[lang = "deref"]
1794 trait Deref { 1774trait Deref {
1795 type Target; 1775 type Target;
1796 1776
1797 fn deref(&self) -> &Self::Target; 1777 fn deref(&self) -> &Self::Target;
1798 } 1778}
1799 1779
1800 #[lang="fn_once"] 1780#[lang="fn_once"]
1801 trait FnOnce<Args> { 1781trait FnOnce<Args> {
1802 type Output; 1782 type Output;
1803 1783
1804 fn call_once(self, args: Args) -> Self::Output; 1784 fn call_once(self, args: Args) -> Self::Output;
1805 } 1785}
1806 1786
1807 struct Foo; 1787struct Foo;
1808 1788
1809 impl Foo { 1789impl Foo {
1810 fn foo(&self) -> usize {} 1790 fn foo(&self) -> usize {}
1811 } 1791}
1812 1792
1813 struct Lazy<T, F = fn() -> T>(F); 1793struct Lazy<T, F = fn() -> T>(F);
1814 1794
1815 impl<T, F> Lazy<T, F> { 1795impl<T, F> Lazy<T, F> {
1816 pub fn new(f: F) -> Lazy<T, F> {} 1796 pub fn new(f: F) -> Lazy<T, F> {}
1817 } 1797}
1818 1798
1819 impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> { 1799impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
1820 type Target = T; 1800 type Target = T;
1821 } 1801}
1822 1802
1823 fn test() { 1803fn test() {
1824 let lazy1: Lazy<Foo, _> = Lazy::new(|| Foo); 1804 let lazy1: Lazy<Foo, _> = Lazy::new(|| Foo);
1825 let r1 = lazy1.foo(); 1805 let r1 = lazy1.foo();
1826 1806
1827 fn make_foo_fn() -> Foo {} 1807 fn make_foo_fn() -> Foo {}
1828 let make_foo_fn_ptr: fn() -> Foo = make_foo_fn; 1808 let make_foo_fn_ptr: fn() -> Foo = make_foo_fn;
1829 let lazy2: Lazy<Foo, _> = Lazy::new(make_foo_fn_ptr); 1809 let lazy2: Lazy<Foo, _> = Lazy::new(make_foo_fn_ptr);
1830 let r2 = lazy2.foo(); 1810 let r2 = lazy2.foo();
1831 } 1811}"#,
1832 "#,
1833 expect![[r#" 1812 expect![[r#"
1834 64..68 'self': &Self 1813 64..68 'self': &Self
1835 165..169 'self': Self 1814 165..169 'self': Self
@@ -1865,23 +1844,22 @@ fn fn_trait_deref_with_ty_default() {
1865fn closure_1() { 1844fn closure_1() {
1866 check_infer_with_mismatches( 1845 check_infer_with_mismatches(
1867 r#" 1846 r#"
1868 #[lang = "fn_once"] 1847#[lang = "fn_once"]
1869 trait FnOnce<Args> { 1848trait FnOnce<Args> {
1870 type Output; 1849 type Output;
1871 } 1850}
1872 1851
1873 enum Option<T> { Some(T), None } 1852enum Option<T> { Some(T), None }
1874 impl<T> Option<T> { 1853impl<T> Option<T> {
1875 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> { loop {} } 1854 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> { loop {} }
1876 } 1855}
1877 1856
1878 fn test() { 1857fn test() {
1879 let x = Option::Some(1u32); 1858 let x = Option::Some(1u32);
1880 x.map(|v| v + 1); 1859 x.map(|v| v + 1);
1881 x.map(|_v| 1u64); 1860 x.map(|_v| 1u64);
1882 let y: Option<i64> = x.map(|_v| 1); 1861 let y: Option<i64> = x.map(|_v| 1);
1883 } 1862}"#,
1884 "#,
1885 expect![[r#" 1863 expect![[r#"
1886 147..151 'self': Option<T> 1864 147..151 'self': Option<T>
1887 153..154 'f': F 1865 153..154 'f': F
@@ -1919,38 +1897,63 @@ fn closure_1() {
1919fn closure_2() { 1897fn closure_2() {
1920 check_infer_with_mismatches( 1898 check_infer_with_mismatches(
1921 r#" 1899 r#"
1922 trait FnOnce<Args> { 1900#[lang = "add"]
1923 type Output; 1901pub trait Add<Rhs = Self> {
1924 } 1902 type Output;
1903 fn add(self, rhs: Rhs) -> Self::Output;
1904}
1925 1905
1926 fn test<F: FnOnce(u32) -> u64>(f: F) { 1906trait FnOnce<Args> {
1927 f(1); 1907 type Output;
1928 let g = |v| v + 1; 1908}
1929 g(1u64); 1909
1930 let h = |v| 1u128 + v; 1910impl Add for u64 {
1931 } 1911 type Output = Self;
1932 "#, 1912 fn add(self, rhs: u64) -> Self::Output {0}
1913}
1914
1915impl Add for u128 {
1916 type Output = Self;
1917 fn add(self, rhs: u128) -> Self::Output {0}
1918}
1919
1920fn test<F: FnOnce(u32) -> u64>(f: F) {
1921 f(1);
1922 let g = |v| v + 1;
1923 g(1u64);
1924 let h = |v| 1u128 + v;
1925}"#,
1933 expect![[r#" 1926 expect![[r#"
1934 72..73 'f': F 1927 72..76 'self': Self
1935 78..154 '{ ...+ v; }': () 1928 78..81 'rhs': Rhs
1936 84..85 'f': F 1929 203..207 'self': u64
1937 84..88 'f(1)': {unknown} 1930 209..212 'rhs': u64
1938 86..87 '1': i32 1931 235..238 '{0}': u64
1939 98..99 'g': |u64| -> i32 1932 236..237 '0': u64
1940 102..111 '|v| v + 1': |u64| -> i32 1933 297..301 'self': u128
1941 103..104 'v': u64 1934 303..306 'rhs': u128
1942 106..107 'v': u64 1935 330..333 '{0}': u128
1943 106..111 'v + 1': i32 1936 331..332 '0': u128
1944 110..111 '1': i32 1937 368..369 'f': F
1945 117..118 'g': |u64| -> i32 1938 374..450 '{ ...+ v; }': ()
1946 117..124 'g(1u64)': i32 1939 380..381 'f': F
1947 119..123 '1u64': u64 1940 380..384 'f(1)': {unknown}
1948 134..135 'h': |u128| -> u128 1941 382..383 '1': i32
1949 138..151 '|v| 1u128 + v': |u128| -> u128 1942 394..395 'g': |u64| -> u64
1950 139..140 'v': u128 1943 398..407 '|v| v + 1': |u64| -> u64
1951 142..147 '1u128': u128 1944 399..400 'v': u64
1952 142..151 '1u128 + v': u128 1945 402..403 'v': u64
1953 150..151 'v': u128 1946 402..407 'v + 1': u64
1947 406..407 '1': u64
1948 413..414 'g': |u64| -> u64
1949 413..420 'g(1u64)': u64
1950 415..419 '1u64': u64
1951 430..431 'h': |u128| -> u128
1952 434..447 '|v| 1u128 + v': |u128| -> u128
1953 435..436 'v': u128
1954 438..443 '1u128': u128
1955 438..447 '1u128 + v': u128
1956 446..447 'v': u128
1954 "#]], 1957 "#]],
1955 ); 1958 );
1956} 1959}
@@ -1959,29 +1962,28 @@ fn closure_2() {
1959fn closure_as_argument_inference_order() { 1962fn closure_as_argument_inference_order() {
1960 check_infer_with_mismatches( 1963 check_infer_with_mismatches(
1961 r#" 1964 r#"
1962 #[lang = "fn_once"] 1965#[lang = "fn_once"]
1963 trait FnOnce<Args> { 1966trait FnOnce<Args> {
1964 type Output; 1967 type Output;
1965 } 1968}
1966 1969
1967 fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U { loop {} } 1970fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U { loop {} }
1968 fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U { loop {} } 1971fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U { loop {} }
1969 1972
1970 struct S; 1973struct S;
1971 impl S { 1974impl S {
1972 fn method(self) -> u64; 1975 fn method(self) -> u64;
1973 1976
1974 fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U { loop {} } 1977 fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U { loop {} }
1975 fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U { loop {} } 1978 fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U { loop {} }
1976 } 1979}
1977 1980
1978 fn test() { 1981fn test() {
1979 let x1 = foo1(S, |s| s.method()); 1982 let x1 = foo1(S, |s| s.method());
1980 let x2 = foo2(|s| s.method(), S); 1983 let x2 = foo2(|s| s.method(), S);
1981 let x3 = S.foo1(S, |s| s.method()); 1984 let x3 = S.foo1(S, |s| s.method());
1982 let x4 = S.foo2(|s| s.method(), S); 1985 let x4 = S.foo2(|s| s.method(), S);
1983 } 1986}"#,
1984 "#,
1985 expect![[r#" 1987 expect![[r#"
1986 94..95 'x': T 1988 94..95 'x': T
1987 100..101 'f': F 1989 100..101 'f': F
@@ -2110,27 +2112,26 @@ fn test<T, U>() where T::Item: Trait2, T: Trait<U::Item>, U: Trait<()> {
2110fn unselected_projection_on_impl_self() { 2112fn unselected_projection_on_impl_self() {
2111 check_infer( 2113 check_infer(
2112 r#" 2114 r#"
2113 //- /main.rs 2115//- /main.rs
2114 trait Trait { 2116trait Trait {
2115 type Item; 2117 type Item;
2116 2118
2117 fn f(&self, x: Self::Item); 2119 fn f(&self, x: Self::Item);
2118 } 2120}
2119 2121
2120 struct S; 2122struct S;
2121 2123
2122 impl Trait for S { 2124impl Trait for S {
2123 type Item = u32; 2125 type Item = u32;
2124 fn f(&self, x: Self::Item) { let y = x; } 2126 fn f(&self, x: Self::Item) { let y = x; }
2125 } 2127}
2126 2128
2127 struct S2; 2129struct S2;
2128 2130
2129 impl Trait for S2 { 2131impl Trait for S2 {
2130 type Item = i32; 2132 type Item = i32;
2131 fn f(&self, x: <Self>::Item) { let y = x; } 2133 fn f(&self, x: <Self>::Item) { let y = x; }
2132 } 2134}"#,
2133 "#,
2134 expect![[r#" 2135 expect![[r#"
2135 40..44 'self': &Self 2136 40..44 'self': &Self
2136 46..47 'x': Trait::Item<Self> 2137 46..47 'x': Trait::Item<Self>
@@ -2366,58 +2367,57 @@ fn test<I: Iterator<Item: Iterator<Item = u32>>>() {
2366fn proc_macro_server_types() { 2367fn proc_macro_server_types() {
2367 check_infer( 2368 check_infer(
2368 r#" 2369 r#"
2369 macro_rules! with_api { 2370macro_rules! with_api {
2370 ($S:ident, $self:ident, $m:ident) => { 2371 ($S:ident, $self:ident, $m:ident) => {
2371 $m! { 2372 $m! {
2372 TokenStream { 2373 TokenStream {
2373 fn new() -> $S::TokenStream; 2374 fn new() -> $S::TokenStream;
2374 }, 2375 },
2375 Group { 2376 Group {
2376 }, 2377 },
2377 }
2378 };
2379 } 2378 }
2380 macro_rules! associated_item { 2379 };
2381 (type TokenStream) => 2380}
2382 (type TokenStream: 'static;); 2381macro_rules! associated_item {
2383 (type Group) => 2382 (type TokenStream) =>
2384 (type Group: 'static;); 2383 (type TokenStream: 'static;);
2385 ($($item:tt)*) => ($($item)*;) 2384 (type Group) =>
2386 } 2385 (type Group: 'static;);
2387 macro_rules! declare_server_traits { 2386 ($($item:tt)*) => ($($item)*;)
2388 ($($name:ident { 2387}
2389 $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* 2388macro_rules! declare_server_traits {
2390 }),* $(,)?) => { 2389 ($($name:ident {
2391 pub trait Types { 2390 $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
2392 $(associated_item!(type $name);)* 2391 }),* $(,)?) => {
2393 } 2392 pub trait Types {
2394 2393 $(associated_item!(type $name);)*
2395 $(pub trait $name: Types {
2396 $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)*
2397 })*
2398
2399 pub trait Server: Types $(+ $name)* {}
2400 impl<S: Types $(+ $name)*> Server for S {}
2401 }
2402 } 2394 }
2403 2395
2404 with_api!(Self, self_, declare_server_traits); 2396 $(pub trait $name: Types {
2405 struct G {} 2397 $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)*
2406 struct T {} 2398 })*
2407 struct Rustc;
2408 impl Types for Rustc {
2409 type TokenStream = T;
2410 type Group = G;
2411 }
2412 2399
2413 fn make<T>() -> T { loop {} } 2400 pub trait Server: Types $(+ $name)* {}
2414 impl TokenStream for Rustc { 2401 impl<S: Types $(+ $name)*> Server for S {}
2415 fn new() -> Self::TokenStream { 2402 }
2416 let group: Self::Group = make(); 2403}
2417 make() 2404
2418 } 2405with_api!(Self, self_, declare_server_traits);
2419 } 2406struct G {}
2420 "#, 2407struct T {}
2408struct Rustc;
2409impl Types for Rustc {
2410 type TokenStream = T;
2411 type Group = G;
2412}
2413
2414fn make<T>() -> T { loop {} }
2415impl TokenStream for Rustc {
2416 fn new() -> Self::TokenStream {
2417 let group: Self::Group = make();
2418 make()
2419 }
2420}"#,
2421 expect![[r#" 2421 expect![[r#"
2422 1061..1072 '{ loop {} }': T 2422 1061..1072 '{ loop {} }': T
2423 1063..1070 'loop {}': ! 2423 1063..1070 'loop {}': !
@@ -2436,23 +2436,22 @@ fn proc_macro_server_types() {
2436fn unify_impl_trait() { 2436fn unify_impl_trait() {
2437 check_infer_with_mismatches( 2437 check_infer_with_mismatches(
2438 r#" 2438 r#"
2439 trait Trait<T> {} 2439trait Trait<T> {}
2440 2440
2441 fn foo(x: impl Trait<u32>) { loop {} } 2441fn foo(x: impl Trait<u32>) { loop {} }
2442 fn bar<T>(x: impl Trait<T>) -> T { loop {} } 2442fn bar<T>(x: impl Trait<T>) -> T { loop {} }
2443 2443
2444 struct S<T>(T); 2444struct S<T>(T);
2445 impl<T> Trait<T> for S<T> {} 2445impl<T> Trait<T> for S<T> {}
2446 2446
2447 fn default<T>() -> T { loop {} } 2447fn default<T>() -> T { loop {} }
2448 2448
2449 fn test() -> impl Trait<i32> { 2449fn test() -> impl Trait<i32> {
2450 let s1 = S(default()); 2450 let s1 = S(default());
2451 foo(s1); 2451 foo(s1);
2452 let x: i32 = bar(S(default())); 2452 let x: i32 = bar(S(default()));
2453 S(default()) 2453 S(default())
2454 } 2454}"#,
2455 "#,
2456 expect![[r#" 2455 expect![[r#"
2457 26..27 'x': impl Trait<u32> 2456 26..27 'x': impl Trait<u32>
2458 46..57 '{ loop {} }': () 2457 46..57 '{ loop {} }': ()
@@ -2493,30 +2492,29 @@ fn unify_impl_trait() {
2493fn assoc_types_from_bounds() { 2492fn assoc_types_from_bounds() {
2494 check_infer( 2493 check_infer(
2495 r#" 2494 r#"
2496 //- /main.rs 2495//- /main.rs
2497 #[lang = "fn_once"] 2496#[lang = "fn_once"]
2498 trait FnOnce<Args> { 2497trait FnOnce<Args> {
2499 type Output; 2498 type Output;
2500 } 2499}
2501 2500
2502 trait T { 2501trait T {
2503 type O; 2502 type O;
2504 } 2503}
2505 2504
2506 impl T for () { 2505impl T for () {
2507 type O = (); 2506 type O = ();
2508 } 2507}
2509 2508
2510 fn f<X, F>(_v: F) 2509fn f<X, F>(_v: F)
2511 where 2510where
2512 X: T, 2511 X: T,
2513 F: FnOnce(&X::O), 2512 F: FnOnce(&X::O),
2514 { } 2513{ }
2515 2514
2516 fn main() { 2515fn main() {
2517 f::<(), _>(|z| { z; }); 2516 f::<(), _>(|z| { z; });
2518 } 2517}"#,
2519 "#,
2520 expect![[r#" 2518 expect![[r#"
2521 133..135 '_v': F 2519 133..135 '_v': F
2522 178..181 '{ }': () 2520 178..181 '{ }': ()
@@ -2602,76 +2600,75 @@ fn test() {
2602fn iterator_chain() { 2600fn iterator_chain() {
2603 check_infer_with_mismatches( 2601 check_infer_with_mismatches(
2604 r#" 2602 r#"
2605 //- /main.rs 2603//- /main.rs
2606 #[lang = "fn_once"] 2604#[lang = "fn_once"]
2607 trait FnOnce<Args> { 2605trait FnOnce<Args> {
2608 type Output; 2606 type Output;
2609 } 2607}
2610 #[lang = "fn_mut"] 2608#[lang = "fn_mut"]
2611 trait FnMut<Args>: FnOnce<Args> { } 2609trait FnMut<Args>: FnOnce<Args> { }
2612 2610
2613 enum Option<T> { Some(T), None } 2611enum Option<T> { Some(T), None }
2614 use Option::*; 2612use Option::*;
2615 2613
2616 pub trait Iterator { 2614pub trait Iterator {
2617 type Item; 2615 type Item;
2618 2616
2619 fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> 2617 fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
2620 where 2618 where
2621 F: FnMut(Self::Item) -> Option<B>, 2619 F: FnMut(Self::Item) -> Option<B>,
2622 { loop {} } 2620 { loop {} }
2623 2621
2624 fn for_each<F>(self, f: F) 2622 fn for_each<F>(self, f: F)
2625 where 2623 where
2626 F: FnMut(Self::Item), 2624 F: FnMut(Self::Item),
2627 { loop {} } 2625 { loop {} }
2628 } 2626}
2629 2627
2630 pub trait IntoIterator { 2628pub trait IntoIterator {
2631 type Item; 2629 type Item;
2632 type IntoIter: Iterator<Item = Self::Item>; 2630 type IntoIter: Iterator<Item = Self::Item>;
2633 fn into_iter(self) -> Self::IntoIter; 2631 fn into_iter(self) -> Self::IntoIter;
2634 } 2632}
2635 2633
2636 pub struct FilterMap<I, F> { } 2634pub struct FilterMap<I, F> { }
2637 impl<B, I: Iterator, F> Iterator for FilterMap<I, F> 2635impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
2638 where 2636where
2639 F: FnMut(I::Item) -> Option<B>, 2637 F: FnMut(I::Item) -> Option<B>,
2640 { 2638{
2641 type Item = B; 2639 type Item = B;
2642 } 2640}
2643 2641
2644 #[stable(feature = "rust1", since = "1.0.0")] 2642#[stable(feature = "rust1", since = "1.0.0")]
2645 impl<I: Iterator> IntoIterator for I { 2643impl<I: Iterator> IntoIterator for I {
2646 type Item = I::Item; 2644 type Item = I::Item;
2647 type IntoIter = I; 2645 type IntoIter = I;
2648 2646
2649 fn into_iter(self) -> I { 2647 fn into_iter(self) -> I {
2650 self 2648 self
2651 } 2649 }
2652 } 2650}
2653 2651
2654 struct Vec<T> {} 2652struct Vec<T> {}
2655 impl<T> Vec<T> { 2653impl<T> Vec<T> {
2656 fn new() -> Self { loop {} } 2654 fn new() -> Self { loop {} }
2657 } 2655}
2658 2656
2659 impl<T> IntoIterator for Vec<T> { 2657impl<T> IntoIterator for Vec<T> {
2660 type Item = T; 2658 type Item = T;
2661 type IntoIter = IntoIter<T>; 2659 type IntoIter = IntoIter<T>;
2662 } 2660}
2663 2661
2664 pub struct IntoIter<T> { } 2662pub struct IntoIter<T> { }
2665 impl<T> Iterator for IntoIter<T> { 2663impl<T> Iterator for IntoIter<T> {
2666 type Item = T; 2664 type Item = T;
2667 } 2665}
2668 2666
2669 fn main() { 2667fn main() {
2670 Vec::<i32>::new().into_iter() 2668 Vec::<i32>::new().into_iter()
2671 .filter_map(|x| if x > 0 { Some(x as u32) } else { None }) 2669 .filter_map(|x| if x > 0 { Some(x as u32) } else { None })
2672 .for_each(|y| { y; }); 2670 .for_each(|y| { y; });
2673 } 2671}"#,
2674 "#,
2675 expect![[r#" 2672 expect![[r#"
2676 226..230 'self': Self 2673 226..230 'self': Self
2677 232..233 'f': F 2674 232..233 'f': F
@@ -2753,14 +2750,13 @@ fn main() {
2753fn trait_object_no_coercion() { 2750fn trait_object_no_coercion() {
2754 check_infer_with_mismatches( 2751 check_infer_with_mismatches(
2755 r#" 2752 r#"
2756 trait Foo {} 2753trait Foo {}
2757 2754
2758 fn foo(x: &dyn Foo) {} 2755fn foo(x: &dyn Foo) {}
2759 2756
2760 fn test(x: &dyn Foo) { 2757fn test(x: &dyn Foo) {
2761 foo(x); 2758 foo(x);
2762 } 2759}"#,
2763 "#,
2764 expect![[r#" 2760 expect![[r#"
2765 21..22 'x': &dyn Foo 2761 21..22 'x': &dyn Foo
2766 34..36 '{}': () 2762 34..36 '{}': ()
@@ -2777,23 +2773,22 @@ fn trait_object_no_coercion() {
2777fn builtin_copy() { 2773fn builtin_copy() {
2778 check_infer_with_mismatches( 2774 check_infer_with_mismatches(
2779 r#" 2775 r#"
2780 #[lang = "copy"] 2776#[lang = "copy"]
2781 trait Copy {} 2777trait Copy {}
2782 2778
2783 struct IsCopy; 2779struct IsCopy;
2784 impl Copy for IsCopy {} 2780impl Copy for IsCopy {}
2785 struct NotCopy; 2781struct NotCopy;
2786 2782
2787 trait Test { fn test(&self) -> bool; } 2783trait Test { fn test(&self) -> bool; }
2788 impl<T: Copy> Test for T {} 2784impl<T: Copy> Test for T {}
2789 2785
2790 fn test() { 2786fn test() {
2791 IsCopy.test(); 2787 IsCopy.test();
2792 NotCopy.test(); 2788 NotCopy.test();
2793 (IsCopy, IsCopy).test(); 2789 (IsCopy, IsCopy).test();
2794 (IsCopy, NotCopy).test(); 2790 (IsCopy, NotCopy).test();
2795 } 2791}"#,
2796 "#,
2797 expect![[r#" 2792 expect![[r#"
2798 110..114 'self': &Self 2793 110..114 'self': &Self
2799 166..267 '{ ...t(); }': () 2794 166..267 '{ ...t(); }': ()
@@ -2817,24 +2812,23 @@ fn builtin_copy() {
2817fn builtin_fn_def_copy() { 2812fn builtin_fn_def_copy() {
2818 check_infer_with_mismatches( 2813 check_infer_with_mismatches(
2819 r#" 2814 r#"
2820 #[lang = "copy"] 2815#[lang = "copy"]
2821 trait Copy {} 2816trait Copy {}
2822 2817
2823 fn foo() {} 2818fn foo() {}
2824 fn bar<T: Copy>(T) -> T {} 2819fn bar<T: Copy>(T) -> T {}
2825 struct Struct(usize); 2820struct Struct(usize);
2826 enum Enum { Variant(usize) } 2821enum Enum { Variant(usize) }
2827 2822
2828 trait Test { fn test(&self) -> bool; } 2823trait Test { fn test(&self) -> bool; }
2829 impl<T: Copy> Test for T {} 2824impl<T: Copy> Test for T {}
2830 2825
2831 fn test() { 2826fn test() {
2832 foo.test(); 2827 foo.test();
2833 bar.test(); 2828 bar.test();
2834 Struct.test(); 2829 Struct.test();
2835 Enum::Variant.test(); 2830 Enum::Variant.test();
2836 } 2831}"#,
2837 "#,
2838 expect![[r#" 2832 expect![[r#"
2839 41..43 '{}': () 2833 41..43 '{}': ()
2840 60..61 'T': {unknown} 2834 60..61 'T': {unknown}
@@ -2858,18 +2852,17 @@ fn builtin_fn_def_copy() {
2858fn builtin_fn_ptr_copy() { 2852fn builtin_fn_ptr_copy() {
2859 check_infer_with_mismatches( 2853 check_infer_with_mismatches(
2860 r#" 2854 r#"
2861 #[lang = "copy"] 2855#[lang = "copy"]
2862 trait Copy {} 2856trait Copy {}
2863 2857
2864 trait Test { fn test(&self) -> bool; } 2858trait Test { fn test(&self) -> bool; }
2865 impl<T: Copy> Test for T {} 2859impl<T: Copy> Test for T {}
2866 2860
2867 fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) { 2861fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) {
2868 f1.test(); 2862 f1.test();
2869 f2.test(); 2863 f2.test();
2870 f3.test(); 2864 f3.test();
2871 } 2865}"#,
2872 "#,
2873 expect![[r#" 2866 expect![[r#"
2874 54..58 'self': &Self 2867 54..58 'self': &Self
2875 108..110 'f1': fn() 2868 108..110 'f1': fn()
@@ -2890,19 +2883,18 @@ fn builtin_fn_ptr_copy() {
2890fn builtin_sized() { 2883fn builtin_sized() {
2891 check_infer_with_mismatches( 2884 check_infer_with_mismatches(
2892 r#" 2885 r#"
2893 #[lang = "sized"] 2886#[lang = "sized"]
2894 trait Sized {} 2887trait Sized {}
2895 2888
2896 trait Test { fn test(&self) -> bool; } 2889trait Test { fn test(&self) -> bool; }
2897 impl<T: Sized> Test for T {} 2890impl<T: Sized> Test for T {}
2898 2891
2899 fn test() { 2892fn test() {
2900 1u8.test(); 2893 1u8.test();
2901 (*"foo").test(); // not Sized 2894 (*"foo").test(); // not Sized
2902 (1u8, 1u8).test(); 2895 (1u8, 1u8).test();
2903 (1u8, *"foo").test(); // not Sized 2896 (1u8, *"foo").test(); // not Sized
2904 } 2897}"#,
2905 "#,
2906 expect![[r#" 2898 expect![[r#"
2907 56..60 'self': &Self 2899 56..60 'self': &Self
2908 113..228 '{ ...ized }': () 2900 113..228 '{ ...ized }': ()
@@ -2972,19 +2964,18 @@ impl<A: Step> iter::Iterator for ops::Range<A> {
2972fn infer_closure_arg() { 2964fn infer_closure_arg() {
2973 check_infer( 2965 check_infer(
2974 r#" 2966 r#"
2975 //- /lib.rs 2967//- /lib.rs
2976 2968
2977 enum Option<T> { 2969enum Option<T> {
2978 None, 2970 None,
2979 Some(T) 2971 Some(T)
2980 } 2972}
2981 2973
2982 fn foo() { 2974fn foo() {
2983 let s = Option::None; 2975 let s = Option::None;
2984 let f = |x: Option<i32>| {}; 2976 let f = |x: Option<i32>| {};
2985 (&f)(s) 2977 (&f)(s)
2986 } 2978}"#,
2987 "#,
2988 expect![[r#" 2979 expect![[r#"
2989 52..126 '{ ...)(s) }': () 2980 52..126 '{ ...)(s) }': ()
2990 62..63 's': Option<i32> 2981 62..63 's': Option<i32>
@@ -3053,46 +3044,45 @@ fn infer_box_fn_arg() {
3053 // The type mismatch is a bug 3044 // The type mismatch is a bug
3054 check_infer_with_mismatches( 3045 check_infer_with_mismatches(
3055 r#" 3046 r#"
3056 //- /lib.rs deps:std 3047//- /lib.rs deps:std
3057 3048
3058 #[lang = "fn_once"] 3049#[lang = "fn_once"]
3059 pub trait FnOnce<Args> { 3050pub trait FnOnce<Args> {
3060 type Output; 3051 type Output;
3061 3052
3062 extern "rust-call" fn call_once(self, args: Args) -> Self::Output; 3053 extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
3063 } 3054}
3064 3055
3065 #[lang = "deref"] 3056#[lang = "deref"]
3066 pub trait Deref { 3057pub trait Deref {
3067 type Target: ?Sized; 3058 type Target: ?Sized;
3068 3059
3069 fn deref(&self) -> &Self::Target; 3060 fn deref(&self) -> &Self::Target;
3070 } 3061}
3071 3062
3072 #[lang = "owned_box"] 3063#[lang = "owned_box"]
3073 pub struct Box<T: ?Sized> { 3064pub struct Box<T: ?Sized> {
3074 inner: *mut T, 3065 inner: *mut T,
3075 } 3066}
3076 3067
3077 impl<T: ?Sized> Deref for Box<T> { 3068impl<T: ?Sized> Deref for Box<T> {
3078 type Target = T; 3069 type Target = T;
3079 3070
3080 fn deref(&self) -> &T { 3071 fn deref(&self) -> &T {
3081 &self.inner 3072 &self.inner
3082 } 3073 }
3083 } 3074}
3084 3075
3085 enum Option<T> { 3076enum Option<T> {
3086 None, 3077 None,
3087 Some(T) 3078 Some(T)
3088 } 3079}
3089 3080
3090 fn foo() { 3081fn foo() {
3091 let s = Option::None; 3082 let s = Option::None;
3092 let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {}); 3083 let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {});
3093 f(&s); 3084 f(&s);
3094 } 3085}"#,
3095 "#,
3096 expect![[r#" 3086 expect![[r#"
3097 100..104 'self': Self 3087 100..104 'self': Self
3098 106..110 'args': Args 3088 106..110 'args': Args
@@ -3258,8 +3248,7 @@ fn f() {
3258 ().method(); 3248 ().method();
3259 //^^^^^^^^^^^ u8 3249 //^^^^^^^^^^^ u8
3260 } 3250 }
3261} 3251}"#,
3262 "#,
3263 expect![[r#" 3252 expect![[r#"
3264 46..50 'self': &Self 3253 46..50 'self': &Self
3265 58..63 '{ 0 }': u8 3254 58..63 '{ 0 }': u8
@@ -3313,8 +3302,7 @@ fn f() {
3313 fn inner() -> S { 3302 fn inner() -> S {
3314 let s = inner(); 3303 let s = inner();
3315 } 3304 }
3316} 3305}"#,
3317 "#,
3318 expect![[r#" 3306 expect![[r#"
3319 17..73 '{ ... } }': () 3307 17..73 '{ ... } }': ()
3320 39..71 '{ ... }': () 3308 39..71 '{ ... }': ()
@@ -3349,8 +3337,7 @@ fn test() {
3349 let x = A; 3337 let x = A;
3350 let y = A; 3338 let y = A;
3351 let r = x.do_op(y); 3339 let r = x.do_op(y);
3352} 3340}"#,
3353 "#,
3354 expect![[r#" 3341 expect![[r#"
3355 63..67 'self': Self 3342 63..67 'self': Self
3356 69..72 'rhs': RHS 3343 69..72 'rhs': RHS
@@ -3370,3 +3357,120 @@ fn test() {
3370 "#]], 3357 "#]],
3371 ) 3358 )
3372} 3359}
3360
3361#[test]
3362fn qualified_path_as_qualified_trait() {
3363 check_infer(
3364 r#"
3365mod foo {
3366
3367 pub trait Foo {
3368 type Target;
3369 }
3370 pub trait Bar {
3371 type Output;
3372 fn boo() -> Self::Output {
3373 loop {}
3374 }
3375 }
3376}
3377
3378struct F;
3379impl foo::Foo for F {
3380 type Target = ();
3381}
3382impl foo::Bar for F {
3383 type Output = <F as foo::Foo>::Target;
3384}
3385
3386fn foo() {
3387 use foo::Bar;
3388 let x = <F as Bar>::boo();
3389}"#,
3390 expect![[r#"
3391 132..163 '{ ... }': Bar::Output<Self>
3392 146..153 'loop {}': !
3393 151..153 '{}': ()
3394 306..358 '{ ...o(); }': ()
3395 334..335 'x': ()
3396 338..353 '<F as Bar>::boo': fn boo<F>() -> <F as Bar>::Output
3397 338..355 '<F as ...:boo()': ()
3398 "#]],
3399 );
3400}
3401
3402#[test]
3403fn renamed_extern_crate_in_block() {
3404 check_types(
3405 r#"
3406//- /lib.rs crate:lib deps:serde
3407use serde::Deserialize;
3408
3409struct Foo {}
3410
3411const _ : () = {
3412 extern crate serde as _serde;
3413 impl _serde::Deserialize for Foo {
3414 fn deserialize() -> u8 { 0 }
3415 }
3416};
3417
3418fn foo() {
3419 Foo::deserialize();
3420 //^^^^^^^^^^^^^^^^^^ u8
3421}
3422
3423//- /serde.rs crate:serde
3424
3425pub trait Deserialize {
3426 fn deserialize() -> u8;
3427}"#,
3428 );
3429}
3430
3431#[test]
3432fn bin_op_adt_with_rhs_primitive() {
3433 check_infer_with_mismatches(
3434 r#"
3435#[lang = "add"]
3436pub trait Add<Rhs = Self> {
3437 type Output;
3438 fn add(self, rhs: Rhs) -> Self::Output;
3439}
3440
3441struct Wrapper(u32);
3442impl Add<u32> for Wrapper {
3443 type Output = Self;
3444 fn add(self, rhs: u32) -> Wrapper {
3445 Wrapper(rhs)
3446 }
3447}
3448fn main(){
3449 let wrapped = Wrapper(10);
3450 let num: u32 = 2;
3451 let res = wrapped + num;
3452
3453}"#,
3454 expect![[r#"
3455 72..76 'self': Self
3456 78..81 'rhs': Rhs
3457 192..196 'self': Wrapper
3458 198..201 'rhs': u32
3459 219..247 '{ ... }': Wrapper
3460 229..236 'Wrapper': Wrapper(u32) -> Wrapper
3461 229..241 'Wrapper(rhs)': Wrapper
3462 237..240 'rhs': u32
3463 259..345 '{ ...um; }': ()
3464 269..276 'wrapped': Wrapper
3465 279..286 'Wrapper': Wrapper(u32) -> Wrapper
3466 279..290 'Wrapper(10)': Wrapper
3467 287..289 '10': u32
3468 300..303 'num': u32
3469 311..312 '2': u32
3470 322..325 'res': Wrapper
3471 328..335 'wrapped': Wrapper
3472 328..341 'wrapped + num': Wrapper
3473 338..341 'num': u32
3474 "#]],
3475 )
3476}
diff --git a/crates/hir_ty/src/traits/chalk/tls.rs b/crates/hir_ty/src/tls.rs
index 8892a63a9..87c671a42 100644
--- a/crates/hir_ty/src/traits/chalk/tls.rs
+++ b/crates/hir_ty/src/tls.rs
@@ -4,8 +4,10 @@ use std::fmt;
4use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication}; 4use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication};
5use itertools::Itertools; 5use itertools::Itertools;
6 6
7use super::{from_chalk, Interner}; 7use crate::{
8use crate::{db::HirDatabase, from_assoc_type_id, CallableDefId}; 8 chalk_db, db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, mapping::from_chalk,
9 CallableDefId, Interner,
10};
9use hir_def::{AdtId, AssocContainerId, Lookup, TypeAliasId}; 11use hir_def::{AdtId, AssocContainerId, Lookup, TypeAliasId};
10 12
11pub(crate) use unsafe_tls::{set_current_program, with_current_program}; 13pub(crate) use unsafe_tls::{set_current_program, with_current_program};
@@ -15,7 +17,7 @@ pub(crate) struct DebugContext<'a>(&'a dyn HirDatabase);
15impl DebugContext<'_> { 17impl DebugContext<'_> {
16 pub(crate) fn debug_struct_id( 18 pub(crate) fn debug_struct_id(
17 &self, 19 &self,
18 id: super::AdtId, 20 id: chalk_db::AdtId,
19 f: &mut fmt::Formatter<'_>, 21 f: &mut fmt::Formatter<'_>,
20 ) -> Result<(), fmt::Error> { 22 ) -> Result<(), fmt::Error> {
21 let name = match id.0 { 23 let name = match id.0 {
@@ -28,17 +30,17 @@ impl DebugContext<'_> {
28 30
29 pub(crate) fn debug_trait_id( 31 pub(crate) fn debug_trait_id(
30 &self, 32 &self,
31 id: super::TraitId, 33 id: chalk_db::TraitId,
32 fmt: &mut fmt::Formatter<'_>, 34 fmt: &mut fmt::Formatter<'_>,
33 ) -> Result<(), fmt::Error> { 35 ) -> Result<(), fmt::Error> {
34 let trait_: hir_def::TraitId = from_chalk(self.0, id); 36 let trait_: hir_def::TraitId = from_chalk_trait_id(id);
35 let trait_data = self.0.trait_data(trait_); 37 let trait_data = self.0.trait_data(trait_);
36 write!(fmt, "{}", trait_data.name) 38 write!(fmt, "{}", trait_data.name)
37 } 39 }
38 40
39 pub(crate) fn debug_assoc_type_id( 41 pub(crate) fn debug_assoc_type_id(
40 &self, 42 &self,
41 id: super::AssocTypeId, 43 id: chalk_db::AssocTypeId,
42 fmt: &mut fmt::Formatter<'_>, 44 fmt: &mut fmt::Formatter<'_>,
43 ) -> Result<(), fmt::Error> { 45 ) -> Result<(), fmt::Error> {
44 let type_alias: TypeAliasId = from_assoc_type_id(id); 46 let type_alias: TypeAliasId = from_assoc_type_id(id);
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index ccee0e5ad..9936d0803 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -1,28 +1,26 @@
1//! Trait solving using Chalk. 1//! Trait solving using Chalk.
2
2use std::env::var; 3use std::env::var;
3 4
4use base_db::CrateId;
5use chalk_ir::cast::Cast; 5use chalk_ir::cast::Cast;
6use chalk_solve::{logging_db::LoggingRustIrDatabase, Solver}; 6use chalk_solve::{logging_db::LoggingRustIrDatabase, Solver};
7
8use base_db::CrateId;
7use hir_def::{lang_item::LangItemTarget, TraitId}; 9use hir_def::{lang_item::LangItemTarget, TraitId};
8use stdx::panic_context; 10use stdx::panic_context;
9 11
10use crate::{ 12use crate::{
11 db::HirDatabase, AliasTy, Canonical, DebruijnIndex, HirDisplay, Substitution, Ty, TyKind, 13 db::HirDatabase, AliasEq, AliasTy, Canonical, DomainGoal, Guidance, HirDisplay, InEnvironment,
12 TypeWalk, WhereClause, 14 Interner, Solution, TraitRefExt, Ty, TyKind, WhereClause,
13}; 15};
14 16
15use self::chalk::{from_chalk, Interner, ToChalk};
16
17pub(crate) mod chalk;
18
19/// This controls how much 'time' we give the Chalk solver before giving up. 17/// This controls how much 'time' we give the Chalk solver before giving up.
20const CHALK_SOLVER_FUEL: i32 = 100; 18const CHALK_SOLVER_FUEL: i32 = 100;
21 19
22#[derive(Debug, Copy, Clone)] 20#[derive(Debug, Copy, Clone)]
23struct ChalkContext<'a> { 21pub(crate) struct ChalkContext<'a> {
24 db: &'a dyn HirDatabase, 22 pub(crate) db: &'a dyn HirDatabase,
25 krate: CrateId, 23 pub(crate) krate: CrateId,
26} 24}
27 25
28fn create_chalk_solver() -> chalk_recursive::RecursiveSolver<Interner> { 26fn create_chalk_solver() -> chalk_recursive::RecursiveSolver<Interner> {
@@ -70,55 +68,6 @@ impl Default for TraitEnvironment {
70 } 68 }
71} 69}
72 70
73/// Something (usually a goal), along with an environment.
74#[derive(Clone, Debug, PartialEq, Eq, Hash)]
75pub struct InEnvironment<T> {
76 pub environment: chalk_ir::Environment<Interner>,
77 pub goal: T,
78}
79
80impl<T> InEnvironment<T> {
81 pub fn new(environment: chalk_ir::Environment<Interner>, value: T) -> InEnvironment<T> {
82 InEnvironment { environment, goal: value }
83 }
84}
85
86/// Something that needs to be proven (by Chalk) during type checking, e.g. that
87/// a certain type implements a certain trait. Proving the Obligation might
88/// result in additional information about inference variables.
89#[derive(Clone, Debug, PartialEq, Eq, Hash)]
90pub enum DomainGoal {
91 Holds(WhereClause),
92}
93
94#[derive(Clone, Debug, PartialEq, Eq, Hash)]
95pub struct AliasEq {
96 pub alias: AliasTy,
97 pub ty: Ty,
98}
99
100impl TypeWalk for AliasEq {
101 fn walk(&self, f: &mut impl FnMut(&Ty)) {
102 self.ty.walk(f);
103 match &self.alias {
104 AliasTy::Projection(projection_ty) => projection_ty.walk(f),
105 AliasTy::Opaque(opaque) => opaque.walk(f),
106 }
107 }
108
109 fn walk_mut_binders(
110 &mut self,
111 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
112 binders: DebruijnIndex,
113 ) {
114 self.ty.walk_mut_binders(f, binders);
115 match &mut self.alias {
116 AliasTy::Projection(projection_ty) => projection_ty.walk_mut_binders(f, binders),
117 AliasTy::Opaque(opaque) => opaque.walk_mut_binders(f, binders),
118 }
119 }
120}
121
122/// Solve a trait goal using Chalk. 71/// Solve a trait goal using Chalk.
123pub(crate) fn trait_solve_query( 72pub(crate) fn trait_solve_query(
124 db: &dyn HirDatabase, 73 db: &dyn HirDatabase,
@@ -130,6 +79,7 @@ pub(crate) fn trait_solve_query(
130 db.trait_data(it.hir_trait_id()).name.to_string() 79 db.trait_data(it.hir_trait_id()).name.to_string()
131 } 80 }
132 DomainGoal::Holds(WhereClause::AliasEq(_)) => "alias_eq".to_string(), 81 DomainGoal::Holds(WhereClause::AliasEq(_)) => "alias_eq".to_string(),
82 _ => "??".to_string(),
133 }); 83 });
134 log::info!("trait_solve_query({})", goal.value.goal.display(db)); 84 log::info!("trait_solve_query({})", goal.value.goal.display(db));
135 85
@@ -138,19 +88,18 @@ pub(crate) fn trait_solve_query(
138 .. 88 ..
139 })) = &goal.value.goal 89 })) = &goal.value.goal
140 { 90 {
141 if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) { 91 if let TyKind::BoundVar(_) = projection_ty.self_type_parameter(&Interner).kind(&Interner) {
142 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible 92 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible
143 return Some(Solution::Ambig(Guidance::Unknown)); 93 return Some(Solution::Ambig(Guidance::Unknown));
144 } 94 }
145 } 95 }
146 96
147 let canonical = goal.to_chalk(db).cast(&Interner); 97 let canonical = goal.cast(&Interner);
148 98
149 // We currently don't deal with universes (I think / hope they're not yet 99 // We currently don't deal with universes (I think / hope they're not yet
150 // relevant for our use cases?) 100 // relevant for our use cases?)
151 let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 }; 101 let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 };
152 let solution = solve(db, krate, &u_canonical); 102 solve(db, krate, &u_canonical)
153 solution.map(|solution| solution_from_chalk(db, solution))
154} 103}
155 104
156fn solve( 105fn solve(
@@ -197,7 +146,7 @@ fn solve(
197 // don't set the TLS for Chalk unless Chalk debugging is active, to make 146 // don't set the TLS for Chalk unless Chalk debugging is active, to make
198 // extra sure we only use it for debugging 147 // extra sure we only use it for debugging
199 let solution = 148 let solution =
200 if is_chalk_debug() { chalk::tls::set_current_program(db, solve) } else { solve() }; 149 if is_chalk_debug() { crate::tls::set_current_program(db, solve) } else { solve() };
201 150
202 solution 151 solution
203} 152}
@@ -218,69 +167,6 @@ fn is_chalk_print() -> bool {
218 std::env::var("CHALK_PRINT").is_ok() 167 std::env::var("CHALK_PRINT").is_ok()
219} 168}
220 169
221fn solution_from_chalk(
222 db: &dyn HirDatabase,
223 solution: chalk_solve::Solution<Interner>,
224) -> Solution {
225 let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution<Interner>>| {
226 let result = from_chalk(db, subst);
227 SolutionVariables(result)
228 };
229 match solution {
230 chalk_solve::Solution::Unique(constr_subst) => {
231 let subst = chalk_ir::Canonical {
232 value: constr_subst.value.subst,
233 binders: constr_subst.binders,
234 };
235 Solution::Unique(convert_subst(subst))
236 }
237 chalk_solve::Solution::Ambig(chalk_solve::Guidance::Definite(subst)) => {
238 Solution::Ambig(Guidance::Definite(convert_subst(subst)))
239 }
240 chalk_solve::Solution::Ambig(chalk_solve::Guidance::Suggested(subst)) => {
241 Solution::Ambig(Guidance::Suggested(convert_subst(subst)))
242 }
243 chalk_solve::Solution::Ambig(chalk_solve::Guidance::Unknown) => {
244 Solution::Ambig(Guidance::Unknown)
245 }
246 }
247}
248
249#[derive(Clone, Debug, PartialEq, Eq)]
250pub struct SolutionVariables(pub Canonical<Substitution>);
251
252#[derive(Clone, Debug, PartialEq, Eq)]
253/// A (possible) solution for a proposed goal.
254pub enum Solution {
255 /// The goal indeed holds, and there is a unique value for all existential
256 /// variables.
257 Unique(SolutionVariables),
258
259 /// The goal may be provable in multiple ways, but regardless we may have some guidance
260 /// for type inference. In this case, we don't return any lifetime
261 /// constraints, since we have not "committed" to any particular solution
262 /// yet.
263 Ambig(Guidance),
264}
265
266#[derive(Clone, Debug, PartialEq, Eq)]
267/// When a goal holds ambiguously (e.g., because there are multiple possible
268/// solutions), we issue a set of *guidance* back to type inference.
269pub enum Guidance {
270 /// The existential variables *must* have the given values if the goal is
271 /// ever to hold, but that alone isn't enough to guarantee the goal will
272 /// actually hold.
273 Definite(SolutionVariables),
274
275 /// There are multiple plausible values for the existentials, but the ones
276 /// here are suggested as the preferred choice heuristically. These should
277 /// be used for inference fallback only.
278 Suggested(SolutionVariables),
279
280 /// There's no useful information to feed back to type inference
281 Unknown,
282}
283
284#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 170#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
285pub enum FnTrait { 171pub enum FnTrait {
286 FnOnce, 172 FnOnce,
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
deleted file mode 100644
index aef6b8a15..000000000
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ /dev/null
@@ -1,560 +0,0 @@
1//! This module contains the implementations of the `ToChalk` trait, which
2//! handles conversion between our data types and their corresponding types in
3//! Chalk (in both directions); plus some helper functions for more specialized
4//! conversions.
5
6use chalk_ir::{cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData};
7use chalk_solve::rust_ir;
8
9use base_db::salsa::InternKey;
10use hir_def::{GenericDefId, TypeAliasId};
11
12use crate::{
13 db::HirDatabase,
14 primitive::UintTy,
15 traits::{Canonical, DomainGoal},
16 AliasTy, CallableDefId, FnPointer, InEnvironment, OpaqueTy, ProjectionTy,
17 QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TypeWalk, WhereClause,
18};
19
20use super::interner::*;
21use super::*;
22
23impl ToChalk for Ty {
24 type Chalk = chalk_ir::Ty<Interner>;
25 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
26 match self.into_inner() {
27 TyKind::Ref(m, ty) => ref_to_chalk(db, m, ty),
28 TyKind::Array(ty) => array_to_chalk(db, ty),
29 TyKind::Function(FnPointer { sig, substs, .. }) => {
30 let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner));
31 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
32 num_binders: 0,
33 sig,
34 substitution,
35 })
36 .intern(&Interner)
37 }
38 TyKind::AssociatedType(assoc_type_id, substs) => {
39 let substitution = substs.to_chalk(db);
40 chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner)
41 }
42
43 TyKind::OpaqueType(id, substs) => {
44 let substitution = substs.to_chalk(db);
45 chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner)
46 }
47
48 TyKind::ForeignType(id) => chalk_ir::TyKind::Foreign(id).intern(&Interner),
49
50 TyKind::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner),
51
52 TyKind::Tuple(cardinality, substs) => {
53 let substitution = substs.to_chalk(db);
54 chalk_ir::TyKind::Tuple(cardinality, substitution).intern(&Interner)
55 }
56 TyKind::Raw(mutability, ty) => {
57 let ty = ty.to_chalk(db);
58 chalk_ir::TyKind::Raw(mutability, ty).intern(&Interner)
59 }
60 TyKind::Slice(ty) => chalk_ir::TyKind::Slice(ty.to_chalk(db)).intern(&Interner),
61 TyKind::Str => chalk_ir::TyKind::Str.intern(&Interner),
62 TyKind::FnDef(id, substs) => {
63 let substitution = substs.to_chalk(db);
64 chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner)
65 }
66 TyKind::Never => chalk_ir::TyKind::Never.intern(&Interner),
67
68 TyKind::Closure(closure_id, substs) => {
69 let substitution = substs.to_chalk(db);
70 chalk_ir::TyKind::Closure(closure_id, substitution).intern(&Interner)
71 }
72
73 TyKind::Adt(adt_id, substs) => {
74 let substitution = substs.to_chalk(db);
75 chalk_ir::TyKind::Adt(adt_id, substitution).intern(&Interner)
76 }
77 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
78 let associated_ty_id = proj_ty.associated_ty_id;
79 let substitution = proj_ty.substitution.to_chalk(db);
80 chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
81 associated_ty_id,
82 substitution,
83 })
84 .cast(&Interner)
85 .intern(&Interner)
86 }
87 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
88 let opaque_ty_id = opaque_ty.opaque_ty_id;
89 let substitution = opaque_ty.substitution.to_chalk(db);
90 chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { opaque_ty_id, substitution })
91 .cast(&Interner)
92 .intern(&Interner)
93 }
94 TyKind::Placeholder(idx) => idx.to_ty::<Interner>(&Interner),
95 TyKind::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner),
96 TyKind::InferenceVar(..) => panic!("uncanonicalized infer ty"),
97 TyKind::Dyn(dyn_ty) => {
98 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
99 &Interner,
100 dyn_ty.bounds.value.interned().iter().cloned().map(|p| p.to_chalk(db)),
101 );
102 let bounded_ty = chalk_ir::DynTy {
103 bounds: make_binders(where_clauses, 1),
104 lifetime: LifetimeData::Static.intern(&Interner),
105 };
106 chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner)
107 }
108 TyKind::Unknown => chalk_ir::TyKind::Error.intern(&Interner),
109 }
110 }
111 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
112 match chalk.data(&Interner).kind.clone() {
113 chalk_ir::TyKind::Error => TyKind::Unknown,
114 chalk_ir::TyKind::Array(ty, _size) => TyKind::Array(from_chalk(db, ty)),
115 chalk_ir::TyKind::Placeholder(idx) => TyKind::Placeholder(idx),
116 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => {
117 let associated_ty = proj.associated_ty_id;
118 let parameters = from_chalk(db, proj.substitution);
119 TyKind::Alias(AliasTy::Projection(ProjectionTy {
120 associated_ty_id: associated_ty,
121 substitution: parameters,
122 }))
123 }
124 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => {
125 let opaque_ty_id = opaque_ty.opaque_ty_id;
126 let parameters = from_chalk(db, opaque_ty.substitution);
127 TyKind::Alias(AliasTy::Opaque(OpaqueTy { opaque_ty_id, substitution: parameters }))
128 }
129 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
130 num_binders,
131 sig,
132 substitution,
133 ..
134 }) => {
135 assert_eq!(num_binders, 0);
136 let substs: Substitution = from_chalk(
137 db,
138 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"),
139 );
140 TyKind::Function(FnPointer { num_args: (substs.len() - 1), sig, substs })
141 }
142 chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx),
143 chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Unknown,
144 chalk_ir::TyKind::Dyn(where_clauses) => {
145 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1);
146 let bounds = where_clauses
147 .bounds
148 .skip_binders()
149 .iter(&Interner)
150 .map(|c| from_chalk(db, c.clone()));
151 TyKind::Dyn(crate::DynTy {
152 bounds: crate::Binders::new(
153 1,
154 crate::QuantifiedWhereClauses::from_iter(&Interner, bounds),
155 ),
156 })
157 }
158
159 chalk_ir::TyKind::Adt(adt_id, subst) => TyKind::Adt(adt_id, from_chalk(db, subst)),
160 chalk_ir::TyKind::AssociatedType(type_id, subst) => {
161 TyKind::AssociatedType(type_id, from_chalk(db, subst))
162 }
163
164 chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => {
165 TyKind::OpaqueType(opaque_type_id, from_chalk(db, subst))
166 }
167
168 chalk_ir::TyKind::Scalar(scalar) => TyKind::Scalar(scalar),
169 chalk_ir::TyKind::Tuple(cardinality, subst) => {
170 TyKind::Tuple(cardinality, from_chalk(db, subst))
171 }
172 chalk_ir::TyKind::Raw(mutability, ty) => TyKind::Raw(mutability, from_chalk(db, ty)),
173 chalk_ir::TyKind::Slice(ty) => TyKind::Slice(from_chalk(db, ty)),
174 chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => {
175 TyKind::Ref(mutability, from_chalk(db, ty))
176 }
177 chalk_ir::TyKind::Str => TyKind::Str,
178 chalk_ir::TyKind::Never => TyKind::Never,
179
180 chalk_ir::TyKind::FnDef(fn_def_id, subst) => {
181 TyKind::FnDef(fn_def_id, from_chalk(db, subst))
182 }
183
184 chalk_ir::TyKind::Closure(id, subst) => TyKind::Closure(id, from_chalk(db, subst)),
185
186 chalk_ir::TyKind::Foreign(foreign_def_id) => TyKind::ForeignType(foreign_def_id),
187 chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME
188 chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME
189 }
190 .intern(&Interner)
191 }
192}
193
194/// We currently don't model lifetimes, but Chalk does. So, we have to insert a
195/// fake lifetime here, because Chalks built-in logic may expect it to be there.
196fn ref_to_chalk(
197 db: &dyn HirDatabase,
198 mutability: chalk_ir::Mutability,
199 ty: Ty,
200) -> chalk_ir::Ty<Interner> {
201 let arg = ty.to_chalk(db);
202 let lifetime = LifetimeData::Static.intern(&Interner);
203 chalk_ir::TyKind::Ref(mutability, lifetime, arg).intern(&Interner)
204}
205
206/// We currently don't model constants, but Chalk does. So, we have to insert a
207/// fake constant here, because Chalks built-in logic may expect it to be there.
208fn array_to_chalk(db: &dyn HirDatabase, ty: Ty) -> chalk_ir::Ty<Interner> {
209 let arg = ty.to_chalk(db);
210 let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner);
211 let const_ = chalk_ir::ConstData {
212 ty: usize_ty,
213 value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }),
214 }
215 .intern(&Interner);
216 chalk_ir::TyKind::Array(arg, const_).intern(&Interner)
217}
218
219impl ToChalk for Substitution {
220 type Chalk = chalk_ir::Substitution<Interner>;
221
222 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
223 chalk_ir::Substitution::from_iter(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db)))
224 }
225
226 fn from_chalk(
227 db: &dyn HirDatabase,
228 parameters: chalk_ir::Substitution<Interner>,
229 ) -> Substitution {
230 let tys = parameters
231 .iter(&Interner)
232 .map(|p| match p.ty(&Interner) {
233 Some(ty) => from_chalk(db, ty.clone()),
234 None => unimplemented!(),
235 })
236 .collect();
237 Substitution(tys)
238 }
239}
240
241impl ToChalk for TraitRef {
242 type Chalk = chalk_ir::TraitRef<Interner>;
243
244 fn to_chalk(self: TraitRef, db: &dyn HirDatabase) -> chalk_ir::TraitRef<Interner> {
245 let trait_id = self.trait_id;
246 let substitution = self.substitution.to_chalk(db);
247 chalk_ir::TraitRef { trait_id, substitution }
248 }
249
250 fn from_chalk(db: &dyn HirDatabase, trait_ref: chalk_ir::TraitRef<Interner>) -> Self {
251 let trait_id = trait_ref.trait_id;
252 let substs = from_chalk(db, trait_ref.substitution);
253 TraitRef { trait_id, substitution: substs }
254 }
255}
256
257impl ToChalk for hir_def::TraitId {
258 type Chalk = TraitId;
259
260 fn to_chalk(self, _db: &dyn HirDatabase) -> TraitId {
261 chalk_ir::TraitId(self.as_intern_id())
262 }
263
264 fn from_chalk(_db: &dyn HirDatabase, trait_id: TraitId) -> hir_def::TraitId {
265 InternKey::from_intern_id(trait_id.0)
266 }
267}
268
269impl ToChalk for hir_def::ImplId {
270 type Chalk = ImplId;
271
272 fn to_chalk(self, _db: &dyn HirDatabase) -> ImplId {
273 chalk_ir::ImplId(self.as_intern_id())
274 }
275
276 fn from_chalk(_db: &dyn HirDatabase, impl_id: ImplId) -> hir_def::ImplId {
277 InternKey::from_intern_id(impl_id.0)
278 }
279}
280
281impl ToChalk for CallableDefId {
282 type Chalk = FnDefId;
283
284 fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId {
285 db.intern_callable_def(self).into()
286 }
287
288 fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDefId {
289 db.lookup_intern_callable_def(fn_def_id.into())
290 }
291}
292
293pub(crate) struct TypeAliasAsValue(pub(crate) TypeAliasId);
294
295impl ToChalk for TypeAliasAsValue {
296 type Chalk = AssociatedTyValueId;
297
298 fn to_chalk(self, _db: &dyn HirDatabase) -> AssociatedTyValueId {
299 rust_ir::AssociatedTyValueId(self.0.as_intern_id())
300 }
301
302 fn from_chalk(
303 _db: &dyn HirDatabase,
304 assoc_ty_value_id: AssociatedTyValueId,
305 ) -> TypeAliasAsValue {
306 TypeAliasAsValue(TypeAliasId::from_intern_id(assoc_ty_value_id.0))
307 }
308}
309
310impl ToChalk for WhereClause {
311 type Chalk = chalk_ir::WhereClause<Interner>;
312
313 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::WhereClause<Interner> {
314 match self {
315 WhereClause::Implemented(trait_ref) => {
316 chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db))
317 }
318 WhereClause::AliasEq(alias_eq) => chalk_ir::WhereClause::AliasEq(alias_eq.to_chalk(db)),
319 }
320 }
321
322 fn from_chalk(
323 db: &dyn HirDatabase,
324 where_clause: chalk_ir::WhereClause<Interner>,
325 ) -> WhereClause {
326 match where_clause {
327 chalk_ir::WhereClause::Implemented(tr) => WhereClause::Implemented(from_chalk(db, tr)),
328 chalk_ir::WhereClause::AliasEq(alias_eq) => {
329 WhereClause::AliasEq(from_chalk(db, alias_eq))
330 }
331
332 chalk_ir::WhereClause::LifetimeOutlives(_) => {
333 // we shouldn't get these from Chalk
334 panic!("encountered LifetimeOutlives from Chalk")
335 }
336
337 chalk_ir::WhereClause::TypeOutlives(_) => {
338 // we shouldn't get these from Chalk
339 panic!("encountered TypeOutlives from Chalk")
340 }
341 }
342 }
343}
344
345impl ToChalk for ProjectionTy {
346 type Chalk = chalk_ir::ProjectionTy<Interner>;
347
348 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy<Interner> {
349 chalk_ir::ProjectionTy {
350 associated_ty_id: self.associated_ty_id,
351 substitution: self.substitution.to_chalk(db),
352 }
353 }
354
355 fn from_chalk(
356 db: &dyn HirDatabase,
357 projection_ty: chalk_ir::ProjectionTy<Interner>,
358 ) -> ProjectionTy {
359 ProjectionTy {
360 associated_ty_id: projection_ty.associated_ty_id,
361 substitution: from_chalk(db, projection_ty.substitution),
362 }
363 }
364}
365impl ToChalk for OpaqueTy {
366 type Chalk = chalk_ir::OpaqueTy<Interner>;
367
368 fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk {
369 chalk_ir::OpaqueTy {
370 opaque_ty_id: self.opaque_ty_id,
371 substitution: self.substitution.to_chalk(db),
372 }
373 }
374
375 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
376 OpaqueTy {
377 opaque_ty_id: chalk.opaque_ty_id,
378 substitution: from_chalk(db, chalk.substitution),
379 }
380 }
381}
382
383impl ToChalk for AliasTy {
384 type Chalk = chalk_ir::AliasTy<Interner>;
385
386 fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk {
387 match self {
388 AliasTy::Projection(projection_ty) => {
389 chalk_ir::AliasTy::Projection(projection_ty.to_chalk(db))
390 }
391 AliasTy::Opaque(opaque_ty) => chalk_ir::AliasTy::Opaque(opaque_ty.to_chalk(db)),
392 }
393 }
394
395 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
396 match chalk {
397 chalk_ir::AliasTy::Projection(projection_ty) => {
398 AliasTy::Projection(from_chalk(db, projection_ty))
399 }
400 chalk_ir::AliasTy::Opaque(opaque_ty) => AliasTy::Opaque(from_chalk(db, opaque_ty)),
401 }
402 }
403}
404
405impl ToChalk for AliasEq {
406 type Chalk = chalk_ir::AliasEq<Interner>;
407
408 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> {
409 chalk_ir::AliasEq { alias: self.alias.to_chalk(db), ty: self.ty.to_chalk(db) }
410 }
411
412 fn from_chalk(db: &dyn HirDatabase, alias_eq: chalk_ir::AliasEq<Interner>) -> Self {
413 AliasEq { alias: from_chalk(db, alias_eq.alias), ty: from_chalk(db, alias_eq.ty) }
414 }
415}
416
417impl ToChalk for DomainGoal {
418 type Chalk = chalk_ir::DomainGoal<Interner>;
419
420 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> {
421 match self {
422 DomainGoal::Holds(WhereClause::Implemented(tr)) => tr.to_chalk(db).cast(&Interner),
423 DomainGoal::Holds(WhereClause::AliasEq(alias_eq)) => {
424 alias_eq.to_chalk(db).cast(&Interner)
425 }
426 }
427 }
428
429 fn from_chalk(_db: &dyn HirDatabase, _goal: chalk_ir::DomainGoal<Interner>) -> Self {
430 unimplemented!()
431 }
432}
433
434impl<T> ToChalk for Canonical<T>
435where
436 T: ToChalk,
437 T::Chalk: HasInterner<Interner = Interner>,
438{
439 type Chalk = chalk_ir::Canonical<T::Chalk>;
440
441 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> {
442 let value = self.value.to_chalk(db);
443 chalk_ir::Canonical { value, binders: self.binders }
444 }
445
446 fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> {
447 Canonical { binders: canonical.binders, value: from_chalk(db, canonical.value) }
448 }
449}
450
451impl<T: ToChalk> ToChalk for InEnvironment<T>
452where
453 T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>,
454{
455 type Chalk = chalk_ir::InEnvironment<T::Chalk>;
456
457 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> {
458 chalk_ir::InEnvironment { environment: self.environment, goal: self.goal.to_chalk(db) }
459 }
460
461 fn from_chalk(
462 _db: &dyn HirDatabase,
463 _in_env: chalk_ir::InEnvironment<T::Chalk>,
464 ) -> InEnvironment<T> {
465 unimplemented!()
466 }
467}
468
469impl<T: ToChalk> ToChalk for crate::Binders<T>
470where
471 T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>,
472{
473 type Chalk = chalk_ir::Binders<T::Chalk>;
474
475 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Binders<T::Chalk> {
476 chalk_ir::Binders::new(
477 chalk_ir::VariableKinds::from_iter(
478 &Interner,
479 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
480 .take(self.num_binders),
481 ),
482 self.value.to_chalk(db),
483 )
484 }
485
486 fn from_chalk(db: &dyn HirDatabase, binders: chalk_ir::Binders<T::Chalk>) -> crate::Binders<T> {
487 let (v, b) = binders.into_value_and_skipped_binders();
488 crate::Binders::new(b.len(&Interner), from_chalk(db, v))
489 }
490}
491
492pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T>
493where
494 T: HasInterner<Interner = Interner>,
495{
496 chalk_ir::Binders::new(
497 chalk_ir::VariableKinds::from_iter(
498 &Interner,
499 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
500 .take(num_vars),
501 ),
502 value,
503 )
504}
505
506pub(super) fn convert_where_clauses(
507 db: &dyn HirDatabase,
508 def: GenericDefId,
509 substs: &Substitution,
510) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> {
511 let generic_predicates = db.generic_predicates(def);
512 let mut result = Vec::with_capacity(generic_predicates.len());
513 for pred in generic_predicates.iter() {
514 result.push(pred.clone().subst(substs).to_chalk(db));
515 }
516 result
517}
518
519pub(super) fn generic_predicate_to_inline_bound(
520 db: &dyn HirDatabase,
521 pred: &QuantifiedWhereClause,
522 self_ty: &Ty,
523) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> {
524 // An InlineBound is like a GenericPredicate, except the self type is left out.
525 // We don't have a special type for this, but Chalk does.
526 let self_ty_shifted_in = self_ty.clone().shift_bound_vars(DebruijnIndex::ONE);
527 match &pred.value {
528 WhereClause::Implemented(trait_ref) => {
529 if trait_ref.self_type_parameter() != &self_ty_shifted_in {
530 // we can only convert predicates back to type bounds if they
531 // have the expected self type
532 return None;
533 }
534 let args_no_self = trait_ref.substitution[1..]
535 .iter()
536 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
537 .collect();
538 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
539 Some(make_binders(rust_ir::InlineBound::TraitBound(trait_bound), pred.num_binders))
540 }
541 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
542 if projection_ty.self_type_parameter() != &self_ty_shifted_in {
543 return None;
544 }
545 let trait_ = projection_ty.trait_(db);
546 let args_no_self = projection_ty.substitution[1..]
547 .iter()
548 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
549 .collect();
550 let alias_eq_bound = rust_ir::AliasEqBound {
551 value: ty.clone().to_chalk(db),
552 trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self },
553 associated_ty_id: projection_ty.associated_ty_id,
554 parameters: Vec::new(), // FIXME we don't support generic associated types yet
555 };
556 Some(make_binders(rust_ir::InlineBound::AliasEqBound(alias_eq_bound), pred.num_binders))
557 }
558 _ => None,
559 }
560}
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index 42d7af146..2f04ee57a 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -1,22 +1,21 @@
1//! Helper functions for working with def, which don't need to be a separate 1//! Helper functions for working with def, which don't need to be a separate
2//! query, but can't be computed directly from `*Data` (ie, which need a `db`). 2//! query, but can't be computed directly from `*Data` (ie, which need a `db`).
3use std::sync::Arc;
4 3
5use chalk_ir::DebruijnIndex; 4use chalk_ir::{fold::Shift, BoundVar, DebruijnIndex};
6use hir_def::{ 5use hir_def::{
7 adt::VariantData,
8 db::DefDatabase, 6 db::DefDatabase,
9 generics::{ 7 generics::{
10 GenericParams, TypeParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget, 8 GenericParams, TypeParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget,
11 }, 9 },
10 intern::Interned,
12 path::Path, 11 path::Path,
13 resolver::{HasResolver, TypeNs}, 12 resolver::{HasResolver, TypeNs},
14 type_ref::TypeRef, 13 type_ref::TypeRef,
15 AssocContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId, VariantId, 14 AssocContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId,
16}; 15};
17use hir_expand::name::{name, Name}; 16use hir_expand::name::{name, Name};
18 17
19use crate::{db::HirDatabase, TraitRef, TypeWalk, WhereClause}; 18use crate::{db::HirDatabase, Interner, Substitution, TraitRef, TraitRefExt, TyKind, WhereClause};
20 19
21fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> { 20fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
22 let resolver = trait_.resolver(db); 21 let resolver = trait_.resolver(db);
@@ -32,11 +31,10 @@ fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
32 .filter_map(|pred| match pred { 31 .filter_map(|pred| match pred {
33 WherePredicate::ForLifetime { target, bound, .. } 32 WherePredicate::ForLifetime { target, bound, .. }
34 | WherePredicate::TypeBound { target, bound } => match target { 33 | WherePredicate::TypeBound { target, bound } => match target {
35 WherePredicateTypeTarget::TypeRef(TypeRef::Path(p)) 34 WherePredicateTypeTarget::TypeRef(type_ref) => match &**type_ref {
36 if p == &Path::from(name![Self]) => 35 TypeRef::Path(p) if p == &Path::from(name![Self]) => bound.as_path(),
37 { 36 _ => None,
38 bound.as_path() 37 },
39 }
40 WherePredicateTypeTarget::TypeParam(local_id) if Some(*local_id) == trait_self => { 38 WherePredicateTypeTarget::TypeParam(local_id) if Some(*local_id) == trait_self => {
41 bound.as_path() 39 bound.as_path()
42 } 40 }
@@ -66,19 +64,21 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
66 .filter_map(|pred| { 64 .filter_map(|pred| {
67 pred.as_ref().filter_map(|pred| match pred.skip_binders() { 65 pred.as_ref().filter_map(|pred| match pred.skip_binders() {
68 // FIXME: how to correctly handle higher-ranked bounds here? 66 // FIXME: how to correctly handle higher-ranked bounds here?
69 WhereClause::Implemented(tr) => { 67 WhereClause::Implemented(tr) => Some(
70 Some(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE)) 68 tr.clone()
71 } 69 .shifted_out_to(&Interner, DebruijnIndex::ONE)
70 .expect("FIXME unexpected higher-ranked trait bound"),
71 ),
72 _ => None, 72 _ => None,
73 }) 73 })
74 }) 74 })
75 .map(|pred| pred.subst(&trait_ref.substitution)) 75 .map(|pred| pred.substitute(&Interner, &trait_ref.substitution))
76 .collect() 76 .collect()
77} 77}
78 78
79/// Returns an iterator over the whole super trait hierarchy (including the 79/// Returns an iterator over the whole super trait hierarchy (including the
80/// trait itself). 80/// trait itself).
81pub(super) fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> { 81pub fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
82 // we need to take care a bit here to avoid infinite loops in case of cycles 82 // we need to take care a bit here to avoid infinite loops in case of cycles
83 // (i.e. if we have `trait A: B; trait B: A;`) 83 // (i.e. if we have `trait A: B; trait B: A;`)
84 let mut result = vec![trait_]; 84 let mut result = vec![trait_];
@@ -103,6 +103,8 @@ pub(super) fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<Tra
103/// we have `Self: Trait<u32, i32>` and `Trait<T, U>: OtherTrait<U>` we'll get 103/// we have `Self: Trait<u32, i32>` and `Trait<T, U>: OtherTrait<U>` we'll get
104/// `Self: OtherTrait<i32>`. 104/// `Self: OtherTrait<i32>`.
105pub(super) fn all_super_trait_refs(db: &dyn HirDatabase, trait_ref: TraitRef) -> Vec<TraitRef> { 105pub(super) fn all_super_trait_refs(db: &dyn HirDatabase, trait_ref: TraitRef) -> Vec<TraitRef> {
106 // FIXME: replace by Chalk's `super_traits`, maybe make this a query
107
106 // we need to take care a bit here to avoid infinite loops in case of cycles 108 // we need to take care a bit here to avoid infinite loops in case of cycles
107 // (i.e. if we have `trait A: B; trait B: A;`) 109 // (i.e. if we have `trait A: B; trait B: A;`)
108 let mut result = vec![trait_ref]; 110 let mut result = vec![trait_ref];
@@ -132,25 +134,6 @@ pub(super) fn associated_type_by_name_including_super_traits(
132 }) 134 })
133} 135}
134 136
135pub(super) fn variant_data(db: &dyn DefDatabase, var: VariantId) -> Arc<VariantData> {
136 match var {
137 VariantId::StructId(it) => db.struct_data(it).variant_data.clone(),
138 VariantId::UnionId(it) => db.union_data(it).variant_data.clone(),
139 VariantId::EnumVariantId(it) => {
140 db.enum_data(it.parent).variants[it.local_id].variant_data.clone()
141 }
142 }
143}
144
145/// Helper for mutating `Arc<[T]>` (i.e. `Arc::make_mut` for Arc slices).
146/// The underlying values are cloned if there are other strong references.
147pub(crate) fn make_mut_slice<T: Clone>(a: &mut Arc<[T]>) -> &mut [T] {
148 if Arc::get_mut(a).is_none() {
149 *a = a.iter().cloned().collect();
150 }
151 Arc::get_mut(a).unwrap()
152}
153
154pub(crate) fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics { 137pub(crate) fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics {
155 let parent_generics = parent_generic_def(db, def).map(|def| Box::new(generics(db, def))); 138 let parent_generics = parent_generic_def(db, def).map(|def| Box::new(generics(db, def)));
156 Generics { def, params: db.generic_params(def), parent_generics } 139 Generics { def, params: db.generic_params(def), parent_generics }
@@ -159,7 +142,7 @@ pub(crate) fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics {
159#[derive(Debug)] 142#[derive(Debug)]
160pub(crate) struct Generics { 143pub(crate) struct Generics {
161 def: GenericDefId, 144 def: GenericDefId,
162 pub(crate) params: Arc<GenericParams>, 145 pub(crate) params: Interned<GenericParams>,
163 parent_generics: Option<Box<Generics>>, 146 parent_generics: Option<Box<Generics>>,
164} 147}
165 148
@@ -249,6 +232,26 @@ impl Generics {
249 self.parent_generics.as_ref().and_then(|g| g.find_param(param)) 232 self.parent_generics.as_ref().and_then(|g| g.find_param(param))
250 } 233 }
251 } 234 }
235
236 /// Returns a Substitution that replaces each parameter by a bound variable.
237 pub(crate) fn bound_vars_subst(&self, debruijn: DebruijnIndex) -> Substitution {
238 Substitution::from_iter(
239 &Interner,
240 self.iter()
241 .enumerate()
242 .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)),
243 )
244 }
245
246 /// Returns a Substitution that replaces each parameter by itself (i.e. `Ty::Param`).
247 pub(crate) fn type_params_subst(&self, db: &dyn HirDatabase) -> Substitution {
248 Substitution::from_iter(
249 &Interner,
250 self.iter().map(|(id, _)| {
251 TyKind::Placeholder(crate::to_placeholder_idx(db, id)).intern(&Interner)
252 }),
253 )
254 }
252} 255}
253 256
254fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Option<GenericDefId> { 257fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Option<GenericDefId> {
diff --git a/crates/hir_ty/src/walk.rs b/crates/hir_ty/src/walk.rs
new file mode 100644
index 000000000..6ef1d5336
--- /dev/null
+++ b/crates/hir_ty/src/walk.rs
@@ -0,0 +1,150 @@
1//! The `TypeWalk` trait (probably to be replaced by Chalk's `Fold` and
2//! `Visit`).
3
4use chalk_ir::interner::HasInterner;
5
6use crate::{
7 AliasEq, AliasTy, Binders, CallableSig, FnSubst, GenericArg, GenericArgData, Interner,
8 OpaqueTy, ProjectionTy, Substitution, TraitRef, Ty, TyKind, WhereClause,
9};
10
11/// This allows walking structures that contain types to do something with those
12/// types, similar to Chalk's `Fold` trait.
13pub trait TypeWalk {
14 fn walk(&self, f: &mut impl FnMut(&Ty));
15}
16
17impl TypeWalk for Ty {
18 fn walk(&self, f: &mut impl FnMut(&Ty)) {
19 match self.kind(&Interner) {
20 TyKind::Alias(AliasTy::Projection(p_ty)) => {
21 for t in p_ty.substitution.iter(&Interner) {
22 t.walk(f);
23 }
24 }
25 TyKind::Alias(AliasTy::Opaque(o_ty)) => {
26 for t in o_ty.substitution.iter(&Interner) {
27 t.walk(f);
28 }
29 }
30 TyKind::Dyn(dyn_ty) => {
31 for p in dyn_ty.bounds.skip_binders().interned().iter() {
32 p.walk(f);
33 }
34 }
35 TyKind::Slice(ty)
36 | TyKind::Array(ty, _)
37 | TyKind::Ref(_, _, ty)
38 | TyKind::Raw(_, ty) => {
39 ty.walk(f);
40 }
41 TyKind::Function(fn_pointer) => {
42 fn_pointer.substitution.0.walk(f);
43 }
44 TyKind::Adt(_, substs)
45 | TyKind::FnDef(_, substs)
46 | TyKind::Tuple(_, substs)
47 | TyKind::OpaqueType(_, substs)
48 | TyKind::AssociatedType(_, substs)
49 | TyKind::Closure(.., substs) => {
50 substs.walk(f);
51 }
52 _ => {}
53 }
54 f(self);
55 }
56}
57
58impl<T: TypeWalk> TypeWalk for Vec<T> {
59 fn walk(&self, f: &mut impl FnMut(&Ty)) {
60 for t in self {
61 t.walk(f);
62 }
63 }
64}
65
66impl TypeWalk for OpaqueTy {
67 fn walk(&self, f: &mut impl FnMut(&Ty)) {
68 self.substitution.walk(f);
69 }
70}
71
72impl TypeWalk for ProjectionTy {
73 fn walk(&self, f: &mut impl FnMut(&Ty)) {
74 self.substitution.walk(f);
75 }
76}
77
78impl TypeWalk for AliasTy {
79 fn walk(&self, f: &mut impl FnMut(&Ty)) {
80 match self {
81 AliasTy::Projection(it) => it.walk(f),
82 AliasTy::Opaque(it) => it.walk(f),
83 }
84 }
85}
86
87impl TypeWalk for GenericArg {
88 fn walk(&self, f: &mut impl FnMut(&Ty)) {
89 match &self.interned() {
90 GenericArgData::Ty(ty) => {
91 ty.walk(f);
92 }
93 _ => {}
94 }
95 }
96}
97
98impl TypeWalk for Substitution {
99 fn walk(&self, f: &mut impl FnMut(&Ty)) {
100 for t in self.iter(&Interner) {
101 t.walk(f);
102 }
103 }
104}
105
106impl<T: TypeWalk + HasInterner<Interner = Interner>> TypeWalk for Binders<T> {
107 fn walk(&self, f: &mut impl FnMut(&Ty)) {
108 self.skip_binders().walk(f);
109 }
110}
111
112impl TypeWalk for TraitRef {
113 fn walk(&self, f: &mut impl FnMut(&Ty)) {
114 self.substitution.walk(f);
115 }
116}
117
118impl TypeWalk for WhereClause {
119 fn walk(&self, f: &mut impl FnMut(&Ty)) {
120 match self {
121 WhereClause::Implemented(trait_ref) => trait_ref.walk(f),
122 WhereClause::AliasEq(alias_eq) => alias_eq.walk(f),
123 _ => {}
124 }
125 }
126}
127
128impl TypeWalk for CallableSig {
129 fn walk(&self, f: &mut impl FnMut(&Ty)) {
130 for t in self.params_and_return.iter() {
131 t.walk(f);
132 }
133 }
134}
135
136impl TypeWalk for AliasEq {
137 fn walk(&self, f: &mut impl FnMut(&Ty)) {
138 self.ty.walk(f);
139 match &self.alias {
140 AliasTy::Projection(projection_ty) => projection_ty.walk(f),
141 AliasTy::Opaque(opaque) => opaque.walk(f),
142 }
143 }
144}
145
146impl TypeWalk for FnSubst<Interner> {
147 fn walk(&self, f: &mut impl FnMut(&Ty)) {
148 self.0.walk(f)
149 }
150}