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.rs68
-rw-r--r--crates/hir_ty/src/builder.rs30
-rw-r--r--crates/hir_ty/src/chalk_cast.rs73
-rw-r--r--crates/hir_ty/src/chalk_db.rs (renamed from crates/hir_ty/src/traits/chalk.rs)262
-rw-r--r--crates/hir_ty/src/chalk_ext.rs294
-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.rs169
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs14
-rw-r--r--crates/hir_ty/src/diagnostics/match_check.rs2
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs4
-rw-r--r--crates/hir_ty/src/display.rs275
-rw-r--r--crates/hir_ty/src/infer.rs165
-rw-r--r--crates/hir_ty/src/infer/coerce.rs29
-rw-r--r--crates/hir_ty/src/infer/expr.rs91
-rw-r--r--crates/hir_ty/src/infer/pat.rs59
-rw-r--r--crates/hir_ty/src/infer/path.rs18
-rw-r--r--crates/hir_ty/src/infer/unify.rs218
-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.rs1290
-rw-r--r--crates/hir_ty/src/lower.rs300
-rw-r--r--crates/hir_ty/src/mapping.rs154
-rw-r--r--crates/hir_ty/src/method_resolution.rs329
-rw-r--r--crates/hir_ty/src/op.rs66
-rw-r--r--crates/hir_ty/src/primitive.rs5
-rw-r--r--crates/hir_ty/src/tests/macros.rs201
-rw-r--r--crates/hir_ty/src/tests/method_resolution.rs57
-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.rs1467
-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.rs575
-rw-r--r--crates/hir_ty/src/utils.rs53
-rw-r--r--crates/hir_ty/src/walk.rs150
36 files changed, 3403 insertions, 3545 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index 70c56cc45..2c07494a9 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -6,16 +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 traits::{InEnvironment, Solution}, 16 DebruijnIndex, InEnvironment, Interner, ProjectionTyExt, Solution, Substitution, Ty, TyBuilder,
17 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner, Ty, 17 TyKind,
18 TyBuilder, TyKind,
19}; 18};
20 19
21const AUTODEREF_RECURSION_LIMIT: usize = 10; 20const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -37,18 +36,28 @@ pub(crate) fn deref(
37 krate: CrateId, 36 krate: CrateId,
38 ty: InEnvironment<&Canonical<Ty>>, 37 ty: InEnvironment<&Canonical<Ty>>,
39) -> Option<Canonical<Ty>> { 38) -> Option<Canonical<Ty>> {
40 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) {
41 Some(Canonical { value: derefed, binders: ty.goal.binders.clone() }) 41 Some(Canonical { value: derefed, binders: ty.goal.binders.clone() })
42 } else { 42 } else {
43 deref_by_trait(db, krate, ty) 43 deref_by_trait(db, krate, ty)
44 } 44 }
45} 45}
46 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
47fn deref_by_trait( 55fn deref_by_trait(
48 db: &dyn HirDatabase, 56 db: &dyn HirDatabase,
49 krate: CrateId, 57 krate: CrateId,
50 ty: InEnvironment<&Canonical<Ty>>, 58 ty: InEnvironment<&Canonical<Ty>>,
51) -> Option<Canonical<Ty>> { 59) -> Option<Canonical<Ty>> {
60 let _p = profile::span("deref_by_trait");
52 let deref_trait = match db.lang_item(krate, "deref".into())? { 61 let deref_trait = match db.lang_item(krate, "deref".into())? {
53 LangItemTarget::TraitId(it) => it, 62 LangItemTarget::TraitId(it) => it,
54 _ => return None, 63 _ => return None,
@@ -97,7 +106,7 @@ fn deref_by_trait(
97 binders: CanonicalVarKinds::from_iter( 106 binders: CanonicalVarKinds::from_iter(
98 &Interner, 107 &Interner,
99 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(
100 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), 109 VariableKind::Ty(chalk_ir::TyVariableKind::General),
101 chalk_ir::UniverseIndex::ROOT, 110 chalk_ir::UniverseIndex::ROOT,
102 ))), 111 ))),
103 ), 112 ),
@@ -122,23 +131,25 @@ fn deref_by_trait(
122 // assumptions will be broken. We would need to properly introduce 131 // assumptions will be broken. We would need to properly introduce
123 // new variables in that case 132 // new variables in that case
124 133
125 for i in 1..vars.0.binders.len(&Interner) { 134 for i in 1..vars.binders.len(&Interner) {
126 if vars.0.value.at(&Interner, i - 1).assert_ty_ref(&Interner).kind(&Interner) 135 if vars.value.subst.at(&Interner, i - 1).assert_ty_ref(&Interner).kind(&Interner)
127 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 136 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
128 { 137 {
129 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution); 138 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
130 return None; 139 return None;
131 } 140 }
132 } 141 }
133 Some(Canonical { 142 // FIXME: we remove lifetime variables here since they can confuse
143 // the method resolution code later
144 Some(fixup_lifetime_variables(Canonical {
134 value: vars 145 value: vars
135 .0
136 .value 146 .value
137 .at(&Interner, vars.0.value.len(&Interner) - 1) 147 .subst
148 .at(&Interner, vars.value.subst.len(&Interner) - 1)
138 .assert_ty_ref(&Interner) 149 .assert_ty_ref(&Interner)
139 .clone(), 150 .clone(),
140 binders: vars.0.binders.clone(), 151 binders: vars.binders.clone(),
141 }) 152 }))
142 } 153 }
143 Solution::Ambig(_) => { 154 Solution::Ambig(_) => {
144 info!("Ambiguous solution for derefing {:?}: {:?}", ty.goal, solution); 155 info!("Ambiguous solution for derefing {:?}: {:?}", ty.goal, solution);
@@ -146,3 +157,32 @@ fn deref_by_trait(
146 } 157 }
147 } 158 }
148} 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
index 4a9a8058f..e25ef866d 100644
--- a/crates/hir_ty/src/builder.rs
+++ b/crates/hir_ty/src/builder.rs
@@ -4,6 +4,7 @@ use std::iter;
4 4
5use chalk_ir::{ 5use chalk_ir::{
6 cast::{Cast, CastTo, Caster}, 6 cast::{Cast, CastTo, Caster},
7 fold::Fold,
7 interner::HasInterner, 8 interner::HasInterner,
8 AdtId, BoundVar, DebruijnIndex, Safety, Scalar, 9 AdtId, BoundVar, DebruijnIndex, Safety, Scalar,
9}; 10};
@@ -12,8 +13,8 @@ use smallvec::SmallVec;
12 13
13use crate::{ 14use crate::{
14 db::HirDatabase, primitive, to_assoc_type_id, to_chalk_trait_id, utils::generics, Binders, 15 db::HirDatabase, primitive, to_assoc_type_id, to_chalk_trait_id, utils::generics, Binders,
15 CallableSig, FnPointer, FnSig, GenericArg, Interner, ProjectionTy, Substitution, TraitRef, Ty, 16 CallableSig, FnPointer, FnSig, FnSubst, GenericArg, Interner, ProjectionTy, Substitution,
16 TyDefId, TyKind, TypeWalk, ValueTyDefId, 17 TraitRef, Ty, TyDefId, TyExt, TyKind, ValueTyDefId,
17}; 18};
18 19
19/// This is a builder for `Ty` or anything that needs a `Substitution`. 20/// This is a builder for `Ty` or anything that needs a `Substitution`.
@@ -32,8 +33,7 @@ impl<D> TyBuilder<D> {
32 33
33 fn build_internal(self) -> (D, Substitution) { 34 fn build_internal(self) -> (D, Substitution) {
34 assert_eq!(self.vec.len(), self.param_count); 35 assert_eq!(self.vec.len(), self.param_count);
35 // FIXME: would be good to have a way to construct a chalk_ir::Substitution from the interned form 36 let subst = Substitution::from_iter(&Interner, self.vec);
36 let subst = Substitution(self.vec);
37 (self.data, subst) 37 (self.data, subst)
38 } 38 }
39 39
@@ -54,7 +54,7 @@ impl<D> TyBuilder<D> {
54 } 54 }
55 55
56 pub fn fill_with_unknown(self) -> Self { 56 pub fn fill_with_unknown(self) -> Self {
57 self.fill(iter::repeat(TyKind::Unknown.intern(&Interner))) 57 self.fill(iter::repeat(TyKind::Error.intern(&Interner)))
58 } 58 }
59 59
60 pub fn fill(mut self, filler: impl Iterator<Item = impl CastTo<GenericArg>>) -> Self { 60 pub fn fill(mut self, filler: impl Iterator<Item = impl CastTo<GenericArg>>) -> Self {
@@ -78,9 +78,12 @@ impl TyBuilder<()> {
78 78
79 pub fn fn_ptr(sig: CallableSig) -> Ty { 79 pub fn fn_ptr(sig: CallableSig) -> Ty {
80 TyKind::Function(FnPointer { 80 TyKind::Function(FnPointer {
81 num_args: sig.params().len(), 81 num_binders: 0,
82 sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs }, 82 sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs },
83 substs: Substitution::from_iter(&Interner, sig.params_and_return.iter().cloned()), 83 substitution: FnSubst(Substitution::from_iter(
84 &Interner,
85 sig.params_and_return.iter().cloned(),
86 )),
84 }) 87 })
85 .intern(&Interner) 88 .intern(&Interner)
86 } 89 }
@@ -138,8 +141,9 @@ impl TyBuilder<hir_def::AdtId> {
138 self.vec.push(fallback().cast(&Interner)); 141 self.vec.push(fallback().cast(&Interner));
139 } else { 142 } else {
140 // each default can depend on the previous parameters 143 // each default can depend on the previous parameters
141 let subst_so_far = Substitution(self.vec.clone()); 144 let subst_so_far = Substitution::from_iter(&Interner, self.vec.clone());
142 self.vec.push(default_ty.clone().subst(&subst_so_far).cast(&Interner)); 145 self.vec
146 .push(default_ty.clone().substitute(&Interner, &subst_so_far).cast(&Interner));
143 } 147 }
144 } 148 }
145 self 149 self
@@ -192,15 +196,15 @@ impl TyBuilder<TypeAliasId> {
192 } 196 }
193} 197}
194 198
195impl<T: TypeWalk + HasInterner<Interner = Interner>> TyBuilder<Binders<T>> { 199impl<T: HasInterner<Interner = Interner> + Fold<Interner>> TyBuilder<Binders<T>> {
196 fn subst_binders(b: Binders<T>) -> Self { 200 fn subst_binders(b: Binders<T>) -> Self {
197 let param_count = b.num_binders; 201 let param_count = b.binders.len(&Interner);
198 TyBuilder::new(b, param_count) 202 TyBuilder::new(b, param_count)
199 } 203 }
200 204
201 pub fn build(self) -> T { 205 pub fn build(self) -> <T as Fold<Interner>>::Result {
202 let (b, subst) = self.build_internal(); 206 let (b, subst) = self.build_internal();
203 b.subst(&subst) 207 b.substitute(&Interner, &subst)
204 } 208 }
205} 209}
206 210
diff --git a/crates/hir_ty/src/chalk_cast.rs b/crates/hir_ty/src/chalk_cast.rs
deleted file mode 100644
index df6492113..000000000
--- a/crates/hir_ty/src/chalk_cast.rs
+++ /dev/null
@@ -1,73 +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, GenericArg, GenericArgData, Interner, TraitRef, Ty, 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);
20has_interner!(GenericArg);
21has_interner!(Ty);
22
23impl CastTo<WhereClause> for TraitRef {
24 fn cast_to(self, _interner: &Interner) -> WhereClause {
25 WhereClause::Implemented(self)
26 }
27}
28
29impl CastTo<WhereClause> for AliasEq {
30 fn cast_to(self, _interner: &Interner) -> WhereClause {
31 WhereClause::AliasEq(self)
32 }
33}
34
35impl CastTo<DomainGoal> for WhereClause {
36 fn cast_to(self, _interner: &Interner) -> DomainGoal {
37 DomainGoal::Holds(self)
38 }
39}
40
41impl CastTo<GenericArg> for Ty {
42 fn cast_to(self, interner: &Interner) -> GenericArg {
43 GenericArg::new(interner, GenericArgData::Ty(self))
44 }
45}
46
47macro_rules! transitive_impl {
48 ($a:ty, $b:ty, $c:ty) => {
49 impl CastTo<$c> for $a {
50 fn cast_to(self, interner: &Interner) -> $c {
51 self.cast::<$b>(interner).cast(interner)
52 }
53 }
54 };
55}
56
57// In Chalk, these can be done as blanket impls, but that doesn't work here
58// because of coherence
59
60transitive_impl!(TraitRef, WhereClause, DomainGoal);
61transitive_impl!(AliasEq, WhereClause, DomainGoal);
62
63macro_rules! reflexive_impl {
64 ($a:ty) => {
65 impl CastTo<$a> for $a {
66 fn cast_to(self, _interner: &Interner) -> $a {
67 self
68 }
69 }
70 };
71}
72
73reflexive_impl!(GenericArg);
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/chalk_db.rs
index 541e6082f..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}; 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, TyBuilder, 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> {
@@ -84,9 +79,9 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
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,
@@ -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 = TyBuilder::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(&Interner).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 {
@@ -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,7 +413,7 @@ 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());
@@ -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(&Interner)), 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,
@@ -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,7 +531,8 @@ 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());
@@ -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(&Interner)), 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 = generic_params.bound_vars_subst(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
index b7463366b..8c4542956 100644
--- a/crates/hir_ty/src/chalk_ext.rs
+++ b/crates/hir_ty/src/chalk_ext.rs
@@ -1,13 +1,305 @@
1//! Various extensions traits for Chalk types. 1//! Various extensions traits for Chalk types.
2 2
3use crate::{Interner, Ty, TyKind}; 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};
4 14
5pub trait TyExt { 15pub trait TyExt {
6 fn is_unit(&self) -> bool; 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;
7} 40}
8 41
9impl TyExt for Ty { 42impl TyExt for Ty {
10 fn is_unit(&self) -> bool { 43 fn is_unit(&self) -> bool {
11 matches!(self.kind(&Interner), TyKind::Tuple(0, _)) 44 matches!(self.kind(&Interner), TyKind::Tuple(0, _))
12 } 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 }
13} 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 1c9f9ede7..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,10 +85,39 @@ 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) {
@@ -109,7 +140,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
109 } 140 }
110 141
111 // Check whether non-snake case identifiers are allowed for this function. 142 // Check whether non-snake case identifiers are allowed for this function.
112 if self.allowed(func.into(), allow::NON_SNAKE_CASE) { 143 if self.allowed(func.into(), allow::NON_SNAKE_CASE, false) {
113 return; 144 return;
114 } 145 }
115 146
@@ -328,8 +359,9 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
328 fn validate_struct(&mut self, struct_id: StructId) { 359 fn validate_struct(&mut self, struct_id: StructId) {
329 let data = self.db.struct_data(struct_id); 360 let data = self.db.struct_data(struct_id);
330 361
331 let non_camel_case_allowed = self.allowed(struct_id.into(), allow::NON_CAMEL_CASE_TYPES); 362 let non_camel_case_allowed =
332 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);
333 365
334 // Check the structure name. 366 // Check the structure name.
335 let struct_name = data.name.to_string(); 367 let struct_name = data.name.to_string();
@@ -461,7 +493,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
461 let data = self.db.enum_data(enum_id); 493 let data = self.db.enum_data(enum_id);
462 494
463 // Check whether non-camel case names are allowed for this enum. 495 // Check whether non-camel case names are allowed for this enum.
464 if self.allowed(enum_id.into(), allow::NON_CAMEL_CASE_TYPES) { 496 if self.allowed(enum_id.into(), allow::NON_CAMEL_CASE_TYPES, false) {
465 return; 497 return;
466 } 498 }
467 499
@@ -584,7 +616,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
584 fn validate_const(&mut self, const_id: ConstId) { 616 fn validate_const(&mut self, const_id: ConstId) {
585 let data = self.db.const_data(const_id); 617 let data = self.db.const_data(const_id);
586 618
587 if self.allowed(const_id.into(), allow::NON_UPPER_CASE_GLOBAL) { 619 if self.allowed(const_id.into(), allow::NON_UPPER_CASE_GLOBAL, false) {
588 return; 620 return;
589 } 621 }
590 622
@@ -632,7 +664,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
632 return; 664 return;
633 } 665 }
634 666
635 if self.allowed(static_id.into(), allow::NON_UPPER_CASE_GLOBAL) { 667 if self.allowed(static_id.into(), allow::NON_UPPER_CASE_GLOBAL, false) {
636 return; 668 return;
637 } 669 }
638 670
@@ -867,23 +899,116 @@ fn main() {
867 fn allow_attributes() { 899 fn allow_attributes() {
868 check_diagnostics( 900 check_diagnostics(
869 r#" 901 r#"
870 #[allow(non_snake_case)] 902#[allow(non_snake_case)]
871 fn NonSnakeCaseName(SOME_VAR: u8) -> u8{ 903fn NonSnakeCaseName(SOME_VAR: u8) -> u8{
872 let OtherVar = SOME_VAR + 1; 904 // cov_flags generated output from elsewhere in this file
873 OtherVar 905 extern "C" {
906 #[no_mangle]
907 static lower_case: u8;
874 } 908 }
875 909
876 #[allow(non_snake_case, non_camel_case_types)] 910 let OtherVar = SOME_VAR + 1;
877 pub struct some_type { 911 OtherVar
878 SOME_FIELD: u8, 912}
879 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 );
880 } 942 }
881 943
882 #[allow(non_upper_case_globals)] 944 #[test]
883 pub const some_const: u8 = 10; 945 fn allow_attributes_crate_attr() {
946 check_diagnostics(
947 r#"
948#![allow(non_snake_case)]
884 949
885 #[allow(non_upper_case_globals)] 950mod F {
886 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}
887 "#, 1012 "#,
888 ); 1013 );
889 } 1014 }
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index 8169b759f..79602c3dd 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -14,7 +14,6 @@ use crate::{
14 MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr, 14 MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr,
15 MissingPatFields, RemoveThisSemicolon, 15 MissingPatFields, RemoveThisSemicolon,
16 }, 16 },
17 utils::variant_data,
18 AdtId, InferenceResult, Interner, TyExt, TyKind, 17 AdtId, InferenceResult, Interner, TyExt, TyKind,
19}; 18};
20 19
@@ -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
@@ -452,7 +452,7 @@ pub fn record_literal_missing_fields(
452 return None; 452 return None;
453 } 453 }
454 454
455 let variant_data = variant_data(db.upcast(), variant_def); 455 let variant_data = variant_def.variant_data(db.upcast());
456 456
457 let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect(); 457 let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
458 let missed_fields: Vec<LocalFieldId> = variant_data 458 let missed_fields: Vec<LocalFieldId> = variant_data
@@ -482,7 +482,7 @@ pub fn record_pattern_missing_fields(
482 return None; 482 return None;
483 } 483 }
484 484
485 let variant_data = variant_data(db.upcast(), variant_def); 485 let variant_data = variant_def.variant_data(db.upcast());
486 486
487 let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect(); 487 let specified_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
488 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 34291578a..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
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs
index b5efe9df5..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,
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 385bd9405..4fb7d9cf2 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -1,9 +1,15 @@
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::{
12 body,
7 db::DefDatabase, 13 db::DefDatabase,
8 find_path, 14 find_path,
9 generics::TypeParamProvenance, 15 generics::TypeParamProvenance,
@@ -13,13 +19,15 @@ use hir_def::{
13 visibility::Visibility, 19 visibility::Visibility,
14 AssocContainerId, Lookup, ModuleId, TraitId, 20 AssocContainerId, Lookup, ModuleId, TraitId,
15}; 21};
16use hir_expand::name::Name; 22use hir_expand::{hygiene::Hygiene, name::Name};
17 23
18use crate::{ 24use crate::{
19 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, 25 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, 26 from_placeholder_idx, lt_from_placeholder_idx, mapping::from_chalk, primitive, subst_prefix,
21 CallableDefId, CallableSig, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, OpaqueTy, 27 to_assoc_type_id, utils::generics, AdtId, AliasEq, AliasTy, CallableDefId, CallableSig, Const,
22 ProjectionTy, QuantifiedWhereClause, Scalar, TraitRef, Ty, TyExt, TyKind, WhereClause, 28 ConstValue, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, LifetimeData,
29 LifetimeOutlives, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause,
30 Scalar, TraitRef, TraitRefExt, Ty, TyExt, TyKind, WhereClause,
23}; 31};
24 32
25pub struct HirFormatter<'a> { 33pub struct HirFormatter<'a> {
@@ -46,6 +54,10 @@ pub trait HirDisplay {
46 where 54 where
47 Self: Sized, 55 Self: Sized,
48 { 56 {
57 assert!(
58 !matches!(display_target, DisplayTarget::SourceCode { .. }),
59 "HirDisplayWrapper cannot fail with DisplaySourceCodeError, use HirDisplay::hir_fmt directly instead"
60 );
49 HirDisplayWrapper { db, t: self, max_size, omit_verbose_types, display_target } 61 HirDisplayWrapper { db, t: self, max_size, omit_verbose_types, display_target }
50 } 62 }
51 63
@@ -230,7 +242,7 @@ where
230 Err(HirDisplayError::FmtError) => Err(fmt::Error), 242 Err(HirDisplayError::FmtError) => Err(fmt::Error),
231 Err(HirDisplayError::DisplaySourceCodeError(_)) => { 243 Err(HirDisplayError::DisplaySourceCodeError(_)) => {
232 // This should never happen 244 // This should never happen
233 panic!("HirDisplay failed when calling Display::fmt!") 245 panic!("HirDisplay::hir_fmt failed with DisplaySourceCodeError when calling Display::fmt!")
234 } 246 }
235 } 247 }
236 } 248 }
@@ -251,16 +263,12 @@ impl HirDisplay for ProjectionTy {
251 } 263 }
252 264
253 let trait_ = f.db.trait_data(self.trait_(f.db)); 265 let trait_ = f.db.trait_data(self.trait_(f.db));
254 let first_parameter = self.self_type_parameter().into_displayable( 266 write!(f, "<")?;
255 f.db, 267 self.self_type_parameter(&Interner).hir_fmt(f)?;
256 f.max_size, 268 write!(f, " as {}", trait_.name)?;
257 f.omit_verbose_types,
258 f.display_target,
259 );
260 write!(f, "<{} as {}", first_parameter, trait_.name)?;
261 if self.substitution.len(&Interner) > 1 { 269 if self.substitution.len(&Interner) > 1 {
262 write!(f, "<")?; 270 write!(f, "<")?;
263 f.write_joined(&self.substitution.interned(&Interner)[1..], ", ")?; 271 f.write_joined(&self.substitution.as_slice(&Interner)[1..], ", ")?;
264 write!(f, ">")?; 272 write!(f, ">")?;
265 } 273 }
266 write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?; 274 write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?;
@@ -282,10 +290,35 @@ impl HirDisplay for GenericArg {
282 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 290 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
283 match self.interned() { 291 match self.interned() {
284 crate::GenericArgData::Ty(ty) => ty.hir_fmt(f), 292 crate::GenericArgData::Ty(ty) => ty.hir_fmt(f),
293 crate::GenericArgData::Lifetime(lt) => lt.hir_fmt(f),
294 crate::GenericArgData::Const(c) => c.hir_fmt(f),
295 }
296 }
297}
298
299impl HirDisplay for Const {
300 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
301 let data = self.interned();
302 match data.value {
303 ConstValue::BoundVar(idx) => idx.hir_fmt(f),
304 ConstValue::InferenceVar(..) => write!(f, "_"),
305 ConstValue::Placeholder(idx) => {
306 let id = const_from_placeholder_idx(f.db, idx);
307 let generics = generics(f.db.upcast(), id.parent);
308 let param_data = &generics.params.consts[id.local_id];
309 write!(f, "{}", param_data.name)
310 }
311 ConstValue::Concrete(_) => write!(f, "_"),
285 } 312 }
286 } 313 }
287} 314}
288 315
316impl HirDisplay for BoundVar {
317 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
318 write!(f, "?{}.{}", self.debruijn.depth(), self.index)
319 }
320}
321
289impl HirDisplay for Ty { 322impl HirDisplay for Ty {
290 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 323 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
291 if f.should_truncate() { 324 if f.should_truncate() {
@@ -305,15 +338,14 @@ impl HirDisplay for Ty {
305 t.hir_fmt(f)?; 338 t.hir_fmt(f)?;
306 write!(f, "]")?; 339 write!(f, "]")?;
307 } 340 }
308 TyKind::Array(t) => { 341 TyKind::Array(t, c) => {
309 write!(f, "[")?; 342 write!(f, "[")?;
310 t.hir_fmt(f)?; 343 t.hir_fmt(f)?;
311 write!(f, "; _]")?; 344 write!(f, "; ")?;
345 c.hir_fmt(f)?;
346 write!(f, "]")?;
312 } 347 }
313 TyKind::Raw(m, t) | TyKind::Ref(m, t) => { 348 TyKind::Raw(m, t) | TyKind::Ref(m, _, t) => {
314 let ty_display =
315 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
316
317 if matches!(self.kind(&Interner), TyKind::Raw(..)) { 349 if matches!(self.kind(&Interner), TyKind::Raw(..)) {
318 write!( 350 write!(
319 f, 351 f,
@@ -352,8 +384,8 @@ impl HirDisplay for Ty {
352 let data = (*datas) 384 let data = (*datas)
353 .as_ref() 385 .as_ref()
354 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 386 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
355 let bounds = data.subst(parameters); 387 let bounds = data.substitute(&Interner, parameters);
356 bounds.value 388 bounds.into_value_and_skipped_binders().0
357 } else { 389 } else {
358 Vec::new() 390 Vec::new()
359 } 391 }
@@ -368,16 +400,16 @@ impl HirDisplay for Ty {
368 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) 400 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_)
369 && predicates.len() <= 2 401 && predicates.len() <= 2
370 { 402 {
371 return write!(f, "{}", ty_display); 403 return t.hir_fmt(f);
372 } 404 }
373 } 405 }
374 406
375 if predicates.len() > 1 { 407 if predicates.len() > 1 {
376 write!(f, "(")?; 408 write!(f, "(")?;
377 write!(f, "{}", ty_display)?; 409 t.hir_fmt(f)?;
378 write!(f, ")")?; 410 write!(f, ")")?;
379 } else { 411 } else {
380 write!(f, "{}", ty_display)?; 412 t.hir_fmt(f)?;
381 } 413 }
382 } 414 }
383 TyKind::Tuple(_, substs) => { 415 TyKind::Tuple(_, substs) => {
@@ -387,7 +419,7 @@ impl HirDisplay for Ty {
387 write!(f, ",)")?; 419 write!(f, ",)")?;
388 } else { 420 } else {
389 write!(f, "(")?; 421 write!(f, "(")?;
390 f.write_joined(&*substs.0, ", ")?; 422 f.write_joined(&*substs.as_slice(&Interner), ", ")?;
391 write!(f, ")")?; 423 write!(f, ")")?;
392 } 424 }
393 } 425 }
@@ -397,7 +429,7 @@ impl HirDisplay for Ty {
397 } 429 }
398 TyKind::FnDef(def, parameters) => { 430 TyKind::FnDef(def, parameters) => {
399 let def = from_chalk(f.db, *def); 431 let def = from_chalk(f.db, *def);
400 let sig = f.db.callable_item_signature(def).subst(parameters); 432 let sig = f.db.callable_item_signature(def).substitute(&Interner, parameters);
401 match def { 433 match def {
402 CallableDefId::FunctionId(ff) => { 434 CallableDefId::FunctionId(ff) => {
403 write!(f, "fn {}", f.db.function_data(ff).name)? 435 write!(f, "fn {}", f.db.function_data(ff).name)?
@@ -415,7 +447,7 @@ impl HirDisplay for Ty {
415 // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? 447 // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
416 if total_len > 0 { 448 if total_len > 0 {
417 write!(f, "<")?; 449 write!(f, "<")?;
418 f.write_joined(&parameters.0[..total_len], ", ")?; 450 f.write_joined(&parameters.as_slice(&Interner)[..total_len], ", ")?;
419 write!(f, ">")?; 451 write!(f, ">")?;
420 } 452 }
421 } 453 }
@@ -424,14 +456,8 @@ impl HirDisplay for Ty {
424 write!(f, ")")?; 456 write!(f, ")")?;
425 let ret = sig.ret(); 457 let ret = sig.ret();
426 if !ret.is_unit() { 458 if !ret.is_unit() {
427 let ret_display = ret.into_displayable( 459 write!(f, " -> ")?;
428 f.db, 460 ret.hir_fmt(f)?;
429 f.max_size,
430 f.omit_verbose_types,
431 f.display_target,
432 );
433
434 write!(f, " -> {}", ret_display)?;
435 } 461 }
436 } 462 }
437 TyKind::Adt(AdtId(def_id), parameters) => { 463 TyKind::Adt(AdtId(def_id), parameters) => {
@@ -468,7 +494,7 @@ impl HirDisplay for Ty {
468 .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) 494 .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
469 .filter(|defaults| !defaults.is_empty()) 495 .filter(|defaults| !defaults.is_empty())
470 { 496 {
471 None => parameters.0.as_ref(), 497 None => parameters.as_slice(&Interner),
472 Some(default_parameters) => { 498 Some(default_parameters) => {
473 let mut default_from = 0; 499 let mut default_from = 0;
474 for (i, parameter) in parameters.iter(&Interner).enumerate() { 500 for (i, parameter) in parameters.iter(&Interner).enumerate() {
@@ -476,13 +502,15 @@ impl HirDisplay for Ty {
476 parameter.assert_ty_ref(&Interner).kind(&Interner), 502 parameter.assert_ty_ref(&Interner).kind(&Interner),
477 default_parameters.get(i), 503 default_parameters.get(i),
478 ) { 504 ) {
479 (&TyKind::Unknown, _) | (_, None) => { 505 (&TyKind::Error, _) | (_, None) => {
480 default_from = i + 1; 506 default_from = i + 1;
481 } 507 }
482 (_, Some(default_parameter)) => { 508 (_, Some(default_parameter)) => {
483 let actual_default = default_parameter 509 let actual_default =
484 .clone() 510 default_parameter.clone().substitute(
485 .subst(&parameters.prefix(i)); 511 &Interner,
512 &subst_prefix(parameters, i),
513 );
486 if parameter.assert_ty_ref(&Interner) != &actual_default 514 if parameter.assert_ty_ref(&Interner) != &actual_default
487 { 515 {
488 default_from = i + 1; 516 default_from = i + 1;
@@ -490,11 +518,11 @@ impl HirDisplay for Ty {
490 } 518 }
491 } 519 }
492 } 520 }
493 &parameters.0[0..default_from] 521 &parameters.as_slice(&Interner)[0..default_from]
494 } 522 }
495 } 523 }
496 } else { 524 } else {
497 parameters.0.as_ref() 525 parameters.as_slice(&Interner)
498 }; 526 };
499 if !parameters_to_write.is_empty() { 527 if !parameters_to_write.is_empty() {
500 write!(f, "<")?; 528 write!(f, "<")?;
@@ -517,7 +545,7 @@ impl HirDisplay for Ty {
517 write!(f, "{}::{}", trait_.name, type_alias_data.name)?; 545 write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
518 if parameters.len(&Interner) > 0 { 546 if parameters.len(&Interner) > 0 {
519 write!(f, "<")?; 547 write!(f, "<")?;
520 f.write_joined(&*parameters.0, ", ")?; 548 f.write_joined(&*parameters.as_slice(&Interner), ", ")?;
521 write!(f, ">")?; 549 write!(f, ">")?;
522 } 550 }
523 } else { 551 } else {
@@ -529,7 +557,7 @@ impl HirDisplay for Ty {
529 projection_ty.hir_fmt(f)?; 557 projection_ty.hir_fmt(f)?;
530 } 558 }
531 } 559 }
532 TyKind::ForeignType(type_alias) => { 560 TyKind::Foreign(type_alias) => {
533 let type_alias = f.db.type_alias_data(from_foreign_def_id(*type_alias)); 561 let type_alias = f.db.type_alias_data(from_foreign_def_id(*type_alias));
534 write!(f, "{}", type_alias.name)?; 562 write!(f, "{}", type_alias.name)?;
535 } 563 }
@@ -542,8 +570,8 @@ impl HirDisplay for Ty {
542 let data = (*datas) 570 let data = (*datas)
543 .as_ref() 571 .as_ref()
544 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 572 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
545 let bounds = data.subst(&parameters); 573 let bounds = data.substitute(&Interner, &parameters);
546 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 574 write_bounds_like_dyn_trait_with_prefix("impl", bounds.skip_binders(), f)?;
547 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution 575 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
548 } 576 }
549 ImplTraitId::AsyncBlockTypeImplTrait(..) => { 577 ImplTraitId::AsyncBlockTypeImplTrait(..) => {
@@ -571,13 +599,8 @@ impl HirDisplay for Ty {
571 write!(f, "|")?; 599 write!(f, "|")?;
572 }; 600 };
573 601
574 let ret_display = sig.ret().into_displayable( 602 write!(f, " -> ")?;
575 f.db, 603 sig.ret().hir_fmt(f)?;
576 f.max_size,
577 f.omit_verbose_types,
578 f.display_target,
579 );
580 write!(f, " -> {}", ret_display)?;
581 } else { 604 } else {
582 write!(f, "{{closure}}")?; 605 write!(f, "{{closure}}")?;
583 } 606 }
@@ -592,25 +615,26 @@ impl HirDisplay for Ty {
592 } 615 }
593 TypeParamProvenance::ArgumentImplTrait => { 616 TypeParamProvenance::ArgumentImplTrait => {
594 let substs = generics.type_params_subst(f.db); 617 let substs = generics.type_params_subst(f.db);
595 let bounds = f 618 let bounds =
596 .db 619 f.db.generic_predicates(id.parent)
597 .generic_predicates(id.parent) 620 .into_iter()
598 .into_iter() 621 .map(|pred| pred.clone().substitute(&Interner, &substs))
599 .map(|pred| pred.clone().subst(&substs)) 622 .filter(|wc| match &wc.skip_binders() {
600 .filter(|wc| match &wc.skip_binders() { 623 WhereClause::Implemented(tr) => {
601 WhereClause::Implemented(tr) => tr.self_type_parameter() == self, 624 &tr.self_type_parameter(&Interner) == self
602 WhereClause::AliasEq(AliasEq { 625 }
603 alias: AliasTy::Projection(proj), 626 WhereClause::AliasEq(AliasEq {
604 ty: _, 627 alias: AliasTy::Projection(proj),
605 }) => proj.self_type_parameter() == self, 628 ty: _,
606 _ => false, 629 }) => &proj.self_type_parameter(&Interner) == self,
607 }) 630 _ => false,
608 .collect::<Vec<_>>(); 631 })
632 .collect::<Vec<_>>();
609 write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?; 633 write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?;
610 } 634 }
611 } 635 }
612 } 636 }
613 TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 637 TyKind::BoundVar(idx) => idx.hir_fmt(f)?,
614 TyKind::Dyn(dyn_ty) => { 638 TyKind::Dyn(dyn_ty) => {
615 write_bounds_like_dyn_trait_with_prefix( 639 write_bounds_like_dyn_trait_with_prefix(
616 "dyn", 640 "dyn",
@@ -628,15 +652,15 @@ impl HirDisplay for Ty {
628 let data = (*datas) 652 let data = (*datas)
629 .as_ref() 653 .as_ref()
630 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 654 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
631 let bounds = data.subst(&opaque_ty.substitution); 655 let bounds = data.substitute(&Interner, &opaque_ty.substitution);
632 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 656 write_bounds_like_dyn_trait_with_prefix("impl", bounds.skip_binders(), f)?;
633 } 657 }
634 ImplTraitId::AsyncBlockTypeImplTrait(..) => { 658 ImplTraitId::AsyncBlockTypeImplTrait(..) => {
635 write!(f, "{{async block}}")?; 659 write!(f, "{{async block}}")?;
636 } 660 }
637 }; 661 };
638 } 662 }
639 TyKind::Unknown => { 663 TyKind::Error => {
640 if f.display_target.is_source_code() { 664 if f.display_target.is_source_code() {
641 return Err(HirDisplayError::DisplaySourceCodeError( 665 return Err(HirDisplayError::DisplaySourceCodeError(
642 DisplaySourceCodeError::UnknownType, 666 DisplaySourceCodeError::UnknownType,
@@ -645,6 +669,8 @@ impl HirDisplay for Ty {
645 write!(f, "{{unknown}}")?; 669 write!(f, "{{unknown}}")?;
646 } 670 }
647 TyKind::InferenceVar(..) => write!(f, "_")?, 671 TyKind::InferenceVar(..) => write!(f, "_")?,
672 TyKind::Generator(..) => write!(f, "{{generator}}")?,
673 TyKind::GeneratorWitness(..) => write!(f, "{{generator witness}}")?,
648 } 674 }
649 Ok(()) 675 Ok(())
650 } 676 }
@@ -664,9 +690,8 @@ impl HirDisplay for CallableSig {
664 write!(f, ")")?; 690 write!(f, ")")?;
665 let ret = self.ret(); 691 let ret = self.ret();
666 if !ret.is_unit() { 692 if !ret.is_unit() {
667 let ret_display = 693 write!(f, " -> ")?;
668 ret.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); 694 ret.hir_fmt(f)?;
669 write!(f, " -> {}", ret_display)?;
670 } 695 }
671 Ok(()) 696 Ok(())
672 } 697 }
@@ -723,17 +748,17 @@ fn write_bounds_like_dyn_trait(
723 if !first { 748 if !first {
724 write!(f, " + ")?; 749 write!(f, " + ")?;
725 } 750 }
726 // We assume that the self type is $0 (i.e. the 751 // We assume that the self type is ^0.0 (i.e. the
727 // existential) here, which is the only thing that's 752 // existential) here, which is the only thing that's
728 // possible in actual Rust, and hence don't print it 753 // possible in actual Rust, and hence don't print it
729 write!(f, "{}", f.db.trait_data(trait_).name)?; 754 write!(f, "{}", f.db.trait_data(trait_).name)?;
730 if let [_, params @ ..] = &*trait_ref.substitution.0 { 755 if let [_, params @ ..] = &*trait_ref.substitution.as_slice(&Interner) {
731 if is_fn_trait { 756 if is_fn_trait {
732 if let Some(args) = 757 if let Some(args) =
733 params.first().and_then(|it| it.assert_ty_ref(&Interner).as_tuple()) 758 params.first().and_then(|it| it.assert_ty_ref(&Interner).as_tuple())
734 { 759 {
735 write!(f, "(")?; 760 write!(f, "(")?;
736 f.write_joined(&*args.0, ", ")?; 761 f.write_joined(args.as_slice(&Interner), ", ")?;
737 write!(f, ")")?; 762 write!(f, ")")?;
738 } 763 }
739 } else if !params.is_empty() { 764 } else if !params.is_empty() {
@@ -765,6 +790,10 @@ fn write_bounds_like_dyn_trait(
765 } 790 }
766 ty.hir_fmt(f)?; 791 ty.hir_fmt(f)?;
767 } 792 }
793
794 // FIXME implement these
795 WhereClause::LifetimeOutlives(_) => {}
796 WhereClause::TypeOutlives(_) => {}
768 } 797 }
769 first = false; 798 first = false;
770 } 799 }
@@ -774,31 +803,29 @@ fn write_bounds_like_dyn_trait(
774 Ok(()) 803 Ok(())
775} 804}
776 805
777impl TraitRef { 806fn fmt_trait_ref(tr: &TraitRef, f: &mut HirFormatter, use_as: bool) -> Result<(), HirDisplayError> {
778 fn hir_fmt_ext(&self, f: &mut HirFormatter, use_as: bool) -> Result<(), HirDisplayError> { 807 if f.should_truncate() {
779 if f.should_truncate() { 808 return write!(f, "{}", TYPE_HINT_TRUNCATION);
780 return write!(f, "{}", TYPE_HINT_TRUNCATION); 809 }
781 }
782 810
783 self.self_type_parameter().hir_fmt(f)?; 811 tr.self_type_parameter(&Interner).hir_fmt(f)?;
784 if use_as { 812 if use_as {
785 write!(f, " as ")?; 813 write!(f, " as ")?;
786 } else { 814 } else {
787 write!(f, ": ")?; 815 write!(f, ": ")?;
788 } 816 }
789 write!(f, "{}", f.db.trait_data(self.hir_trait_id()).name)?; 817 write!(f, "{}", f.db.trait_data(tr.hir_trait_id()).name)?;
790 if self.substitution.len(&Interner) > 1 { 818 if tr.substitution.len(&Interner) > 1 {
791 write!(f, "<")?; 819 write!(f, "<")?;
792 f.write_joined(&self.substitution.interned(&Interner)[1..], ", ")?; 820 f.write_joined(&tr.substitution.as_slice(&Interner)[1..], ", ")?;
793 write!(f, ">")?; 821 write!(f, ">")?;
794 }
795 Ok(())
796 } 822 }
823 Ok(())
797} 824}
798 825
799impl HirDisplay for TraitRef { 826impl HirDisplay for TraitRef {
800 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 827 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
801 self.hir_fmt_ext(f, false) 828 fmt_trait_ref(self, f, false)
802 } 829 }
803} 830}
804 831
@@ -812,7 +839,7 @@ impl HirDisplay for WhereClause {
812 WhereClause::Implemented(trait_ref) => trait_ref.hir_fmt(f)?, 839 WhereClause::Implemented(trait_ref) => trait_ref.hir_fmt(f)?,
813 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { 840 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
814 write!(f, "<")?; 841 write!(f, "<")?;
815 projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?; 842 fmt_trait_ref(&projection_ty.trait_ref(f.db), f, true)?;
816 write!( 843 write!(
817 f, 844 f,
818 ">::{} = ", 845 ">::{} = ",
@@ -821,20 +848,44 @@ impl HirDisplay for WhereClause {
821 ty.hir_fmt(f)?; 848 ty.hir_fmt(f)?;
822 } 849 }
823 WhereClause::AliasEq(_) => write!(f, "{{error}}")?, 850 WhereClause::AliasEq(_) => write!(f, "{{error}}")?,
851
852 // FIXME implement these
853 WhereClause::TypeOutlives(..) => {}
854 WhereClause::LifetimeOutlives(..) => {}
824 } 855 }
825 Ok(()) 856 Ok(())
826 } 857 }
827} 858}
828 859
860impl HirDisplay for LifetimeOutlives {
861 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
862 self.a.hir_fmt(f)?;
863 write!(f, ": ")?;
864 self.b.hir_fmt(f)
865 }
866}
867
829impl HirDisplay for Lifetime { 868impl HirDisplay for Lifetime {
830 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 869 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
870 self.interned().hir_fmt(f)
871 }
872}
873
874impl HirDisplay for LifetimeData {
875 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
831 match self { 876 match self {
832 Lifetime::Parameter(id) => { 877 LifetimeData::BoundVar(idx) => idx.hir_fmt(f),
878 LifetimeData::InferenceVar(_) => write!(f, "_"),
879 LifetimeData::Placeholder(idx) => {
880 let id = lt_from_placeholder_idx(f.db, *idx);
833 let generics = generics(f.db.upcast(), id.parent); 881 let generics = generics(f.db.upcast(), id.parent);
834 let param_data = &generics.params.lifetimes[id.local_id]; 882 let param_data = &generics.params.lifetimes[id.local_id];
835 write!(f, "{}", &param_data.name) 883 write!(f, "{}", param_data.name)
836 } 884 }
837 Lifetime::Static => write!(f, "'static"), 885 LifetimeData::Static => write!(f, "'static"),
886 LifetimeData::Empty(_) => Ok(()),
887 LifetimeData::Erased => Ok(()),
888 LifetimeData::Phantom(_, _) => Ok(()),
838 } 889 }
839 } 890 }
840} 891}
@@ -845,9 +896,11 @@ impl HirDisplay for DomainGoal {
845 DomainGoal::Holds(wc) => { 896 DomainGoal::Holds(wc) => {
846 write!(f, "Holds(")?; 897 write!(f, "Holds(")?;
847 wc.hir_fmt(f)?; 898 wc.hir_fmt(f)?;
848 write!(f, ")") 899 write!(f, ")")?;
849 } 900 }
901 _ => write!(f, "?")?,
850 } 902 }
903 Ok(())
851 } 904 }
852} 905}
853 906
@@ -945,6 +998,18 @@ impl HirDisplay for TypeRef {
945 write!(f, "dyn ")?; 998 write!(f, "dyn ")?;
946 f.write_joined(bounds, " + ")?; 999 f.write_joined(bounds, " + ")?;
947 } 1000 }
1001 TypeRef::Macro(macro_call) => {
1002 let macro_call = macro_call.to_node(f.db.upcast());
1003 let ctx = body::LowerCtx::with_hygiene(&Hygiene::new_unhygienic());
1004 match macro_call.path() {
1005 Some(path) => match Path::from_src(path, &ctx) {
1006 Some(path) => path.hir_fmt(f)?,
1007 None => write!(f, "{{macro}}")?,
1008 },
1009 None => write!(f, "{{macro}}")?,
1010 }
1011 write!(f, "!(..)")?;
1012 }
948 TypeRef::Error => write!(f, "{{error}}")?, 1013 TypeRef::Error => write!(f, "{{error}}")?,
949 } 1014 }
950 Ok(()) 1015 Ok(())
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 1b1d4458c..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, 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, AliasEq, AliasTy, Interner, TyBuilder, 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 }
@@ -247,7 +238,7 @@ impl<'a> InferenceContext<'a> {
247 table: unify::InferenceTable::new(), 238 table: unify::InferenceTable::new(),
248 obligations: Vec::default(), 239 obligations: Vec::default(),
249 last_obligations_check: None, 240 last_obligations_check: None,
250 return_ty: TyKind::Unknown.intern(&Interner), // set in collect_fn_signature 241 return_ty: TyKind::Error.intern(&Interner), // set in collect_fn_signature
251 trait_env: owner 242 trait_env: owner
252 .as_generic_def_id() 243 .as_generic_def_id()
253 .map_or_else(Default::default, |d| db.trait_environment(d)), 244 .map_or_else(Default::default, |d| db.trait_environment(d)),
@@ -261,7 +252,7 @@ impl<'a> InferenceContext<'a> {
261 } 252 }
262 253
263 fn err_ty(&self) -> Ty { 254 fn err_ty(&self) -> Ty {
264 TyKind::Unknown.intern(&Interner) 255 TyKind::Error.intern(&Interner)
265 } 256 }
266 257
267 fn resolve_all(mut self) -> InferenceResult { 258 fn resolve_all(mut self) -> InferenceResult {
@@ -326,13 +317,13 @@ impl<'a> InferenceContext<'a> {
326 /// 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.
327 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { 318 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
328 match ty.kind(&Interner) { 319 match ty.kind(&Interner) {
329 TyKind::Unknown => self.table.new_type_var(), 320 TyKind::Error => self.table.new_type_var(),
330 _ => ty, 321 _ => ty,
331 } 322 }
332 } 323 }
333 324
334 fn insert_type_vars(&mut self, ty: Ty) -> Ty { 325 fn insert_type_vars(&mut self, ty: Ty) -> Ty {
335 ty.fold(&mut |ty| self.insert_type_vars_shallow(ty)) 326 fold_tys(ty, |ty, _| self.insert_type_vars_shallow(ty), DebruijnIndex::INNERMOST)
336 } 327 }
337 328
338 fn resolve_obligations_as_possible(&mut self) { 329 fn resolve_obligations_as_possible(&mut self) {
@@ -345,17 +336,24 @@ impl<'a> InferenceContext<'a> {
345 self.last_obligations_check = Some(self.table.revision); 336 self.last_obligations_check = Some(self.table.revision);
346 let obligations = mem::replace(&mut self.obligations, Vec::new()); 337 let obligations = mem::replace(&mut self.obligations, Vec::new());
347 for obligation in obligations { 338 for obligation in obligations {
348 let in_env = InEnvironment::new(self.trait_env.env.clone(), obligation.clone()); 339 let in_env = InEnvironment::new(&self.trait_env.env, obligation.clone());
349 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env); 340 let canonicalized = self.canonicalizer().canonicalize_obligation(in_env);
350 let solution = 341 let solution =
351 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone()); 342 self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone());
352 343
353 match solution { 344 match solution {
354 Some(Solution::Unique(substs)) => { 345 Some(Solution::Unique(canonical_subst)) => {
355 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 );
356 } 354 }
357 Some(Solution::Ambig(Guidance::Definite(substs))) => { 355 Some(Solution::Ambig(Guidance::Definite(substs))) => {
358 canonicalized.apply_solution(self, substs.0); 356 canonicalized.apply_solution(self, substs);
359 self.obligations.push(obligation); 357 self.obligations.push(obligation);
360 } 358 }
361 Some(_) => { 359 Some(_) => {
@@ -436,12 +434,16 @@ impl<'a> InferenceContext<'a> {
436 /// to do it as well. 434 /// to do it as well.
437 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 435 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
438 let ty = self.resolve_ty_as_possible(ty); 436 let ty = self.resolve_ty_as_possible(ty);
439 ty.fold(&mut |ty| match ty.kind(&Interner) { 437 fold_tys(
440 TyKind::Alias(AliasTy::Projection(proj_ty)) => { 438 ty,
441 self.normalize_projection_ty(proj_ty.clone()) 439 |ty, _| match ty.kind(&Interner) {
442 } 440 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
443 _ => ty, 441 self.normalize_projection_ty(proj_ty.clone())
444 }) 442 }
443 _ => ty,
444 },
445 DebruijnIndex::INNERMOST,
446 )
445 } 447 }
446 448
447 fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty { 449 fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {
@@ -470,55 +472,32 @@ impl<'a> InferenceContext<'a> {
470 TypeNs::AdtId(AdtId::StructId(strukt)) => { 472 TypeNs::AdtId(AdtId::StructId(strukt)) => {
471 let substs = ctx.substs_from_path(path, strukt.into(), true); 473 let substs = ctx.substs_from_path(path, strukt.into(), true);
472 let ty = self.db.ty(strukt.into()); 474 let ty = self.db.ty(strukt.into());
473 let ty = self.insert_type_vars(ty.subst(&substs)); 475 let ty = self.insert_type_vars(ty.substitute(&Interner, &substs));
474 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) 476 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
475 } 477 }
476 TypeNs::AdtId(AdtId::UnionId(u)) => { 478 TypeNs::AdtId(AdtId::UnionId(u)) => {
477 let substs = ctx.substs_from_path(path, u.into(), true); 479 let substs = ctx.substs_from_path(path, u.into(), true);
478 let ty = self.db.ty(u.into()); 480 let ty = self.db.ty(u.into());
479 let ty = self.insert_type_vars(ty.subst(&substs)); 481 let ty = self.insert_type_vars(ty.substitute(&Interner, &substs));
480 forbid_unresolved_segments((ty, Some(u.into())), unresolved) 482 forbid_unresolved_segments((ty, Some(u.into())), unresolved)
481 } 483 }
482 TypeNs::EnumVariantId(var) => { 484 TypeNs::EnumVariantId(var) => {
483 let substs = ctx.substs_from_path(path, var.into(), true); 485 let substs = ctx.substs_from_path(path, var.into(), true);
484 let ty = self.db.ty(var.parent.into()); 486 let ty = self.db.ty(var.parent.into());
485 let ty = self.insert_type_vars(ty.subst(&substs)); 487 let ty = self.insert_type_vars(ty.substitute(&Interner, &substs));
486 forbid_unresolved_segments((ty, Some(var.into())), unresolved) 488 forbid_unresolved_segments((ty, Some(var.into())), unresolved)
487 } 489 }
488 TypeNs::SelfType(impl_id) => { 490 TypeNs::SelfType(impl_id) => {
489 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 491 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
490 let substs = generics.type_params_subst(self.db); 492 let substs = generics.type_params_subst(self.db);
491 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 493 let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs);
492 match unresolved { 494 self.resolve_variant_on_alias(ty, unresolved, path)
493 None => {
494 let variant = ty_variant(&ty);
495 (ty, variant)
496 }
497 Some(1) => {
498 let segment = path.mod_path().segments().last().unwrap();
499 // this could be an enum variant or associated type
500 if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
501 let enum_data = self.db.enum_data(enum_id);
502 if let Some(local_id) = enum_data.variant(segment) {
503 let variant = EnumVariantId { parent: enum_id, local_id };
504 return (ty, Some(variant.into()));
505 }
506 }
507 // FIXME potentially resolve assoc type
508 (self.err_ty(), None)
509 }
510 Some(_) => {
511 // FIXME diagnostic
512 (self.err_ty(), None)
513 }
514 }
515 } 495 }
516 TypeNs::TypeAliasId(it) => { 496 TypeNs::TypeAliasId(it) => {
517 let ty = TyBuilder::def_ty(self.db, it.into()) 497 let ty = TyBuilder::def_ty(self.db, it.into())
518 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 498 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
519 .build(); 499 .build();
520 let variant = ty_variant(&ty); 500 self.resolve_variant_on_alias(ty, unresolved, path)
521 forbid_unresolved_segments((ty, variant), unresolved)
522 } 501 }
523 TypeNs::AdtSelfType(_) => { 502 TypeNs::AdtSelfType(_) => {
524 // 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
@@ -542,19 +521,46 @@ impl<'a> InferenceContext<'a> {
542 result 521 result
543 } else { 522 } else {
544 // FIXME diagnostic 523 // FIXME diagnostic
545 (TyKind::Unknown.intern(&Interner), None) 524 (TyKind::Error.intern(&Interner), None)
546 } 525 }
547 } 526 }
527 }
548 528
549 fn ty_variant(ty: &Ty) -> Option<VariantId> { 529 fn resolve_variant_on_alias(
550 ty.as_adt().and_then(|(adt_id, _)| match adt_id { 530 &mut self,
551 AdtId::StructId(s) => Some(VariantId::StructId(s)), 531 ty: Ty,
552 AdtId::UnionId(u) => Some(VariantId::UnionId(u)), 532 unresolved: Option<usize>,
553 AdtId::EnumId(_) => { 533 path: &Path,
554 // FIXME Error E0071, expected struct, variant or union type, found enum `Foo` 534 ) -> (Ty, Option<VariantId>) {
555 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 }
556 } 556 }
557 }) 557 // FIXME potentially resolve assoc type
558 (self.err_ty(), None)
559 }
560 Some(_) => {
561 // FIXME diagnostic
562 (self.err_ty(), None)
563 }
558 } 564 }
559 } 565 }
560 566
@@ -692,25 +698,6 @@ impl<'a> InferenceContext<'a> {
692 } 698 }
693} 699}
694 700
695/// The kinds of placeholders we need during type inference. There's separate
696/// values for general types, and for integer and float variables. The latter
697/// two are used for inference of literal values (e.g. `100` could be one of
698/// several integer types).
699#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
700pub struct InferenceVar {
701 index: u32,
702}
703
704impl InferenceVar {
705 fn to_inner(self) -> unify::TypeVarId {
706 unify::TypeVarId(self.index)
707 }
708
709 fn from_inner(unify::TypeVarId(index): unify::TypeVarId) -> Self {
710 InferenceVar { index }
711 }
712}
713
714/// When inferring an expression, we propagate downward whatever type hint we 701/// When inferring an expression, we propagate downward whatever type hint we
715/// are able in the form of an `Expectation`. 702/// are able in the form of an `Expectation`.
716#[derive(Clone, PartialEq, Eq, Debug)] 703#[derive(Clone, PartialEq, Eq, Debug)]
@@ -755,7 +742,7 @@ impl Expectation {
755 fn none() -> Self { 742 fn none() -> Self {
756 Expectation { 743 Expectation {
757 // FIXME 744 // FIXME
758 ty: TyKind::Unknown.intern(&Interner), 745 ty: TyKind::Error.intern(&Interner),
759 rvalue_hint: false, 746 rvalue_hint: false,
760 } 747 }
761 } 748 }
@@ -763,7 +750,7 @@ impl Expectation {
763 fn coercion_target(&self) -> Ty { 750 fn coercion_target(&self) -> Ty {
764 if self.rvalue_hint { 751 if self.rvalue_hint {
765 // FIXME 752 // FIXME
766 TyKind::Unknown.intern(&Interner) 753 TyKind::Error.intern(&Interner)
767 } else { 754 } else {
768 self.ty.clone() 755 self.ty.clone()
769 } 756 }
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 028a4d568..1f463a425 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -7,7 +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::{autoderef, traits::Solution, Interner, Ty, TyBuilder, TyKind}; 10use crate::{autoderef, Canonical, Interner, Solution, Ty, TyBuilder, TyExt, TyKind};
11 11
12use super::{InEnvironment, InferenceContext}; 12use super::{InEnvironment, InferenceContext};
13 13
@@ -71,17 +71,19 @@ impl<'a> InferenceContext<'a> {
71 } 71 }
72 72
73 // Pointer weakening and function to pointer 73 // Pointer weakening and function to pointer
74 match (from_ty.interned_mut(), to_ty.kind(&Interner)) { 74 match (from_ty.kind(&Interner), to_ty.kind(&Interner)) {
75 // `*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 }
76 // `&mut T` -> `&T` 79 // `&mut T` -> `&T`
77 (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) 80 (TyKind::Ref(_, lt, inner), TyKind::Ref(m2 @ Mutability::Not, ..)) => {
78 | (TyKind::Ref(m1, ..), TyKind::Ref(m2 @ Mutability::Not, ..)) => { 81 from_ty = TyKind::Ref(*m2, lt.clone(), inner.clone()).intern(&Interner);
79 *m1 = *m2;
80 } 82 }
81 // `&T` -> `*const T` 83 // `&T` -> `*const T`
82 // `&mut T` -> `*mut T`/`*const T` 84 // `&mut T` -> `*mut T`/`*const T`
83 (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..)) 85 (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..))
84 | (TyKind::Ref(Mutability::Mut, substs), &TyKind::Raw(m2, ..)) => { 86 | (TyKind::Ref(Mutability::Mut, _, substs), &TyKind::Raw(m2, ..)) => {
85 from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner); 87 from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner);
86 } 88 }
87 89
@@ -111,7 +113,9 @@ impl<'a> InferenceContext<'a> {
111 // Auto Deref if cannot coerce 113 // Auto Deref if cannot coerce
112 match (from_ty.kind(&Interner), to_ty.kind(&Interner)) { 114 match (from_ty.kind(&Interner), to_ty.kind(&Interner)) {
113 // FIXME: DerefMut 115 // FIXME: DerefMut
114 (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 }
115 119
116 // Otherwise, normal unify 120 // Otherwise, normal unify
117 _ => self.unify(&from_ty, to_ty), 121 _ => self.unify(&from_ty, to_ty),
@@ -137,7 +141,7 @@ impl<'a> InferenceContext<'a> {
137 b.push(from_ty.clone()).push(to_ty.clone()).build() 141 b.push(from_ty.clone()).push(to_ty.clone()).build()
138 }; 142 };
139 143
140 let goal = InEnvironment::new(self.trait_env.env.clone(), trait_ref.cast(&Interner)); 144 let goal = InEnvironment::new(&self.trait_env.env, trait_ref.cast(&Interner));
141 145
142 let canonicalizer = self.canonicalizer(); 146 let canonicalizer = self.canonicalizer();
143 let canonicalized = canonicalizer.canonicalize_obligation(goal); 147 let canonicalized = canonicalizer.canonicalize_obligation(goal);
@@ -146,7 +150,14 @@ impl<'a> InferenceContext<'a> {
146 150
147 match solution { 151 match solution {
148 Solution::Unique(v) => { 152 Solution::Unique(v) => {
149 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 );
150 } 161 }
151 _ => return None, 162 _ => return None,
152 }; 163 };
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index c584a2c08..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_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, FnPointer, FnSig, Interner, Rawness, Scalar, Substitution, 26 AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner,
26 TraitRef, Ty, TyBuilder, TyKind, 27 ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind,
27}; 28};
28 29
29use super::{ 30use super::{
@@ -180,7 +181,8 @@ impl<'a> InferenceContext<'a> {
180 let inner_ty = self.infer_expr(*body, &Expectation::none()); 181 let inner_ty = self.infer_expr(*body, &Expectation::none());
181 let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body); 182 let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body);
182 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();
183 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)
184 } 186 }
185 Expr::Loop { body, label } => { 187 Expr::Loop { body, label } => {
186 self.breakables.push(BreakableContext { 188 self.breakables.push(BreakableContext {
@@ -259,14 +261,17 @@ impl<'a> InferenceContext<'a> {
259 }; 261 };
260 sig_tys.push(ret_ty.clone()); 262 sig_tys.push(ret_ty.clone());
261 let sig_ty = TyKind::Function(FnPointer { 263 let sig_ty = TyKind::Function(FnPointer {
262 num_args: sig_tys.len() - 1, 264 num_binders: 0,
263 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, 265 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
264 substs: Substitution::from_iter(&Interner, sig_tys.clone()), 266 substitution: FnSubst(
267 Substitution::from_iter(&Interner, sig_tys.clone()).shifted_in(&Interner),
268 ),
265 }) 269 })
266 .intern(&Interner); 270 .intern(&Interner);
267 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();
268 let closure_ty = 272 let closure_ty =
269 TyKind::Closure(closure_id, Substitution::single(sig_ty)).intern(&Interner); 273 TyKind::Closure(closure_id, Substitution::from1(&Interner, sig_ty))
274 .intern(&Interner);
270 275
271 // Eagerly try to relate the closure type with the expected 276 // Eagerly try to relate the closure type with the expected
272 // type, otherwise we often won't have enough information to 277 // type, otherwise we often won't have enough information to
@@ -313,7 +318,13 @@ impl<'a> InferenceContext<'a> {
313 self.normalize_associated_types_in(ret_ty) 318 self.normalize_associated_types_in(ret_ty)
314 } 319 }
315 Expr::MethodCall { receiver, args, method_name, generic_args } => self 320 Expr::MethodCall { receiver, args, method_name, generic_args } => self
316 .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 ),
317 Expr::Match { expr, arms } => { 328 Expr::Match { expr, arms } => {
318 let input_ty = self.infer_expr(*expr, &Expectation::none()); 329 let input_ty = self.infer_expr(*expr, &Expectation::none());
319 330
@@ -394,16 +405,19 @@ impl<'a> InferenceContext<'a> {
394 TyKind::Never.intern(&Interner) 405 TyKind::Never.intern(&Interner)
395 } 406 }
396 Expr::RecordLit { path, fields, spread } => { 407 Expr::RecordLit { path, fields, spread } => {
397 let (ty, def_id) = self.resolve_variant(path.as_ref()); 408 let (ty, def_id) = self.resolve_variant(path.as_deref());
398 if let Some(variant) = def_id { 409 if let Some(variant) = def_id {
399 self.write_variant_resolution(tgt_expr.into(), variant); 410 self.write_variant_resolution(tgt_expr.into(), variant);
400 } 411 }
401 412
402 self.unify(&ty, &expected.ty); 413 self.unify(&ty, &expected.ty);
403 414
404 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner)); 415 let substs = ty
416 .as_adt()
417 .map(|(_, s)| s.clone())
418 .unwrap_or_else(|| Substitution::empty(&Interner));
405 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();
406 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()));
407 for field in fields.iter() { 421 for field in fields.iter() {
408 let field_def = 422 let field_def =
409 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) {
@@ -415,11 +429,8 @@ impl<'a> InferenceContext<'a> {
415 None 429 None
416 } 430 }
417 }); 431 });
418 if let Some(field_def) = field_def {
419 self.result.record_field_resolutions.insert(field.expr, field_def);
420 }
421 let field_ty = field_def.map_or(self.err_ty(), |it| { 432 let field_ty = field_def.map_or(self.err_ty(), |it| {
422 field_types[it.local_id].clone().subst(&substs) 433 field_types[it.local_id].clone().substitute(&Interner, &substs)
423 }); 434 });
424 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 435 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
425 } 436 }
@@ -453,7 +464,7 @@ impl<'a> InferenceContext<'a> {
453 match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) { 464 match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) {
454 TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| { 465 TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| {
455 substs 466 substs
456 .interned(&Interner) 467 .as_slice(&Interner)
457 .get(idx) 468 .get(idx)
458 .map(|a| a.assert_ty_ref(&Interner)) 469 .map(|a| a.assert_ty_ref(&Interner))
459 .cloned() 470 .cloned()
@@ -466,7 +477,7 @@ impl<'a> InferenceContext<'a> {
466 Some( 477 Some(
467 self.db.field_types((*s).into())[field.local_id] 478 self.db.field_types((*s).into())[field.local_id]
468 .clone() 479 .clone()
469 .subst(&parameters), 480 .substitute(&Interner, &parameters),
470 ) 481 )
471 } else { 482 } else {
472 None 483 None
@@ -480,7 +491,7 @@ impl<'a> InferenceContext<'a> {
480 Some( 491 Some(
481 self.db.field_types((*u).into())[field.local_id] 492 self.db.field_types((*u).into())[field.local_id]
482 .clone() 493 .clone()
483 .subst(&parameters), 494 .substitute(&Interner, &parameters),
484 ) 495 )
485 } else { 496 } else {
486 None 497 None
@@ -527,7 +538,7 @@ impl<'a> InferenceContext<'a> {
527 let inner_ty = self.infer_expr_inner(*expr, &expectation); 538 let inner_ty = self.infer_expr_inner(*expr, &expectation);
528 match rawness { 539 match rawness {
529 Rawness::RawPtr => TyKind::Raw(mutability, inner_ty), 540 Rawness::RawPtr => TyKind::Raw(mutability, inner_ty),
530 Rawness::Ref => TyKind::Ref(mutability, inner_ty), 541 Rawness::Ref => TyKind::Ref(mutability, static_lifetime(), inner_ty),
531 } 542 }
532 .intern(&Interner) 543 .intern(&Interner)
533 } 544 }
@@ -702,7 +713,7 @@ impl<'a> InferenceContext<'a> {
702 } 713 }
703 Expr::Array(array) => { 714 Expr::Array(array) => {
704 let elem_ty = match expected.ty.kind(&Interner) { 715 let elem_ty = match expected.ty.kind(&Interner) {
705 TyKind::Array(st) | TyKind::Slice(st) => st.clone(), 716 TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(),
706 _ => self.table.new_type_var(), 717 _ => self.table.new_type_var(),
707 }; 718 };
708 719
@@ -726,17 +737,19 @@ impl<'a> InferenceContext<'a> {
726 } 737 }
727 } 738 }
728 739
729 TyKind::Array(elem_ty).intern(&Interner) 740 TyKind::Array(elem_ty, dummy_usize_const()).intern(&Interner)
730 } 741 }
731 Expr::Literal(lit) => match lit { 742 Expr::Literal(lit) => match lit {
732 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), 743 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
733 Literal::String(..) => { 744 Literal::String(..) => {
734 TyKind::Ref(Mutability::Not, TyKind::Str.intern(&Interner)).intern(&Interner) 745 TyKind::Ref(Mutability::Not, static_lifetime(), TyKind::Str.intern(&Interner))
746 .intern(&Interner)
735 } 747 }
736 Literal::ByteString(..) => { 748 Literal::ByteString(..) => {
737 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); 749 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner);
738 let array_type = TyKind::Array(byte_type).intern(&Interner); 750 let array_type =
739 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)
740 } 753 }
741 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), 754 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner),
742 Literal::Int(_v, ty) => match ty { 755 Literal::Int(_v, ty) => match ty {
@@ -853,10 +866,10 @@ impl<'a> InferenceContext<'a> {
853 self.write_method_resolution(tgt_expr, func); 866 self.write_method_resolution(tgt_expr, func);
854 (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())))
855 } 868 }
856 None => (receiver_ty, Binders::new(0, self.err_ty()), None), 869 None => (receiver_ty, Binders::empty(&Interner, self.err_ty()), None),
857 }; 870 };
858 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);
859 let method_ty = method_ty.subst(&substs); 872 let method_ty = method_ty.substitute(&Interner, &substs);
860 let method_ty = self.insert_type_vars(method_ty); 873 let method_ty = self.insert_type_vars(method_ty);
861 self.register_obligations_for_call(&method_ty); 874 self.register_obligations_for_call(&method_ty);
862 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) {
@@ -872,7 +885,9 @@ impl<'a> InferenceContext<'a> {
872 // Apply autoref so the below unification works correctly 885 // Apply autoref so the below unification works correctly
873 // FIXME: return correct autorefs from lookup_method 886 // FIXME: return correct autorefs from lookup_method
874 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 887 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
875 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 }
876 _ => derefed_receiver_ty, 891 _ => derefed_receiver_ty,
877 }; 892 };
878 self.unify(&expected_receiver_ty, &actual_receiver_ty); 893 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -953,9 +968,11 @@ impl<'a> InferenceContext<'a> {
953 let def: CallableDefId = from_chalk(self.db, *fn_def); 968 let def: CallableDefId = from_chalk(self.db, *fn_def);
954 let generic_predicates = self.db.generic_predicates(def.into()); 969 let generic_predicates = self.db.generic_predicates(def.into());
955 for predicate in generic_predicates.iter() { 970 for predicate in generic_predicates.iter() {
956 let (predicate, binders) = 971 let (predicate, binders) = predicate
957 predicate.clone().subst(parameters).into_value_and_skipped_binders(); 972 .clone()
958 always!(binders == 0); // quantified where clauses not yet handled 973 .substitute(&Interner, parameters)
974 .into_value_and_skipped_binders();
975 always!(binders.len(&Interner) == 0); // quantified where clauses not yet handled
959 self.push_obligation(predicate.cast(&Interner)); 976 self.push_obligation(predicate.cast(&Interner));
960 } 977 }
961 // add obligation for trait implementation, if this is a trait method 978 // add obligation for trait implementation, if this is a trait method
@@ -964,8 +981,10 @@ impl<'a> InferenceContext<'a> {
964 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container 981 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
965 { 982 {
966 // construct a TraitRef 983 // construct a TraitRef
967 let substs = 984 let substs = crate::subst_prefix(
968 parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); 985 &*parameters,
986 generics(self.db.upcast(), trait_.into()).len(),
987 );
969 self.push_obligation( 988 self.push_obligation(
970 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs } 989 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }
971 .cast(&Interner), 990 .cast(&Interner),
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 5b70d5e5a..aea354cde 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -7,14 +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, utils::variant_data, Interner, Substitution, Ty, TyBuilder, 15 lower::lower_to_chalk_mutability, static_lifetime, Interner, Substitution, Ty, TyBuilder,
17 TyKind, 16 TyExt, TyKind,
18}; 17};
19 18
20impl<'a> InferenceContext<'a> { 19impl<'a> InferenceContext<'a> {
@@ -28,13 +27,14 @@ impl<'a> InferenceContext<'a> {
28 ellipsis: Option<usize>, 27 ellipsis: Option<usize>,
29 ) -> Ty { 28 ) -> Ty {
30 let (ty, def) = self.resolve_variant(path); 29 let (ty, def) = self.resolve_variant(path);
31 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()));
32 if let Some(variant) = def { 31 if let Some(variant) = def {
33 self.write_variant_resolution(id.into(), variant); 32 self.write_variant_resolution(id.into(), variant);
34 } 33 }
35 self.unify(&ty, expected); 34 self.unify(&ty, expected);
36 35
37 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner)); 36 let substs =
37 ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(&Interner));
38 38
39 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();
40 let (pre, post) = match ellipsis { 40 let (pre, post) = match ellipsis {
@@ -49,7 +49,9 @@ impl<'a> InferenceContext<'a> {
49 let expected_ty = var_data 49 let expected_ty = var_data
50 .as_ref() 50 .as_ref()
51 .and_then(|d| d.field(&Name::new_tuple_field(i))) 51 .and_then(|d| d.field(&Name::new_tuple_field(i)))
52 .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 });
53 let expected_ty = self.normalize_associated_types_in(expected_ty); 55 let expected_ty = self.normalize_associated_types_in(expected_ty);
54 self.infer_pat(subpat, &expected_ty, default_bm); 56 self.infer_pat(subpat, &expected_ty, default_bm);
55 } 57 }
@@ -66,25 +68,22 @@ impl<'a> InferenceContext<'a> {
66 id: PatId, 68 id: PatId,
67 ) -> Ty { 69 ) -> Ty {
68 let (ty, def) = self.resolve_variant(path); 70 let (ty, def) = self.resolve_variant(path);
69 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()));
70 if let Some(variant) = def { 72 if let Some(variant) = def {
71 self.write_variant_resolution(id.into(), variant); 73 self.write_variant_resolution(id.into(), variant);
72 } 74 }
73 75
74 self.unify(&ty, expected); 76 self.unify(&ty, expected);
75 77
76 let substs = ty.substs().cloned().unwrap_or_else(|| Substitution::empty(&Interner)); 78 let substs =
79 ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(&Interner));
77 80
78 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();
79 for subpat in subpats { 82 for subpat in subpats {
80 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));
81 if let Some(local_id) = matching_field { 84 let expected_ty = matching_field.map_or(self.err_ty(), |field| {
82 let field_def = FieldId { parent: def.unwrap(), local_id }; 85 field_tys[field].clone().substitute(&Interner, &substs)
83 self.result.record_pat_field_resolutions.insert(subpat.pat, field_def); 86 });
84 }
85
86 let expected_ty = matching_field
87 .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs));
88 let expected_ty = self.normalize_associated_types_in(expected_ty); 87 let expected_ty = self.normalize_associated_types_in(expected_ty);
89 self.infer_pat(subpat.pat, &expected_ty, default_bm); 88 self.infer_pat(subpat.pat, &expected_ty, default_bm);
90 } 89 }
@@ -101,7 +100,7 @@ impl<'a> InferenceContext<'a> {
101 let body = Arc::clone(&self.body); // avoid borrow checker problem 100 let body = Arc::clone(&self.body); // avoid borrow checker problem
102 101
103 if is_non_ref_pat(&body, pat) { 102 if is_non_ref_pat(&body, pat) {
104 while let Some((inner, mutability)) = expected.as_reference() { 103 while let Some((inner, _lifetime, mutability)) = expected.as_reference() {
105 expected = inner; 104 expected = inner;
106 default_bm = match default_bm { 105 default_bm = match default_bm {
107 BindingMode::Move => BindingMode::Ref(mutability), 106 BindingMode::Move => BindingMode::Ref(mutability),
@@ -123,7 +122,7 @@ impl<'a> InferenceContext<'a> {
123 let ty = match &body[pat] { 122 let ty = match &body[pat] {
124 &Pat::Tuple { ref args, ellipsis } => { 123 &Pat::Tuple { ref args, ellipsis } => {
125 let expectations = match expected.as_tuple() { 124 let expectations = match expected.as_tuple() {
126 Some(parameters) => &*parameters.0, 125 Some(parameters) => &*parameters.as_slice(&Interner),
127 _ => &[], 126 _ => &[],
128 }; 127 };
129 128
@@ -159,7 +158,7 @@ impl<'a> InferenceContext<'a> {
159 Pat::Ref { pat, mutability } => { 158 Pat::Ref { pat, mutability } => {
160 let mutability = lower_to_chalk_mutability(*mutability); 159 let mutability = lower_to_chalk_mutability(*mutability);
161 let expectation = match expected.as_reference() { 160 let expectation = match expected.as_reference() {
162 Some((inner_ty, exp_mut)) => { 161 Some((inner_ty, _lifetime, exp_mut)) => {
163 if mutability != exp_mut { 162 if mutability != exp_mut {
164 // FIXME: emit type error? 163 // FIXME: emit type error?
165 } 164 }
@@ -168,10 +167,10 @@ impl<'a> InferenceContext<'a> {
168 _ => self.result.standard_types.unknown.clone(), 167 _ => self.result.standard_types.unknown.clone(),
169 }; 168 };
170 let subty = self.infer_pat(*pat, &expectation, default_bm); 169 let subty = self.infer_pat(*pat, &expectation, default_bm);
171 TyKind::Ref(mutability, subty).intern(&Interner) 170 TyKind::Ref(mutability, static_lifetime(), subty).intern(&Interner)
172 } 171 }
173 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(
174 p.as_ref(), 173 p.as_deref(),
175 subpats, 174 subpats,
176 expected, 175 expected,
177 default_bm, 176 default_bm,
@@ -179,7 +178,7 @@ impl<'a> InferenceContext<'a> {
179 *ellipsis, 178 *ellipsis,
180 ), 179 ),
181 Pat::Record { path: p, args: fields, ellipsis: _ } => { 180 Pat::Record { path: p, args: fields, ellipsis: _ } => {
182 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)
183 } 182 }
184 Pat::Path(path) => { 183 Pat::Path(path) => {
185 // FIXME use correct resolver for the surrounding expression 184 // FIXME use correct resolver for the surrounding expression
@@ -201,7 +200,8 @@ impl<'a> InferenceContext<'a> {
201 200
202 let bound_ty = match mode { 201 let bound_ty = match mode {
203 BindingMode::Ref(mutability) => { 202 BindingMode::Ref(mutability) => {
204 TyKind::Ref(mutability, inner_ty.clone()).intern(&Interner) 203 TyKind::Ref(mutability, static_lifetime(), inner_ty.clone())
204 .intern(&Interner)
205 } 205 }
206 BindingMode::Move => inner_ty.clone(), 206 BindingMode::Move => inner_ty.clone(),
207 }; 207 };
@@ -210,17 +210,20 @@ impl<'a> InferenceContext<'a> {
210 return inner_ty; 210 return inner_ty;
211 } 211 }
212 Pat::Slice { prefix, slice, suffix } => { 212 Pat::Slice { prefix, slice, suffix } => {
213 let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.kind(&Interner) { 213 let elem_ty = match expected.kind(&Interner) {
214 TyKind::Array(st) => (TyKind::Array, st.clone()), 214 TyKind::Array(st, _) | TyKind::Slice(st) => st.clone(),
215 TyKind::Slice(st) => (TyKind::Slice, st.clone()), 215 _ => self.err_ty(),
216 _ => (TyKind::Slice, self.err_ty()),
217 }; 216 };
218 217
219 for pat_id in prefix.iter().chain(suffix) { 218 for pat_id in prefix.iter().chain(suffix) {
220 self.infer_pat(*pat_id, &elem_ty, default_bm); 219 self.infer_pat(*pat_id, &elem_ty, default_bm);
221 } 220 }
222 221
223 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);
224 if let Some(slice_pat_id) = slice { 227 if let Some(slice_pat_id) = slice {
225 self.infer_pat(*slice_pat_id, &pat_ty, default_bm); 228 self.infer_pat(*slice_pat_id, &pat_ty, default_bm);
226 } 229 }
@@ -239,7 +242,7 @@ impl<'a> InferenceContext<'a> {
239 let (inner_ty, alloc_ty) = match expected.as_adt() { 242 let (inner_ty, alloc_ty) = match expected.as_adt() {
240 Some((adt, subst)) if adt == box_adt => ( 243 Some((adt, subst)) if adt == box_adt => (
241 subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(), 244 subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(),
242 subst.interned(&Interner).get(1).and_then(|a| a.ty(&Interner).cloned()), 245 subst.as_slice(&Interner).get(1).and_then(|a| a.ty(&Interner).cloned()),
243 ), 246 ),
244 _ => (self.result.standard_types.unknown.clone(), None), 247 _ => (self.result.standard_types.unknown.clone(), None),
245 }; 248 };
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index 671ea355f..495282eba 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -10,7 +10,10 @@ use hir_def::{
10}; 10};
11use hir_expand::name::Name; 11use hir_expand::name::Name;
12 12
13use crate::{method_resolution, Interner, Substitution, Ty, TyBuilder, TyKind, ValueTyDefId}; 13use crate::{
14 method_resolution, Interner, Substitution, TraitRefExt, Ty, TyBuilder, TyExt, TyKind,
15 ValueTyDefId,
16};
14 17
15use super::{ExprOrPatId, InferenceContext, TraitRef}; 18use super::{ExprOrPatId, InferenceContext, TraitRef};
16 19
@@ -81,9 +84,9 @@ impl<'a> InferenceContext<'a> {
81 ValueNs::ImplSelf(impl_id) => { 84 ValueNs::ImplSelf(impl_id) => {
82 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 85 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
83 let substs = generics.type_params_subst(self.db); 86 let substs = generics.type_params_subst(self.db);
84 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 87 let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs);
85 if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() { 88 if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() {
86 let ty = self.db.value_ty(struct_id.into()).subst(&substs); 89 let ty = self.db.value_ty(struct_id.into()).substitute(&Interner, &substs);
87 return Some(ty); 90 return Some(ty);
88 } else { 91 } else {
89 // FIXME: diagnostic, invalid Self reference 92 // FIXME: diagnostic, invalid Self reference
@@ -98,7 +101,7 @@ impl<'a> InferenceContext<'a> {
98 let substs = ctx.substs_from_path(path, typable, true); 101 let substs = ctx.substs_from_path(path, typable, true);
99 let ty = TyBuilder::value_ty(self.db, typable) 102 let ty = TyBuilder::value_ty(self.db, typable)
100 .use_parent_substs(&parent_substs) 103 .use_parent_substs(&parent_substs)
101 .fill(substs.interned(&Interner)[parent_substs.len(&Interner)..].iter().cloned()) 104 .fill(substs.as_slice(&Interner)[parent_substs.len(&Interner)..].iter().cloned())
102 .build(); 105 .build();
103 Some(ty) 106 Some(ty)
104 } 107 }
@@ -142,7 +145,7 @@ impl<'a> InferenceContext<'a> {
142 remaining_segments_for_ty, 145 remaining_segments_for_ty,
143 true, 146 true,
144 ); 147 );
145 if let TyKind::Unknown = ty.kind(&Interner) { 148 if let TyKind::Error = ty.kind(&Interner) {
146 return None; 149 return None;
147 } 150 }
148 151
@@ -207,7 +210,7 @@ impl<'a> InferenceContext<'a> {
207 name: &Name, 210 name: &Name,
208 id: ExprOrPatId, 211 id: ExprOrPatId,
209 ) -> Option<(ValueNs, Option<Substitution>)> { 212 ) -> Option<(ValueNs, Option<Substitution>)> {
210 if let TyKind::Unknown = ty.kind(&Interner) { 213 if let TyKind::Error = ty.kind(&Interner) {
211 return None; 214 return None;
212 } 215 }
213 216
@@ -243,7 +246,8 @@ impl<'a> InferenceContext<'a> {
243 let impl_substs = TyBuilder::subst_for_def(self.db, impl_id) 246 let impl_substs = TyBuilder::subst_for_def(self.db, impl_id)
244 .fill(iter::repeat_with(|| self.table.new_type_var())) 247 .fill(iter::repeat_with(|| self.table.new_type_var()))
245 .build(); 248 .build();
246 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);
247 self.unify(&impl_self_ty, &ty); 251 self.unify(&impl_self_ty, &ty);
248 Some(impl_substs) 252 Some(impl_substs)
249 } 253 }
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index a04b935ef..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.kind(&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(
@@ -132,15 +140,17 @@ impl<T> Canonicalized<T> {
132 let new_vars = Substitution::from_iter( 140 let new_vars = Substitution::from_iter(
133 &Interner, 141 &Interner,
134 solution.binders.iter(&Interner).map(|k| match k.kind { 142 solution.binders.iter(&Interner).map(|k| match k.kind {
135 VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(), 143 VariableKind::Ty(TyVariableKind::General) => {
136 VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(), 144 ctx.table.new_type_var().cast(&Interner)
137 VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(), 145 }
138 // HACK: Chalk can sometimes return new lifetime variables. We 146 VariableKind::Ty(TyVariableKind::Integer) => {
139 // want to just skip them, but to not mess up the indices of 147 ctx.table.new_integer_var().cast(&Interner)
140 // other variables, we'll just create a new type variable in 148 }
141 // their place instead. This should not matter (we never see the 149 VariableKind::Ty(TyVariableKind::Float) => {
142 // actual *uses* of the lifetime variable). 150 ctx.table.new_float_var().cast(&Interner)
143 VariableKind::Lifetime => ctx.table.new_type_var(), 151 }
152 // Chalk can sometimes return new lifetime variables. We just use the static lifetime everywhere
153 VariableKind::Lifetime => static_lifetime().cast(&Interner),
144 _ => panic!("const variable in solution"), 154 _ => panic!("const variable in solution"),
145 }), 155 }),
146 ); 156 );
@@ -149,7 +159,7 @@ impl<T> Canonicalized<T> {
149 // eagerly replace projections in the type; we may be getting types 159 // eagerly replace projections in the type; we may be getting types
150 // e.g. from where clauses where this hasn't happened yet 160 // e.g. from where clauses where this hasn't happened yet
151 let ty = ctx.normalize_associated_types_in( 161 let ty = ctx.normalize_associated_types_in(
152 ty.assert_ty_ref(&Interner).clone().subst_bound_vars(&new_vars), 162 new_vars.apply(ty.assert_ty_ref(&Interner).clone(), &Interner),
153 ); 163 );
154 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); 164 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty);
155 } 165 }
@@ -170,8 +180,8 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
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 ); 182 );
173 let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars); 183 let ty1_with_vars = vars.apply(tys.value.0.clone(), &Interner);
174 let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars); 184 let ty2_with_vars = vars.apply(tys.value.1.clone(), &Interner);
175 if !table.unify(&ty1_with_vars, &ty2_with_vars) { 185 if !table.unify(&ty1_with_vars, &ty2_with_vars) {
176 return None; 186 return None;
177 } 187 }
@@ -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 }
@@ -247,7 +257,7 @@ impl InferenceTable {
247 self.type_variable_table.push(TypeVariableData { diverging }); 257 self.type_variable_table.push(TypeVariableData { diverging });
248 let key = self.var_unification_table.new_key(TypeVarValue::Unknown); 258 let key = self.var_unification_table.new_key(TypeVarValue::Unknown);
249 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);
250 TyKind::InferenceVar(InferenceVar::from_inner(key), kind).intern(&Interner) 260 TyKind::InferenceVar(to_inference_var(key), kind).intern(&Interner)
251 } 261 }
252 262
253 pub(crate) fn new_type_var(&mut self) -> Ty { 263 pub(crate) fn new_type_var(&mut self) -> Ty {
@@ -284,7 +294,7 @@ impl InferenceTable {
284 substs2: &Substitution, 294 substs2: &Substitution,
285 depth: usize, 295 depth: usize,
286 ) -> bool { 296 ) -> bool {
287 substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| { 297 substs1.iter(&Interner).zip(substs2.iter(&Interner)).all(|(t1, t2)| {
288 self.unify_inner(t1.assert_ty_ref(&Interner), t2.assert_ty_ref(&Interner), depth) 298 self.unify_inner(t1.assert_ty_ref(&Interner), t2.assert_ty_ref(&Interner), depth)
289 }) 299 })
290 } 300 }
@@ -305,8 +315,8 @@ impl InferenceTable {
305 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) 315 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2))
306 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) 316 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2))
307 | ( 317 | (
308 TyKind::Function(FnPointer { substs: substs1, .. }), 318 TyKind::Function(FnPointer { substitution: FnSubst(substs1), .. }),
309 TyKind::Function(FnPointer { substs: substs2, .. }), 319 TyKind::Function(FnPointer { substitution: FnSubst(substs2), .. }),
310 ) 320 )
311 | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2)) 321 | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2))
312 | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2)) 322 | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2))
@@ -314,9 +324,11 @@ impl InferenceTable {
314 | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => { 324 | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => {
315 self.unify_substs(substs1, substs2, depth + 1) 325 self.unify_substs(substs1, substs2, depth + 1)
316 } 326 }
317 (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))
318 | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2)) 331 | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2))
319 | (TyKind::Array(ty1), TyKind::Array(ty2))
320 | (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),
321 _ => true, /* we checked equals_ctor already */ 333 _ => true, /* we checked equals_ctor already */
322 } 334 }
@@ -327,7 +339,7 @@ impl InferenceTable {
327 339
328 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 {
329 match (ty1.kind(&Interner), ty2.kind(&Interner)) { 341 match (ty1.kind(&Interner), ty2.kind(&Interner)) {
330 (TyKind::Unknown, _) | (_, TyKind::Unknown) => true, 342 (TyKind::Error, _) | (_, TyKind::Error) => true,
331 343
332 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, 344 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true,
333 345
@@ -364,8 +376,12 @@ impl InferenceTable {
364 == self.type_variable_table.is_diverging(*tv2) => 376 == self.type_variable_table.is_diverging(*tv2) =>
365 { 377 {
366 // both type vars are unknown since we tried to resolve them 378 // both type vars are unknown since we tried to resolve them
367 if !self.var_unification_table.unioned(tv1.to_inner(), tv2.to_inner()) { 379 if !self
368 self.var_unification_table.union(tv1.to_inner(), tv2.to_inner()); 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));
369 self.revision += 1; 385 self.revision += 1;
370 } 386 }
371 true 387 true
@@ -402,7 +418,7 @@ impl InferenceTable {
402 ) => { 418 ) => {
403 // the type var is unknown since we tried to resolve it 419 // the type var is unknown since we tried to resolve it
404 self.var_unification_table.union_value( 420 self.var_unification_table.union_value(
405 tv.to_inner(), 421 from_inference_var(*tv),
406 TypeVarValue::Known(other.clone().intern(&Interner)), 422 TypeVarValue::Known(other.clone().intern(&Interner)),
407 ); 423 );
408 self.revision += 1; 424 self.revision += 1;
@@ -457,7 +473,7 @@ impl InferenceTable {
457 } 473 }
458 match ty.kind(&Interner) { 474 match ty.kind(&Interner) {
459 TyKind::InferenceVar(tv, _) => { 475 TyKind::InferenceVar(tv, _) => {
460 let inner = tv.to_inner(); 476 let inner = from_inference_var(*tv);
461 match self.var_unification_table.inlined_probe_value(inner).known() { 477 match self.var_unification_table.inlined_probe_value(inner).known() {
462 Some(known_ty) => { 478 Some(known_ty) => {
463 // The known_ty can't be a type var itself 479 // The known_ty can't be a type var itself
@@ -478,55 +494,63 @@ impl InferenceTable {
478 /// 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
479 /// known type. 495 /// known type.
480 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 {
481 ty.fold(&mut |ty| match ty.kind(&Interner) { 497 fold_tys(
482 &TyKind::InferenceVar(tv, kind) => { 498 ty,
483 let inner = tv.to_inner(); 499 |ty, _| match ty.kind(&Interner) {
484 if tv_stack.contains(&inner) { 500 &TyKind::InferenceVar(tv, kind) => {
485 cov_mark::hit!(type_var_cycles_resolve_as_possible); 501 let inner = from_inference_var(tv);
486 // recursive type 502 if tv_stack.contains(&inner) {
487 return self.type_variable_table.fallback_value(tv, kind); 503 cov_mark::hit!(type_var_cycles_resolve_as_possible);
488 } 504 // recursive type
489 if let Some(known_ty) = 505 return self.type_variable_table.fallback_value(tv, kind);
490 self.var_unification_table.inlined_probe_value(inner).known() 506 }
491 { 507 if let Some(known_ty) =
492 // known_ty may contain other variables that are known by now 508 self.var_unification_table.inlined_probe_value(inner).known()
493 tv_stack.push(inner); 509 {
494 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
495 tv_stack.pop(); 511 tv_stack.push(inner);
496 result 512 let result = self.resolve_ty_as_possible_inner(tv_stack, known_ty.clone());
497 } else { 513 tv_stack.pop();
498 ty 514 result
515 } else {
516 ty
517 }
499 } 518 }
500 } 519 _ => ty,
501 _ => ty, 520 },
502 }) 521 DebruijnIndex::INNERMOST,
522 )
503 } 523 }
504 524
505 /// Resolves the type completely; type variables without known type are 525 /// Resolves the type completely; type variables without known type are
506 /// replaced by TyKind::Unknown. 526 /// replaced by TyKind::Unknown.
507 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 {
508 ty.fold(&mut |ty| match ty.kind(&Interner) { 528 fold_tys(
509 &TyKind::InferenceVar(tv, kind) => { 529 ty,
510 let inner = tv.to_inner(); 530 |ty, _| match ty.kind(&Interner) {
511 if tv_stack.contains(&inner) { 531 &TyKind::InferenceVar(tv, kind) => {
512 cov_mark::hit!(type_var_cycles_resolve_completely); 532 let inner = from_inference_var(tv);
513 // recursive type 533 if tv_stack.contains(&inner) {
514 return self.type_variable_table.fallback_value(tv, kind); 534 cov_mark::hit!(type_var_cycles_resolve_completely);
515 } 535 // recursive type
516 if let Some(known_ty) = 536 return self.type_variable_table.fallback_value(tv, kind);
517 self.var_unification_table.inlined_probe_value(inner).known() 537 }
518 { 538 if let Some(known_ty) =
519 // known_ty may contain other variables that are known by now 539 self.var_unification_table.inlined_probe_value(inner).known()
520 tv_stack.push(inner); 540 {
521 let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone()); 541 // known_ty may contain other variables that are known by now
522 tv_stack.pop(); 542 tv_stack.push(inner);
523 result 543 let result = self.resolve_ty_completely_inner(tv_stack, known_ty.clone());
524 } else { 544 tv_stack.pop();
525 self.type_variable_table.fallback_value(tv, kind) 545 result
546 } else {
547 self.type_variable_table.fallback_value(tv, kind)
548 }
526 } 549 }
527 } 550 _ => ty,
528 _ => ty, 551 },
529 }) 552 DebruijnIndex::INNERMOST,
553 )
530 } 554 }
531} 555}
532 556
@@ -550,6 +574,14 @@ impl UnifyKey for TypeVarId {
550 } 574 }
551} 575}
552 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
553/// 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
554/// know it yet. 586/// know it yet.
555#[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 a8c87eadf..0505fa4ae 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -1,65 +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;
10pub mod traits;
11pub mod method_resolution;
12mod op;
13mod lower;
14pub(crate) mod infer;
15pub(crate) mod utils;
16mod chalk_cast;
17mod chalk_ext;
18mod builder; 10mod builder;
19 11mod chalk_db;
20pub mod display; 12mod chalk_ext;
13mod infer;
14mod interner;
15mod lower;
16mod mapping;
17mod op;
18mod tls;
19mod utils;
20mod walk;
21pub mod db; 21pub mod db;
22pub mod diagnostics; 22pub mod diagnostics;
23pub mod display;
24pub mod method_resolution;
25pub mod primitive;
26pub mod traits;
23 27
24#[cfg(test)] 28#[cfg(test)]
25mod tests; 29mod tests;
26#[cfg(test)] 30#[cfg(test)]
27mod test_db; 31mod test_db;
28 32
29use std::{mem, sync::Arc}; 33use std::sync::Arc;
30
31use chalk_ir::cast::{CastTo, Caster};
32use itertools::Itertools;
33use smallvec::SmallVec;
34 34
35use base_db::salsa; 35use chalk_ir::{
36use hir_def::{ 36 fold::{Fold, Shift},
37 expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId, GenericDefId, HasModule, 37 interner::HasInterner,
38 LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, 38 UintTy,
39}; 39};
40use hir_def::{expr::ExprId, type_ref::Rawness, TypeParamId};
40 41
41use crate::{ 42use crate::{db::HirDatabase, display::HirDisplay, utils::generics};
42 db::HirDatabase,
43 display::HirDisplay,
44 utils::{generics, make_mut_slice},
45};
46 43
47pub use autoderef::autoderef; 44pub use autoderef::autoderef;
48pub use builder::TyBuilder; 45pub use builder::TyBuilder;
49pub use chalk_ext::TyExt; 46pub use chalk_ext::*;
50pub use infer::{could_unify, InferenceResult, InferenceVar}; 47pub use infer::{could_unify, InferenceResult};
48pub use interner::Interner;
51pub use lower::{ 49pub use lower::{
52 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, 50 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
53 TyDefId, TyLoweringContext, ValueTyDefId, 51 TyDefId, TyLoweringContext, ValueTyDefId,
54}; 52};
55pub 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;
56 61
57pub use chalk_ir::{ 62pub use chalk_ir::{
58 cast::Cast, AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind, 63 cast::Cast, AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind,
59}; 64};
60 65
61pub use crate::traits::chalk::Interner;
62
63pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>; 66pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>;
64pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>; 67pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
65pub type FnDefId = chalk_ir::FnDefId<Interner>; 68pub type FnDefId = chalk_ir::FnDefId<Interner>;
@@ -67,401 +70,56 @@ pub type ClosureId = chalk_ir::ClosureId<Interner>;
67pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; 70pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
68pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; 71pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
69 72
73pub type VariableKind = chalk_ir::VariableKind<Interner>;
74pub type VariableKinds = chalk_ir::VariableKinds<Interner>;
70pub 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>;
71 100
72pub type ChalkTraitId = chalk_ir::TraitId<Interner>; 101pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
73 102pub type TraitRef = chalk_ir::TraitRef<Interner>;
74#[derive(Clone, PartialEq, Eq, Debug, Hash)] 103pub type QuantifiedWhereClause = Binders<WhereClause>;
75pub enum Lifetime { 104pub type QuantifiedWhereClauses = chalk_ir::QuantifiedWhereClauses<Interner>;
76 Parameter(LifetimeParamId), 105pub type Canonical<T> = chalk_ir::Canonical<T>;
77 Static,
78}
79
80#[derive(Clone, PartialEq, Eq, Debug, Hash)]
81pub struct OpaqueTy {
82 pub opaque_ty_id: OpaqueTyId,
83 pub substitution: Substitution,
84}
85
86impl TypeWalk for OpaqueTy {
87 fn walk(&self, f: &mut impl FnMut(&Ty)) {
88 self.substitution.walk(f);
89 }
90
91 fn walk_mut_binders(
92 &mut self,
93 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
94 binders: DebruijnIndex,
95 ) {
96 self.substitution.walk_mut_binders(f, binders);
97 }
98}
99
100/// A "projection" type corresponds to an (unnormalized)
101/// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
102/// trait and all its parameters are fully known.
103#[derive(Clone, PartialEq, Eq, Debug, Hash)]
104pub struct ProjectionTy {
105 pub associated_ty_id: AssocTypeId,
106 pub substitution: Substitution,
107}
108
109impl ProjectionTy {
110 pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
111 TraitRef {
112 trait_id: to_chalk_trait_id(self.trait_(db)),
113 substitution: self.substitution.clone(),
114 }
115 }
116
117 pub fn self_type_parameter(&self) -> &Ty {
118 &self.substitution.interned(&Interner)[0].assert_ty_ref(&Interner)
119 }
120
121 fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
122 match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container {
123 AssocContainerId::TraitId(it) => it,
124 _ => panic!("projection ty without parent trait"),
125 }
126 }
127}
128
129impl TypeWalk for ProjectionTy {
130 fn walk(&self, f: &mut impl FnMut(&Ty)) {
131 self.substitution.walk(f);
132 }
133
134 fn walk_mut_binders(
135 &mut self,
136 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
137 binders: DebruijnIndex,
138 ) {
139 self.substitution.walk_mut_binders(f, binders);
140 }
141}
142
143#[derive(Clone, PartialEq, Eq, Debug, Hash)]
144pub struct DynTy {
145 /// The unknown self type.
146 pub bounds: Binders<QuantifiedWhereClauses>,
147}
148 106
149pub type FnSig = chalk_ir::FnSig<Interner>; 107pub type FnSig = chalk_ir::FnSig<Interner>;
150 108
151#[derive(Clone, PartialEq, Eq, Debug, Hash)] 109pub type InEnvironment<T> = chalk_ir::InEnvironment<T>;
152pub struct FnPointer { 110pub type DomainGoal = chalk_ir::DomainGoal<Interner>;
153 pub num_args: usize, 111pub type AliasEq = chalk_ir::AliasEq<Interner>;
154 pub sig: FnSig, 112pub type Solution = chalk_solve::Solution<Interner>;
155 pub substs: Substitution, 113pub type ConstrainedSubst = chalk_ir::ConstrainedSubst<Interner>;
156} 114pub type Guidance = chalk_solve::Guidance<Interner>;
157 115pub type WhereClause = chalk_ir::WhereClause<Interner>;
158#[derive(Clone, PartialEq, Eq, Debug, Hash)]
159pub enum AliasTy {
160 /// A "projection" type corresponds to an (unnormalized)
161 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
162 /// trait and all its parameters are fully known.
163 Projection(ProjectionTy),
164 /// An opaque type (`impl Trait`).
165 ///
166 /// This is currently only used for return type impl trait; each instance of
167 /// `impl Trait` in a return type gets its own ID.
168 Opaque(OpaqueTy),
169}
170
171impl TypeWalk for AliasTy {
172 fn walk(&self, f: &mut impl FnMut(&Ty)) {
173 match self {
174 AliasTy::Projection(it) => it.walk(f),
175 AliasTy::Opaque(it) => it.walk(f),
176 }
177 }
178 116
179 fn walk_mut_binders( 117// FIXME: get rid of this
180 &mut self, 118pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution {
181 f: &mut impl FnMut(&mut Ty, DebruijnIndex), 119 Substitution::from_iter(
182 binders: DebruijnIndex, 120 &Interner,
183 ) { 121 s.as_slice(&Interner)[..std::cmp::min(s.len(&Interner), n)].iter().cloned(),
184 match self { 122 )
185 AliasTy::Projection(it) => it.walk_mut_binders(f, binders),
186 AliasTy::Opaque(it) => it.walk_mut_binders(f, binders),
187 }
188 }
189}
190/// A type.
191///
192/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
193/// the same thing (but in a different way).
194///
195/// This should be cheap to clone.
196#[derive(Clone, PartialEq, Eq, Debug, Hash)]
197pub enum TyKind {
198 /// Structures, enumerations and unions.
199 Adt(AdtId<Interner>, Substitution),
200
201 /// Represents an associated item like `Iterator::Item`. This is used
202 /// when we have tried to normalize a projection like `T::Item` but
203 /// couldn't find a better representation. In that case, we generate
204 /// an **application type** like `(Iterator::Item)<T>`.
205 AssociatedType(AssocTypeId, Substitution),
206
207 /// a scalar type like `bool` or `u32`
208 Scalar(Scalar),
209
210 /// A tuple type. For example, `(i32, bool)`.
211 Tuple(usize, Substitution),
212
213 /// An array with the given length. Written as `[T; n]`.
214 Array(Ty),
215
216 /// The pointee of an array slice. Written as `[T]`.
217 Slice(Ty),
218
219 /// A raw pointer. Written as `*mut T` or `*const T`
220 Raw(Mutability, Ty),
221
222 /// A reference; a pointer with an associated lifetime. Written as
223 /// `&'a mut T` or `&'a T`.
224 Ref(Mutability, Ty),
225
226 /// This represents a placeholder for an opaque type in situations where we
227 /// don't know the hidden type (i.e. currently almost always). This is
228 /// analogous to the `AssociatedType` type constructor.
229 /// It is also used as the type of async block, with one type parameter
230 /// representing the Future::Output type.
231 OpaqueType(OpaqueTyId, Substitution),
232
233 /// The anonymous type of a function declaration/definition. Each
234 /// function has a unique type, which is output (for a function
235 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
236 ///
237 /// This includes tuple struct / enum variant constructors as well.
238 ///
239 /// For example the type of `bar` here:
240 ///
241 /// ```
242 /// fn foo() -> i32 { 1 }
243 /// let bar = foo; // bar: fn() -> i32 {foo}
244 /// ```
245 FnDef(FnDefId, Substitution),
246
247 /// The pointee of a string slice. Written as `str`.
248 Str,
249
250 /// The never type `!`.
251 Never,
252
253 /// The type of a specific closure.
254 ///
255 /// The closure signature is stored in a `FnPtr` type in the first type
256 /// parameter.
257 Closure(ClosureId, Substitution),
258
259 /// Represents a foreign type declared in external blocks.
260 ForeignType(ForeignDefId),
261
262 /// A pointer to a function. Written as `fn() -> i32`.
263 ///
264 /// For example the type of `bar` here:
265 ///
266 /// ```
267 /// fn foo() -> i32 { 1 }
268 /// let bar: fn() -> i32 = foo;
269 /// ```
270 Function(FnPointer),
271
272 /// An "alias" type represents some form of type alias, such as:
273 /// - An associated type projection like `<T as Iterator>::Item`
274 /// - `impl Trait` types
275 /// - Named type aliases like `type Foo<X> = Vec<X>`
276 Alias(AliasTy),
277
278 /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T)
279 /// {}` when we're type-checking the body of that function. In this
280 /// situation, we know this stands for *some* type, but don't know the exact
281 /// type.
282 Placeholder(PlaceholderIndex),
283
284 /// A bound type variable. This is used in various places: when representing
285 /// some polymorphic type like the type of function `fn f<T>`, the type
286 /// parameters get turned into variables; during trait resolution, inference
287 /// variables get turned into bound variables and back; and in `Dyn` the
288 /// `Self` type is represented with a bound variable as well.
289 BoundVar(BoundVar),
290
291 /// A type variable used during type checking.
292 InferenceVar(InferenceVar, TyVariableKind),
293
294 /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust).
295 ///
296 /// The predicates are quantified over the `Self` type, i.e. `Ty::Bound(0)`
297 /// represents the `Self` type inside the bounds. This is currently
298 /// implicit; Chalk has the `Binders` struct to make it explicit, but it
299 /// didn't seem worth the overhead yet.
300 Dyn(DynTy),
301
302 /// A placeholder for a type which could not be computed; this is propagated
303 /// to avoid useless error messages. Doubles as a placeholder where type
304 /// variables are inserted before type checking, since we want to try to
305 /// infer a better type here anyway -- for the IDE use case, we want to try
306 /// to infer as much as possible even in the presence of type errors.
307 Unknown,
308}
309
310#[derive(Clone, PartialEq, Eq, Debug, Hash)]
311pub struct Ty(Arc<TyKind>);
312
313impl TyKind {
314 pub fn intern(self, _interner: &Interner) -> Ty {
315 Ty(Arc::new(self))
316 }
317}
318
319impl Ty {
320 pub fn kind(&self, _interner: &Interner) -> &TyKind {
321 &self.0
322 }
323
324 pub fn interned_mut(&mut self) -> &mut TyKind {
325 Arc::make_mut(&mut self.0)
326 }
327
328 pub fn into_inner(self) -> TyKind {
329 Arc::try_unwrap(self.0).unwrap_or_else(|a| (*a).clone())
330 }
331}
332
333#[derive(Clone, PartialEq, Eq, Debug, Hash)]
334pub struct GenericArg {
335 interned: GenericArgData,
336}
337
338#[derive(Clone, PartialEq, Eq, Debug, Hash)]
339pub enum GenericArgData {
340 Ty(Ty),
341}
342
343impl GenericArg {
344 /// Constructs a generic argument using `GenericArgData`.
345 pub fn new(_interner: &Interner, data: GenericArgData) -> Self {
346 GenericArg { interned: data }
347 }
348
349 /// Gets the interned value.
350 pub fn interned(&self) -> &GenericArgData {
351 &self.interned
352 }
353
354 /// Asserts that this is a type argument.
355 pub fn assert_ty_ref(&self, interner: &Interner) -> &Ty {
356 self.ty(interner).unwrap()
357 }
358
359 /// Checks whether the generic argument is a type.
360 pub fn is_ty(&self, _interner: &Interner) -> bool {
361 match self.interned() {
362 GenericArgData::Ty(_) => true,
363 }
364 }
365
366 /// Returns the type if it is one, `None` otherwise.
367 pub fn ty(&self, _interner: &Interner) -> Option<&Ty> {
368 match self.interned() {
369 GenericArgData::Ty(t) => Some(t),
370 }
371 }
372}
373
374impl TypeWalk for GenericArg {
375 fn walk(&self, f: &mut impl FnMut(&Ty)) {
376 match &self.interned {
377 GenericArgData::Ty(ty) => {
378 ty.walk(f);
379 }
380 }
381 }
382
383 fn walk_mut_binders(
384 &mut self,
385 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
386 binders: DebruijnIndex,
387 ) {
388 match &mut self.interned {
389 GenericArgData::Ty(ty) => {
390 ty.walk_mut_binders(f, binders);
391 }
392 }
393 }
394}
395
396/// A list of substitutions for generic parameters.
397#[derive(Clone, PartialEq, Eq, Debug, Hash)]
398pub struct Substitution(SmallVec<[GenericArg; 2]>);
399
400impl TypeWalk for Substitution {
401 fn walk(&self, f: &mut impl FnMut(&Ty)) {
402 for t in self.0.iter() {
403 t.walk(f);
404 }
405 }
406
407 fn walk_mut_binders(
408 &mut self,
409 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
410 binders: DebruijnIndex,
411 ) {
412 for t in &mut self.0 {
413 t.walk_mut_binders(f, binders);
414 }
415 }
416}
417
418impl Substitution {
419 pub fn interned(&self, _: &Interner) -> &[GenericArg] {
420 &self.0
421 }
422
423 pub fn len(&self, _: &Interner) -> usize {
424 self.0.len()
425 }
426
427 pub fn is_empty(&self, _: &Interner) -> bool {
428 self.0.is_empty()
429 }
430
431 pub fn at(&self, _: &Interner, i: usize) -> &GenericArg {
432 &self.0[i]
433 }
434
435 pub fn empty(_: &Interner) -> Substitution {
436 Substitution(SmallVec::new())
437 }
438
439 pub fn iter(&self, _: &Interner) -> std::slice::Iter<'_, GenericArg> {
440 self.0.iter()
441 }
442
443 pub fn single(ty: Ty) -> Substitution {
444 Substitution({
445 let mut v = SmallVec::new();
446 v.push(ty.cast(&Interner));
447 v
448 })
449 }
450
451 pub fn prefix(&self, n: usize) -> Substitution {
452 Substitution(self.0[..std::cmp::min(self.0.len(), n)].into())
453 }
454
455 pub fn suffix(&self, n: usize) -> Substitution {
456 Substitution(self.0[self.0.len() - std::cmp::min(self.0.len(), n)..].into())
457 }
458
459 pub fn from_iter(
460 interner: &Interner,
461 elements: impl IntoIterator<Item = impl CastTo<GenericArg>>,
462 ) -> Self {
463 Substitution(elements.into_iter().casted(interner).collect())
464 }
465} 123}
466 124
467/// 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.
@@ -469,190 +127,39 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> {
469 generics(db.upcast(), id.parent).param_idx(id) 127 generics(db.upcast(), id.parent).param_idx(id)
470} 128}
471 129
472#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] 130pub(crate) fn wrap_empty_binders<T>(value: T) -> Binders<T>
473pub struct Binders<T> { 131where
474 pub num_binders: usize, 132 T: Fold<Interner, Result = T> + HasInterner<Interner = Interner>,
475 pub value: T, 133{
476} 134 Binders::empty(&Interner, value.shifted_in_from(&Interner, DebruijnIndex::ONE))
477 135}
478impl<T> Binders<T> { 136
479 pub fn new(num_binders: usize, value: T) -> Self { 137pub(crate) fn make_only_type_binders<T: HasInterner<Interner = Interner>>(
480 Self { num_binders, value } 138 num_vars: usize,
481 } 139 value: T,
482 140) -> Binders<T> {
483 pub fn wrap_empty(value: T) -> Self 141 Binders::new(
484 where 142 VariableKinds::from_iter(
485 T: TypeWalk, 143 &Interner,
486 { 144 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
487 Self { num_binders: 0, value: value.shift_bound_vars(DebruijnIndex::ONE) } 145 .take(num_vars),
488 } 146 ),
489 147 value,
490 pub fn as_ref(&self) -> Binders<&T> { 148 )
491 Binders { num_binders: self.num_binders, value: &self.value } 149}
492 } 150
493 151// FIXME: get rid of this
494 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binders<U> { 152pub fn make_canonical<T: HasInterner<Interner = Interner>>(
495 Binders { num_binders: self.num_binders, value: f(self.value) } 153 value: T,
496 } 154 kinds: impl IntoIterator<Item = TyVariableKind>,
497 155) -> Canonical<T> {
498 pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> { 156 let kinds = kinds.into_iter().map(|tk| {
499 Some(Binders { num_binders: self.num_binders, value: f(self.value)? }) 157 chalk_ir::CanonicalVarKind::new(
500 } 158 chalk_ir::VariableKind::Ty(tk),
501 159 chalk_ir::UniverseIndex::ROOT,
502 pub fn skip_binders(&self) -> &T { 160 )
503 &self.value 161 });
504 } 162 Canonical { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) }
505
506 pub fn into_value_and_skipped_binders(self) -> (T, usize) {
507 (self.value, self.num_binders)
508 }
509}
510
511impl<T: Clone> Binders<&T> {
512 pub fn cloned(&self) -> Binders<T> {
513 Binders { num_binders: self.num_binders, value: self.value.clone() }
514 }
515}
516
517impl<T: TypeWalk> Binders<T> {
518 /// Substitutes all variables.
519 pub fn subst(self, subst: &Substitution) -> T {
520 assert_eq!(subst.len(&Interner), self.num_binders);
521 self.value.subst_bound_vars(subst)
522 }
523}
524
525impl<T: TypeWalk> TypeWalk for Binders<T> {
526 fn walk(&self, f: &mut impl FnMut(&Ty)) {
527 self.value.walk(f);
528 }
529
530 fn walk_mut_binders(
531 &mut self,
532 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
533 binders: DebruijnIndex,
534 ) {
535 self.value.walk_mut_binders(f, binders.shifted_in())
536 }
537}
538
539/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.
540#[derive(Clone, PartialEq, Eq, Debug, Hash)]
541pub struct TraitRef {
542 pub trait_id: ChalkTraitId,
543 pub substitution: Substitution,
544}
545
546impl TraitRef {
547 pub fn self_type_parameter(&self) -> &Ty {
548 &self.substitution.at(&Interner, 0).assert_ty_ref(&Interner)
549 }
550
551 pub fn hir_trait_id(&self) -> TraitId {
552 from_chalk_trait_id(self.trait_id)
553 }
554}
555
556impl TypeWalk for TraitRef {
557 fn walk(&self, f: &mut impl FnMut(&Ty)) {
558 self.substitution.walk(f);
559 }
560
561 fn walk_mut_binders(
562 &mut self,
563 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
564 binders: DebruijnIndex,
565 ) {
566 self.substitution.walk_mut_binders(f, binders);
567 }
568}
569
570/// Like `generics::WherePredicate`, but with resolved types: A condition on the
571/// parameters of a generic item.
572#[derive(Debug, Clone, PartialEq, Eq, Hash)]
573pub enum WhereClause {
574 /// The given trait needs to be implemented for its type parameters.
575 Implemented(TraitRef),
576 /// An associated type bindings like in `Iterator<Item = T>`.
577 AliasEq(AliasEq),
578}
579
580impl WhereClause {
581 pub fn is_implemented(&self) -> bool {
582 matches!(self, WhereClause::Implemented(_))
583 }
584
585 pub fn trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> {
586 match self {
587 WhereClause::Implemented(tr) => Some(tr.clone()),
588 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(proj), .. }) => {
589 Some(proj.trait_ref(db))
590 }
591 WhereClause::AliasEq(_) => None,
592 }
593 }
594}
595
596impl TypeWalk for WhereClause {
597 fn walk(&self, f: &mut impl FnMut(&Ty)) {
598 match self {
599 WhereClause::Implemented(trait_ref) => trait_ref.walk(f),
600 WhereClause::AliasEq(alias_eq) => alias_eq.walk(f),
601 }
602 }
603
604 fn walk_mut_binders(
605 &mut self,
606 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
607 binders: DebruijnIndex,
608 ) {
609 match self {
610 WhereClause::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders),
611 WhereClause::AliasEq(alias_eq) => alias_eq.walk_mut_binders(f, binders),
612 }
613 }
614}
615
616pub type QuantifiedWhereClause = Binders<WhereClause>;
617
618#[derive(Debug, Clone, PartialEq, Eq, Hash)]
619pub struct QuantifiedWhereClauses(Arc<[QuantifiedWhereClause]>);
620
621impl QuantifiedWhereClauses {
622 pub fn from_iter(
623 _interner: &Interner,
624 elements: impl IntoIterator<Item = QuantifiedWhereClause>,
625 ) -> Self {
626 QuantifiedWhereClauses(elements.into_iter().collect())
627 }
628
629 pub fn interned(&self) -> &Arc<[QuantifiedWhereClause]> {
630 &self.0
631 }
632}
633
634/// Basically a claim (currently not validated / checked) that the contained
635/// type / trait ref contains no inference variables; any inference variables it
636/// contained have been replaced by bound variables, and `kinds` tells us how
637/// many there are and whether they were normal or float/int variables. This is
638/// used to erase irrelevant differences between types before using them in
639/// queries.
640#[derive(Debug, Clone, PartialEq, Eq, Hash)]
641pub struct Canonical<T> {
642 pub value: T,
643 pub binders: CanonicalVarKinds,
644}
645
646impl<T> Canonical<T> {
647 pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self {
648 let kinds = kinds.into_iter().map(|tk| {
649 chalk_ir::CanonicalVarKind::new(
650 chalk_ir::VariableKind::Ty(tk),
651 chalk_ir::UniverseIndex::ROOT,
652 )
653 });
654 Self { value, binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds) }
655 }
656} 163}
657 164
658/// 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
@@ -663,6 +170,8 @@ pub struct CallableSig {
663 is_varargs: bool, 170 is_varargs: bool,
664} 171}
665 172
173has_interner!(CallableSig);
174
666/// A polymorphic function signature. 175/// A polymorphic function signature.
667pub type PolyFnSig = Binders<CallableSig>; 176pub type PolyFnSig = Binders<CallableSig>;
668 177
@@ -676,10 +185,12 @@ impl CallableSig {
676 CallableSig { 185 CallableSig {
677 // FIXME: what to do about lifetime params? -> return PolyFnSig 186 // FIXME: what to do about lifetime params? -> return PolyFnSig
678 params_and_return: fn_ptr 187 params_and_return: fn_ptr
679 .substs 188 .substitution
680 .clone() 189 .clone()
681 .shift_bound_vars_out(DebruijnIndex::ONE) 190 .shifted_out_to(&Interner, DebruijnIndex::ONE)
682 .interned(&Interner) 191 .expect("unexpected lifetime vars in fn ptr")
192 .0
193 .as_slice(&Interner)
683 .iter() 194 .iter()
684 .map(|arg| arg.assert_ty_ref(&Interner).clone()) 195 .map(|arg| arg.assert_ty_ref(&Interner).clone())
685 .collect(), 196 .collect(),
@@ -696,485 +207,20 @@ impl CallableSig {
696 } 207 }
697} 208}
698 209
699impl TypeWalk for CallableSig { 210impl Fold<Interner> for CallableSig {
700 fn walk(&self, f: &mut impl FnMut(&Ty)) { 211 type Result = CallableSig;
701 for t in self.params_and_return.iter() {
702 t.walk(f);
703 }
704 }
705
706 fn walk_mut_binders(
707 &mut self,
708 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
709 binders: DebruijnIndex,
710 ) {
711 for t in make_mut_slice(&mut self.params_and_return) {
712 t.walk_mut_binders(f, binders);
713 }
714 }
715}
716
717impl Ty {
718 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
719 match self.kind(&Interner) {
720 TyKind::Ref(mutability, ty) => Some((ty, *mutability)),
721 _ => None,
722 }
723 }
724
725 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
726 match self.kind(&Interner) {
727 TyKind::Ref(mutability, ty) => Some((ty, Rawness::Ref, *mutability)),
728 TyKind::Raw(mutability, ty) => Some((ty, Rawness::RawPtr, *mutability)),
729 _ => None,
730 }
731 }
732
733 pub fn strip_references(&self) -> &Ty {
734 let mut t: &Ty = self;
735
736 while let TyKind::Ref(_mutability, ty) = t.kind(&Interner) {
737 t = ty;
738 }
739
740 t
741 }
742
743 pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)> {
744 match self.kind(&Interner) {
745 TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),
746 _ => None,
747 }
748 }
749
750 pub fn as_tuple(&self) -> Option<&Substitution> {
751 match self.kind(&Interner) {
752 TyKind::Tuple(_, substs) => Some(substs),
753 _ => None,
754 }
755 }
756
757 pub fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId> {
758 match *self.kind(&Interner) {
759 TyKind::Adt(AdtId(adt), ..) => Some(adt.into()),
760 TyKind::FnDef(callable, ..) => {
761 Some(db.lookup_intern_callable_def(callable.into()).into())
762 }
763 TyKind::AssociatedType(type_alias, ..) => Some(from_assoc_type_id(type_alias).into()),
764 TyKind::ForeignType(type_alias, ..) => Some(from_foreign_def_id(type_alias).into()),
765 _ => None,
766 }
767 }
768
769 pub fn is_never(&self) -> bool {
770 matches!(self.kind(&Interner), TyKind::Never)
771 }
772
773 pub fn is_unknown(&self) -> bool {
774 matches!(self.kind(&Interner), TyKind::Unknown)
775 }
776
777 pub fn equals_ctor(&self, other: &Ty) -> bool {
778 match (self.kind(&Interner), other.kind(&Interner)) {
779 (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2,
780 (TyKind::Slice(_), TyKind::Slice(_)) | (TyKind::Array(_), TyKind::Array(_)) => true,
781 (TyKind::FnDef(def_id, ..), TyKind::FnDef(def_id2, ..)) => def_id == def_id2,
782 (TyKind::OpaqueType(ty_id, ..), TyKind::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
783 (TyKind::AssociatedType(ty_id, ..), TyKind::AssociatedType(ty_id2, ..)) => {
784 ty_id == ty_id2
785 }
786 (TyKind::ForeignType(ty_id, ..), TyKind::ForeignType(ty_id2, ..)) => ty_id == ty_id2,
787 (TyKind::Closure(id1, _), TyKind::Closure(id2, _)) => id1 == id2,
788 (TyKind::Ref(mutability, ..), TyKind::Ref(mutability2, ..))
789 | (TyKind::Raw(mutability, ..), TyKind::Raw(mutability2, ..)) => {
790 mutability == mutability2
791 }
792 (
793 TyKind::Function(FnPointer { num_args, sig, .. }),
794 TyKind::Function(FnPointer { num_args: num_args2, sig: sig2, .. }),
795 ) => num_args == num_args2 && sig == sig2,
796 (TyKind::Tuple(cardinality, _), TyKind::Tuple(cardinality2, _)) => {
797 cardinality == cardinality2
798 }
799 (TyKind::Str, TyKind::Str) | (TyKind::Never, TyKind::Never) => true,
800 (TyKind::Scalar(scalar), TyKind::Scalar(scalar2)) => scalar == scalar2,
801 _ => false,
802 }
803 }
804
805 /// If this is a `dyn Trait` type, this returns the `Trait` part.
806 fn dyn_trait_ref(&self) -> Option<&TraitRef> {
807 match self.kind(&Interner) {
808 TyKind::Dyn(dyn_ty) => {
809 dyn_ty.bounds.value.interned().get(0).and_then(|b| match b.skip_binders() {
810 WhereClause::Implemented(trait_ref) => Some(trait_ref),
811 _ => None,
812 })
813 }
814 _ => None,
815 }
816 }
817
818 /// If this is a `dyn Trait`, returns that trait.
819 pub fn dyn_trait(&self) -> Option<TraitId> {
820 self.dyn_trait_ref().map(|it| it.trait_id).map(from_chalk_trait_id)
821 }
822
823 fn builtin_deref(&self) -> Option<Ty> {
824 match self.kind(&Interner) {
825 TyKind::Ref(.., ty) => Some(ty.clone()),
826 TyKind::Raw(.., ty) => Some(ty.clone()),
827 _ => None,
828 }
829 }
830
831 pub fn callable_def(&self, db: &dyn HirDatabase) -> Option<CallableDefId> {
832 match self.kind(&Interner) {
833 &TyKind::FnDef(def, ..) => Some(db.lookup_intern_callable_def(def.into())),
834 _ => None,
835 }
836 }
837
838 pub fn as_fn_def(&self, db: &dyn HirDatabase) -> Option<FunctionId> {
839 if let Some(CallableDefId::FunctionId(func)) = self.callable_def(db) {
840 Some(func)
841 } else {
842 None
843 }
844 }
845
846 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
847 match self.kind(&Interner) {
848 TyKind::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
849 TyKind::FnDef(def, parameters) => {
850 let callable_def = db.lookup_intern_callable_def((*def).into());
851 let sig = db.callable_item_signature(callable_def);
852 Some(sig.subst(&parameters))
853 }
854 TyKind::Closure(.., substs) => {
855 let sig_param = substs.at(&Interner, 0).assert_ty_ref(&Interner);
856 sig_param.callable_sig(db)
857 }
858 _ => None,
859 }
860 }
861
862 /// Returns the type parameters of this type if it has some (i.e. is an ADT
863 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
864 pub fn substs(&self) -> Option<&Substitution> {
865 match self.kind(&Interner) {
866 TyKind::Adt(_, substs)
867 | TyKind::FnDef(_, substs)
868 | TyKind::Function(FnPointer { substs, .. })
869 | TyKind::Tuple(_, substs)
870 | TyKind::OpaqueType(_, substs)
871 | TyKind::AssociatedType(_, substs)
872 | TyKind::Closure(.., substs) => Some(substs),
873 _ => None,
874 }
875 }
876
877 fn substs_mut(&mut self) -> Option<&mut Substitution> {
878 match self.interned_mut() {
879 TyKind::Adt(_, substs)
880 | TyKind::FnDef(_, substs)
881 | TyKind::Function(FnPointer { substs, .. })
882 | TyKind::Tuple(_, substs)
883 | TyKind::OpaqueType(_, substs)
884 | TyKind::AssociatedType(_, substs)
885 | TyKind::Closure(.., substs) => Some(substs),
886 _ => None,
887 }
888 }
889
890 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> {
891 match self.kind(&Interner) {
892 TyKind::OpaqueType(opaque_ty_id, ..) => {
893 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
894 ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
895 let krate = def.module(db.upcast()).krate();
896 if let Some(future_trait) = db
897 .lang_item(krate, "future_trait".into())
898 .and_then(|item| item.as_trait())
899 {
900 // This is only used by type walking.
901 // Parameters will be walked outside, and projection predicate is not used.
902 // So just provide the Future trait.
903 let impl_bound = Binders::new(
904 0,
905 WhereClause::Implemented(TraitRef {
906 trait_id: to_chalk_trait_id(future_trait),
907 substitution: Substitution::empty(&Interner),
908 }),
909 );
910 Some(vec![impl_bound])
911 } else {
912 None
913 }
914 }
915 ImplTraitId::ReturnTypeImplTrait(..) => None,
916 }
917 }
918 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
919 let predicates = match db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into())
920 {
921 ImplTraitId::ReturnTypeImplTrait(func, idx) => {
922 db.return_type_impl_traits(func).map(|it| {
923 let data = (*it)
924 .as_ref()
925 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
926 data.subst(&opaque_ty.substitution)
927 })
928 }
929 // It always has an parameter for Future::Output type.
930 ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(),
931 };
932
933 predicates.map(|it| it.value)
934 }
935 TyKind::Placeholder(idx) => {
936 let id = from_placeholder_idx(db, *idx);
937 let generic_params = db.generic_params(id.parent);
938 let param_data = &generic_params.types[id.local_id];
939 match param_data.provenance {
940 hir_def::generics::TypeParamProvenance::ArgumentImplTrait => {
941 let substs = TyBuilder::type_params_subst(db, id.parent);
942 let predicates = db
943 .generic_predicates(id.parent)
944 .into_iter()
945 .map(|pred| pred.clone().subst(&substs))
946 .filter(|wc| match &wc.skip_binders() {
947 WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
948 WhereClause::AliasEq(AliasEq {
949 alias: AliasTy::Projection(proj),
950 ty: _,
951 }) => proj.self_type_parameter() == self,
952 _ => false,
953 })
954 .collect_vec();
955
956 Some(predicates)
957 }
958 _ => None,
959 }
960 }
961 _ => None,
962 }
963 }
964
965 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> {
966 match self.kind(&Interner) {
967 TyKind::AssociatedType(id, ..) => {
968 match from_assoc_type_id(*id).lookup(db.upcast()).container {
969 AssocContainerId::TraitId(trait_id) => Some(trait_id),
970 _ => None,
971 }
972 }
973 TyKind::Alias(AliasTy::Projection(projection_ty)) => {
974 match from_assoc_type_id(projection_ty.associated_ty_id)
975 .lookup(db.upcast())
976 .container
977 {
978 AssocContainerId::TraitId(trait_id) => Some(trait_id),
979 _ => None,
980 }
981 }
982 _ => None,
983 }
984 }
985}
986
987/// This allows walking structures that contain types to do something with those
988/// types, similar to Chalk's `Fold` trait.
989pub trait TypeWalk {
990 fn walk(&self, f: &mut impl FnMut(&Ty));
991 fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
992 self.walk_mut_binders(&mut |ty, _binders| f(ty), DebruijnIndex::INNERMOST);
993 }
994 /// Walk the type, counting entered binders.
995 ///
996 /// `TyKind::Bound` variables use DeBruijn indexing, which means that 0 refers
997 /// to the innermost binder, 1 to the next, etc.. So when we want to
998 /// substitute a certain bound variable, we can't just walk the whole type
999 /// and blindly replace each instance of a certain index; when we 'enter'
1000 /// things that introduce new bound variables, we have to keep track of
1001 /// that. Currently, the only thing that introduces bound variables on our
1002 /// side are `TyKind::Dyn` and `TyKind::Opaque`, which each introduce a bound
1003 /// variable for the self type.
1004 fn walk_mut_binders(
1005 &mut self,
1006 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
1007 binders: DebruijnIndex,
1008 );
1009
1010 fn fold_binders(
1011 mut self,
1012 f: &mut impl FnMut(Ty, DebruijnIndex) -> Ty,
1013 binders: DebruijnIndex,
1014 ) -> Self
1015 where
1016 Self: Sized,
1017 {
1018 self.walk_mut_binders(
1019 &mut |ty_mut, binders| {
1020 let ty = mem::replace(ty_mut, TyKind::Unknown.intern(&Interner));
1021 *ty_mut = f(ty, binders);
1022 },
1023 binders,
1024 );
1025 self
1026 }
1027
1028 fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Self
1029 where
1030 Self: Sized,
1031 {
1032 self.walk_mut(&mut |ty_mut| {
1033 let ty = mem::replace(ty_mut, TyKind::Unknown.intern(&Interner));
1034 *ty_mut = f(ty);
1035 });
1036 self
1037 }
1038 212
1039 /// Substitutes `TyKind::Bound` vars with the given substitution. 213 fn fold_with<'i>(
1040 fn subst_bound_vars(self, substs: &Substitution) -> Self 214 self,
215 folder: &mut dyn chalk_ir::fold::Folder<'i, Interner>,
216 outer_binder: DebruijnIndex,
217 ) -> chalk_ir::Fallible<Self::Result>
1041 where 218 where
1042 Self: Sized, 219 Interner: 'i,
1043 { 220 {
1044 self.subst_bound_vars_at_depth(substs, DebruijnIndex::INNERMOST) 221 let vec = self.params_and_return.to_vec();
1045 } 222 let folded = vec.fold_with(folder, outer_binder)?;
1046 223 Ok(CallableSig { params_and_return: folded.into(), is_varargs: self.is_varargs })
1047 /// Substitutes `TyKind::Bound` vars with the given substitution.
1048 fn subst_bound_vars_at_depth(mut self, substs: &Substitution, depth: DebruijnIndex) -> Self
1049 where
1050 Self: Sized,
1051 {
1052 self.walk_mut_binders(
1053 &mut |ty, binders| {
1054 if let &mut TyKind::BoundVar(bound) = ty.interned_mut() {
1055 if bound.debruijn >= binders {
1056 *ty = substs.0[bound.index]
1057 .assert_ty_ref(&Interner)
1058 .clone()
1059 .shift_bound_vars(binders);
1060 }
1061 }
1062 },
1063 depth,
1064 );
1065 self
1066 }
1067
1068 /// Shifts up debruijn indices of `TyKind::Bound` vars by `n`.
1069 fn shift_bound_vars(self, n: DebruijnIndex) -> Self
1070 where
1071 Self: Sized,
1072 {
1073 self.fold_binders(
1074 &mut |ty, binders| match ty.kind(&Interner) {
1075 TyKind::BoundVar(bound) if bound.debruijn >= binders => {
1076 TyKind::BoundVar(bound.shifted_in_from(n)).intern(&Interner)
1077 }
1078 _ => ty,
1079 },
1080 DebruijnIndex::INNERMOST,
1081 )
1082 }
1083
1084 /// Shifts debruijn indices of `TyKind::Bound` vars out (down) by `n`.
1085 fn shift_bound_vars_out(self, n: DebruijnIndex) -> Self
1086 where
1087 Self: Sized + std::fmt::Debug,
1088 {
1089 self.fold_binders(
1090 &mut |ty, binders| match ty.kind(&Interner) {
1091 TyKind::BoundVar(bound) if bound.debruijn >= binders => {
1092 TyKind::BoundVar(bound.shifted_out_to(n).unwrap_or(bound.clone()))
1093 .intern(&Interner)
1094 }
1095 _ => ty,
1096 },
1097 DebruijnIndex::INNERMOST,
1098 )
1099 }
1100}
1101
1102impl TypeWalk for Ty {
1103 fn walk(&self, f: &mut impl FnMut(&Ty)) {
1104 match self.kind(&Interner) {
1105 TyKind::Alias(AliasTy::Projection(p_ty)) => {
1106 for t in p_ty.substitution.iter(&Interner) {
1107 t.walk(f);
1108 }
1109 }
1110 TyKind::Alias(AliasTy::Opaque(o_ty)) => {
1111 for t in o_ty.substitution.iter(&Interner) {
1112 t.walk(f);
1113 }
1114 }
1115 TyKind::Dyn(dyn_ty) => {
1116 for p in dyn_ty.bounds.value.interned().iter() {
1117 p.walk(f);
1118 }
1119 }
1120 TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => {
1121 ty.walk(f);
1122 }
1123 _ => {
1124 if let Some(substs) = self.substs() {
1125 for t in substs.iter(&Interner) {
1126 t.walk(f);
1127 }
1128 }
1129 }
1130 }
1131 f(self);
1132 }
1133
1134 fn walk_mut_binders(
1135 &mut self,
1136 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
1137 binders: DebruijnIndex,
1138 ) {
1139 match self.interned_mut() {
1140 TyKind::Alias(AliasTy::Projection(p_ty)) => {
1141 p_ty.substitution.walk_mut_binders(f, binders);
1142 }
1143 TyKind::Dyn(dyn_ty) => {
1144 for p in make_mut_slice(&mut dyn_ty.bounds.value.0) {
1145 p.walk_mut_binders(f, binders.shifted_in());
1146 }
1147 }
1148 TyKind::Alias(AliasTy::Opaque(o_ty)) => {
1149 o_ty.substitution.walk_mut_binders(f, binders);
1150 }
1151 TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => {
1152 ty.walk_mut_binders(f, binders);
1153 }
1154 _ => {
1155 if let Some(substs) = self.substs_mut() {
1156 substs.walk_mut_binders(f, binders);
1157 }
1158 }
1159 }
1160 f(self, binders);
1161 }
1162}
1163
1164impl<T: TypeWalk> TypeWalk for Vec<T> {
1165 fn walk(&self, f: &mut impl FnMut(&Ty)) {
1166 for t in self {
1167 t.walk(f);
1168 }
1169 }
1170 fn walk_mut_binders(
1171 &mut self,
1172 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
1173 binders: DebruijnIndex,
1174 ) {
1175 for t in self {
1176 t.walk_mut_binders(f, binders);
1177 }
1178 } 224 }
1179} 225}
1180 226
@@ -1189,45 +235,75 @@ pub struct ReturnTypeImplTraits {
1189 pub(crate) impl_traits: Vec<ReturnTypeImplTrait>, 235 pub(crate) impl_traits: Vec<ReturnTypeImplTrait>,
1190} 236}
1191 237
238has_interner!(ReturnTypeImplTraits);
239
1192#[derive(Clone, PartialEq, Eq, Debug, Hash)] 240#[derive(Clone, PartialEq, Eq, Debug, Hash)]
1193pub(crate) struct ReturnTypeImplTrait { 241pub(crate) struct ReturnTypeImplTrait {
1194 pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>, 242 pub(crate) bounds: Binders<Vec<QuantifiedWhereClause>>,
1195} 243}
1196 244
1197pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { 245pub fn static_lifetime() -> Lifetime {
1198 chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id)) 246 LifetimeData::Static.intern(&Interner)
1199}
1200
1201pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId {
1202 salsa::InternKey::from_intern_id(id.0)
1203} 247}
1204 248
1205pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId { 249pub fn dummy_usize_const() -> Const {
1206 chalk_ir::AssocTypeId(salsa::InternKey::as_intern_id(&id)) 250 let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner);
251 chalk_ir::ConstData {
252 ty: usize_ty,
253 value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }),
254 }
255 .intern(&Interner)
1207} 256}
1208 257
1209pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId { 258pub(crate) fn fold_free_vars<T: HasInterner<Interner = Interner> + Fold<Interner>>(
1210 salsa::InternKey::from_intern_id(id.0) 259 t: T,
1211} 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 }
1212 268
1213pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeParamId { 269 fn interner(&self) -> &'i Interner {
1214 assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); 270 &Interner
1215 let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); 271 }
1216 db.lookup_intern_type_param_id(interned_id)
1217}
1218 272
1219pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderIndex { 273 fn fold_free_var_ty(
1220 let interned_id = db.intern_type_param_id(id); 274 &mut self,
1221 PlaceholderIndex { 275 bound_var: BoundVar,
1222 ui: chalk_ir::UniverseIndex::ROOT, 276 outer_binder: DebruijnIndex,
1223 idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(), 277 ) -> Fallible<Ty> {
278 Ok(self.0(bound_var, outer_binder))
279 }
1224 } 280 }
281 t.fold_with(&mut FreeVarFolder(f), DebruijnIndex::INNERMOST).expect("fold failed unexpectedly")
1225} 282}
1226 283
1227pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId { 284pub(crate) fn fold_tys<T: HasInterner<Interner = Interner> + Fold<Interner>>(
1228 chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id)) 285 t: T,
1229} 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 }
1230 302
1231pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId { 303 fn fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Fallible<Ty> {
1232 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")
1233} 309}
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 214655807..7fd46becd 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -5,12 +5,14 @@
5//! - Building the type for an item: This happens through the `type_for_def` query. 5//! - Building the type for an item: This happens through the `type_for_def` query.
6//! 6//!
7//! This usually involves resolving names, collecting generic arguments etc. 7//! This usually involves resolving names, collecting generic arguments etc.
8use std::cell::{Cell, RefCell};
8use std::{iter, sync::Arc}; 9use std::{iter, sync::Arc};
9 10
10use base_db::CrateId; 11use base_db::CrateId;
11use chalk_ir::{cast::Cast, Mutability, Safety}; 12use chalk_ir::{cast::Cast, fold::Shift, interner::HasInterner, Mutability, Safety};
12use hir_def::{ 13use hir_def::{
13 adt::StructKind, 14 adt::StructKind,
15 body::{Expander, LowerCtx},
14 builtin_type::BuiltinType, 16 builtin_type::BuiltinType,
15 generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget}, 17 generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget},
16 path::{GenericArg, Path, PathSegment, PathSegments}, 18 path::{GenericArg, Path, PathSegment, PathSegments},
@@ -20,23 +22,24 @@ use hir_def::{
20 GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId, 22 GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
21 TypeAliasId, TypeParamId, UnionId, VariantId, 23 TypeAliasId, TypeParamId, UnionId, VariantId,
22}; 24};
23use hir_expand::name::Name; 25use hir_expand::{name::Name, ExpandResult};
24use la_arena::ArenaMap; 26use la_arena::ArenaMap;
25use smallvec::SmallVec; 27use smallvec::SmallVec;
26use stdx::impl_from; 28use stdx::impl_from;
29use syntax::ast;
27 30
28use crate::{ 31use crate::{
29 db::HirDatabase, 32 db::HirDatabase,
30 to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx, 33 dummy_usize_const,
31 traits::chalk::{Interner, ToChalk}, 34 mapping::ToChalk,
35 static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
32 utils::{ 36 utils::{
33 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, 37 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics,
34 variant_data,
35 }, 38 },
36 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig, 39 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig,
37 ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses, 40 FnSubst, ImplTraitId, Interner, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause,
38 ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty, 41 QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution,
39 TyBuilder, TyKind, TypeWalk, WhereClause, 42 TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
40}; 43};
41 44
42#[derive(Debug)] 45#[derive(Debug)]
@@ -50,7 +53,7 @@ pub struct TyLoweringContext<'a> {
50 /// possible currently, so this should be fine for now. 53 /// possible currently, so this should be fine for now.
51 pub type_param_mode: TypeParamLoweringMode, 54 pub type_param_mode: TypeParamLoweringMode,
52 pub impl_trait_mode: ImplTraitLoweringMode, 55 pub impl_trait_mode: ImplTraitLoweringMode,
53 impl_trait_counter: std::cell::Cell<u16>, 56 impl_trait_counter: Cell<u16>,
54 /// When turning `impl Trait` into opaque types, we have to collect the 57 /// When turning `impl Trait` into opaque types, we have to collect the
55 /// bounds at the same time to get the IDs correct (without becoming too 58 /// bounds at the same time to get the IDs correct (without becoming too
56 /// complicated). I don't like using interior mutability (as for the 59 /// complicated). I don't like using interior mutability (as for the
@@ -59,16 +62,17 @@ pub struct TyLoweringContext<'a> {
59 /// we're grouping the mutable data (the counter and this field) together 62 /// we're grouping the mutable data (the counter and this field) together
60 /// with the immutable context (the references to the DB and resolver). 63 /// with the immutable context (the references to the DB and resolver).
61 /// Splitting this up would be a possible fix. 64 /// Splitting this up would be a possible fix.
62 opaque_type_data: std::cell::RefCell<Vec<ReturnTypeImplTrait>>, 65 opaque_type_data: RefCell<Vec<ReturnTypeImplTrait>>,
66 expander: RefCell<Option<Expander>>,
63} 67}
64 68
65impl<'a> TyLoweringContext<'a> { 69impl<'a> TyLoweringContext<'a> {
66 pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver) -> Self { 70 pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver) -> Self {
67 let impl_trait_counter = std::cell::Cell::new(0); 71 let impl_trait_counter = Cell::new(0);
68 let impl_trait_mode = ImplTraitLoweringMode::Disallowed; 72 let impl_trait_mode = ImplTraitLoweringMode::Disallowed;
69 let type_param_mode = TypeParamLoweringMode::Placeholder; 73 let type_param_mode = TypeParamLoweringMode::Placeholder;
70 let in_binders = DebruijnIndex::INNERMOST; 74 let in_binders = DebruijnIndex::INNERMOST;
71 let opaque_type_data = std::cell::RefCell::new(Vec::new()); 75 let opaque_type_data = RefCell::new(Vec::new());
72 Self { 76 Self {
73 db, 77 db,
74 resolver, 78 resolver,
@@ -77,6 +81,7 @@ impl<'a> TyLoweringContext<'a> {
77 impl_trait_counter, 81 impl_trait_counter,
78 type_param_mode, 82 type_param_mode,
79 opaque_type_data, 83 opaque_type_data,
84 expander: RefCell::new(None),
80 } 85 }
81 } 86 }
82 87
@@ -86,15 +91,18 @@ impl<'a> TyLoweringContext<'a> {
86 f: impl FnOnce(&TyLoweringContext) -> T, 91 f: impl FnOnce(&TyLoweringContext) -> T,
87 ) -> T { 92 ) -> T {
88 let opaque_ty_data_vec = self.opaque_type_data.replace(Vec::new()); 93 let opaque_ty_data_vec = self.opaque_type_data.replace(Vec::new());
94 let expander = self.expander.replace(None);
89 let new_ctx = Self { 95 let new_ctx = Self {
90 in_binders: debruijn, 96 in_binders: debruijn,
91 impl_trait_counter: std::cell::Cell::new(self.impl_trait_counter.get()), 97 impl_trait_counter: Cell::new(self.impl_trait_counter.get()),
92 opaque_type_data: std::cell::RefCell::new(opaque_ty_data_vec), 98 opaque_type_data: RefCell::new(opaque_ty_data_vec),
99 expander: RefCell::new(expander),
93 ..*self 100 ..*self
94 }; 101 };
95 let result = f(&new_ctx); 102 let result = f(&new_ctx);
96 self.impl_trait_counter.set(new_ctx.impl_trait_counter.get()); 103 self.impl_trait_counter.set(new_ctx.impl_trait_counter.get());
97 self.opaque_type_data.replace(new_ctx.opaque_type_data.into_inner()); 104 self.opaque_type_data.replace(new_ctx.opaque_type_data.into_inner());
105 self.expander.replace(new_ctx.expander.into_inner());
98 result 106 result
99 } 107 }
100 108
@@ -166,7 +174,7 @@ impl<'a> TyLoweringContext<'a> {
166 } 174 }
167 TypeRef::Array(inner) => { 175 TypeRef::Array(inner) => {
168 let inner_ty = self.lower_ty(inner); 176 let inner_ty = self.lower_ty(inner);
169 TyKind::Array(inner_ty).intern(&Interner) 177 TyKind::Array(inner_ty, dummy_usize_const()).intern(&Interner)
170 } 178 }
171 TypeRef::Slice(inner) => { 179 TypeRef::Slice(inner) => {
172 let inner_ty = self.lower_ty(inner); 180 let inner_ty = self.lower_ty(inner);
@@ -174,16 +182,19 @@ impl<'a> TyLoweringContext<'a> {
174 } 182 }
175 TypeRef::Reference(inner, _, mutability) => { 183 TypeRef::Reference(inner, _, mutability) => {
176 let inner_ty = self.lower_ty(inner); 184 let inner_ty = self.lower_ty(inner);
177 TyKind::Ref(lower_to_chalk_mutability(*mutability), inner_ty).intern(&Interner) 185 let lifetime = static_lifetime();
186 TyKind::Ref(lower_to_chalk_mutability(*mutability), lifetime, inner_ty)
187 .intern(&Interner)
178 } 188 }
179 TypeRef::Placeholder => TyKind::Unknown.intern(&Interner), 189 TypeRef::Placeholder => TyKind::Error.intern(&Interner),
180 TypeRef::Fn(params, is_varargs) => { 190 TypeRef::Fn(params, is_varargs) => {
181 let substs = 191 let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
182 Substitution::from_iter(&Interner, params.iter().map(|tr| self.lower_ty(tr))); 192 Substitution::from_iter(&Interner, params.iter().map(|tr| ctx.lower_ty(tr)))
193 });
183 TyKind::Function(FnPointer { 194 TyKind::Function(FnPointer {
184 num_args: substs.len(&Interner) - 1, 195 num_binders: 0, // FIXME lower `for<'a> fn()` correctly
185 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs }, 196 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
186 substs, 197 substitution: FnSubst(substs),
187 }) 198 })
188 .intern(&Interner) 199 .intern(&Interner)
189 } 200 }
@@ -196,8 +207,8 @@ impl<'a> TyLoweringContext<'a> {
196 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)), 207 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
197 ) 208 )
198 }); 209 });
199 let bounds = Binders::new(1, bounds); 210 let bounds = crate::make_only_type_binders(1, bounds);
200 TyKind::Dyn(DynTy { bounds }).intern(&Interner) 211 TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(&Interner)
201 } 212 }
202 TypeRef::ImplTrait(bounds) => { 213 TypeRef::ImplTrait(bounds) => {
203 match self.impl_trait_mode { 214 match self.impl_trait_mode {
@@ -209,9 +220,9 @@ impl<'a> TyLoweringContext<'a> {
209 // this dance is to make sure the data is in the right 220 // this dance is to make sure the data is in the right
210 // place even if we encounter more opaque types while 221 // place even if we encounter more opaque types while
211 // lowering the bounds 222 // lowering the bounds
212 self.opaque_type_data 223 self.opaque_type_data.borrow_mut().push(ReturnTypeImplTrait {
213 .borrow_mut() 224 bounds: crate::make_only_type_binders(1, Vec::new()),
214 .push(ReturnTypeImplTrait { bounds: Binders::new(1, Vec::new()) }); 225 });
215 // We don't want to lower the bounds inside the binders 226 // We don't want to lower the bounds inside the binders
216 // we're currently in, because they don't end up inside 227 // we're currently in, because they don't end up inside
217 // those binders. E.g. when we have `impl Trait<impl 228 // those binders. E.g. when we have `impl Trait<impl
@@ -253,12 +264,12 @@ impl<'a> TyLoweringContext<'a> {
253 data.provenance == TypeParamProvenance::ArgumentImplTrait 264 data.provenance == TypeParamProvenance::ArgumentImplTrait
254 }) 265 })
255 .nth(idx as usize) 266 .nth(idx as usize)
256 .map_or(TyKind::Unknown, |(id, _)| { 267 .map_or(TyKind::Error, |(id, _)| {
257 TyKind::Placeholder(to_placeholder_idx(self.db, id)) 268 TyKind::Placeholder(to_placeholder_idx(self.db, id))
258 }); 269 });
259 param.intern(&Interner) 270 param.intern(&Interner)
260 } else { 271 } else {
261 TyKind::Unknown.intern(&Interner) 272 TyKind::Error.intern(&Interner)
262 } 273 }
263 } 274 }
264 ImplTraitLoweringMode::Variable => { 275 ImplTraitLoweringMode::Variable => {
@@ -280,11 +291,58 @@ impl<'a> TyLoweringContext<'a> {
280 } 291 }
281 ImplTraitLoweringMode::Disallowed => { 292 ImplTraitLoweringMode::Disallowed => {
282 // FIXME: report error 293 // FIXME: report error
283 TyKind::Unknown.intern(&Interner) 294 TyKind::Error.intern(&Interner)
295 }
296 }
297 }
298 TypeRef::Macro(macro_call) => {
299 let (expander, recursion_start) = {
300 let mut expander = self.expander.borrow_mut();
301 if expander.is_some() {
302 (Some(expander), false)
303 } else {
304 if let Some(module_id) = self.resolver.module() {
305 *expander = Some(Expander::new(
306 self.db.upcast(),
307 macro_call.file_id,
308 module_id,
309 ));
310 (Some(expander), true)
311 } else {
312 (None, false)
313 }
284 } 314 }
315 };
316 let ty = if let Some(mut expander) = expander {
317 let expander_mut = expander.as_mut().unwrap();
318 let macro_call = macro_call.to_node(self.db.upcast());
319 match expander_mut.enter_expand::<ast::Type>(self.db.upcast(), macro_call) {
320 Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
321 let ctx =
322 LowerCtx::new(self.db.upcast(), expander_mut.current_file_id());
323 let type_ref = TypeRef::from_ast(&ctx, expanded);
324
325 drop(expander);
326 let ty = self.lower_ty(&type_ref);
327
328 self.expander
329 .borrow_mut()
330 .as_mut()
331 .unwrap()
332 .exit(self.db.upcast(), mark);
333 Some(ty)
334 }
335 _ => None,
336 }
337 } else {
338 None
339 };
340 if recursion_start {
341 *self.expander.borrow_mut() = None;
285 } 342 }
343 ty.unwrap_or_else(|| TyKind::Error.intern(&Interner))
286 } 344 }
287 TypeRef::Error => TyKind::Unknown.intern(&Interner), 345 TypeRef::Error => TyKind::Error.intern(&Interner),
288 }; 346 };
289 (ty, res) 347 (ty, res)
290 } 348 }
@@ -328,7 +386,7 @@ impl<'a> TyLoweringContext<'a> {
328 (self.select_associated_type(res, segment), None) 386 (self.select_associated_type(res, segment), None)
329 } else if remaining_segments.len() > 1 { 387 } else if remaining_segments.len() > 1 {
330 // FIXME report error (ambiguous associated type) 388 // FIXME report error (ambiguous associated type)
331 (TyKind::Unknown.intern(&Interner), None) 389 (TyKind::Error.intern(&Interner), None)
332 } else { 390 } else {
333 (ty, res) 391 (ty, res)
334 } 392 }
@@ -372,21 +430,24 @@ impl<'a> TyLoweringContext<'a> {
372 } 430 }
373 None => { 431 None => {
374 // FIXME: report error (associated type not found) 432 // FIXME: report error (associated type not found)
375 TyKind::Unknown.intern(&Interner) 433 TyKind::Error.intern(&Interner)
376 } 434 }
377 } 435 }
378 } else if remaining_segments.len() > 1 { 436 } else if remaining_segments.len() > 1 {
379 // FIXME report error (ambiguous associated type) 437 // FIXME report error (ambiguous associated type)
380 TyKind::Unknown.intern(&Interner) 438 TyKind::Error.intern(&Interner)
381 } else { 439 } else {
382 let dyn_ty = DynTy { 440 let dyn_ty = DynTy {
383 bounds: Binders::new( 441 bounds: crate::make_only_type_binders(
384 1, 442 1,
385 QuantifiedWhereClauses::from_iter( 443 QuantifiedWhereClauses::from_iter(
386 &Interner, 444 &Interner,
387 Some(Binders::wrap_empty(WhereClause::Implemented(trait_ref))), 445 Some(crate::wrap_empty_binders(WhereClause::Implemented(
446 trait_ref,
447 ))),
388 ), 448 ),
389 ), 449 ),
450 lifetime: static_lifetime(),
390 }; 451 };
391 TyKind::Dyn(dyn_ty).intern(&Interner) 452 TyKind::Dyn(dyn_ty).intern(&Interner)
392 }; 453 };
@@ -414,7 +475,7 @@ impl<'a> TyLoweringContext<'a> {
414 TypeParamLoweringMode::Placeholder => generics.type_params_subst(self.db), 475 TypeParamLoweringMode::Placeholder => generics.type_params_subst(self.db),
415 TypeParamLoweringMode::Variable => generics.bound_vars_subst(self.in_binders), 476 TypeParamLoweringMode::Variable => generics.bound_vars_subst(self.in_binders),
416 }; 477 };
417 self.db.impl_self_ty(impl_id).subst(&substs) 478 self.db.impl_self_ty(impl_id).substitute(&Interner, &substs)
418 } 479 }
419 TypeNs::AdtSelfType(adt) => { 480 TypeNs::AdtSelfType(adt) => {
420 let generics = generics(self.db.upcast(), adt.into()); 481 let generics = generics(self.db.upcast(), adt.into());
@@ -422,7 +483,7 @@ impl<'a> TyLoweringContext<'a> {
422 TypeParamLoweringMode::Placeholder => generics.type_params_subst(self.db), 483 TypeParamLoweringMode::Placeholder => generics.type_params_subst(self.db),
423 TypeParamLoweringMode::Variable => generics.bound_vars_subst(self.in_binders), 484 TypeParamLoweringMode::Variable => generics.bound_vars_subst(self.in_binders),
424 }; 485 };
425 self.db.ty(adt.into()).subst(&substs) 486 self.db.ty(adt.into()).substitute(&Interner, &substs)
426 } 487 }
427 488
428 TypeNs::AdtId(it) => self.lower_path_inner(resolved_segment, it.into(), infer_args), 489 TypeNs::AdtId(it) => self.lower_path_inner(resolved_segment, it.into(), infer_args),
@@ -433,7 +494,7 @@ impl<'a> TyLoweringContext<'a> {
433 self.lower_path_inner(resolved_segment, it.into(), infer_args) 494 self.lower_path_inner(resolved_segment, it.into(), infer_args)
434 } 495 }
435 // FIXME: report error 496 // FIXME: report error
436 TypeNs::EnumVariantId(_) => return (TyKind::Unknown.intern(&Interner), None), 497 TypeNs::EnumVariantId(_) => return (TyKind::Error.intern(&Interner), None),
437 }; 498 };
438 self.lower_ty_relative_path(ty, Some(resolution), remaining_segments) 499 self.lower_ty_relative_path(ty, Some(resolution), remaining_segments)
439 } 500 }
@@ -447,7 +508,7 @@ impl<'a> TyLoweringContext<'a> {
447 let (resolution, remaining_index) = 508 let (resolution, remaining_index) =
448 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) { 509 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
449 Some(it) => it, 510 Some(it) => it,
450 None => return (TyKind::Unknown.intern(&Interner), None), 511 None => return (TyKind::Error.intern(&Interner), None),
451 }; 512 };
452 let (resolved_segment, remaining_segments) = match remaining_index { 513 let (resolved_segment, remaining_segments) = match remaining_index {
453 None => ( 514 None => (
@@ -477,13 +538,13 @@ impl<'a> TyLoweringContext<'a> {
477 ), 538 ),
478 ); 539 );
479 let s = generics.type_params_subst(self.db); 540 let s = generics.type_params_subst(self.db);
480 t.substitution.clone().subst_bound_vars(&s) 541 s.apply(t.substitution.clone(), &Interner)
481 } 542 }
482 TypeParamLoweringMode::Variable => t.substitution.clone(), 543 TypeParamLoweringMode::Variable => t.substitution.clone(),
483 }; 544 };
484 // We need to shift in the bound vars, since 545 // We need to shift in the bound vars, since
485 // associated_type_shorthand_candidates does not do that 546 // associated_type_shorthand_candidates does not do that
486 let substs = substs.shift_bound_vars(self.in_binders); 547 let substs = substs.shifted_in_from(&Interner, self.in_binders);
487 // FIXME handle type parameters on the segment 548 // FIXME handle type parameters on the segment
488 return Some( 549 return Some(
489 TyKind::Alias(AliasTy::Projection(ProjectionTy { 550 TyKind::Alias(AliasTy::Projection(ProjectionTy {
@@ -498,9 +559,9 @@ impl<'a> TyLoweringContext<'a> {
498 }, 559 },
499 ); 560 );
500 561
501 ty.unwrap_or(TyKind::Unknown.intern(&Interner)) 562 ty.unwrap_or(TyKind::Error.intern(&Interner))
502 } else { 563 } else {
503 TyKind::Unknown.intern(&Interner) 564 TyKind::Error.intern(&Interner)
504 } 565 }
505 } 566 }
506 567
@@ -516,7 +577,7 @@ impl<'a> TyLoweringContext<'a> {
516 TyDefId::TypeAliasId(it) => Some(it.into()), 577 TyDefId::TypeAliasId(it) => Some(it.into()),
517 }; 578 };
518 let substs = self.substs_from_path_segment(segment, generic_def, infer_args, None); 579 let substs = self.substs_from_path_segment(segment, generic_def, infer_args, None);
519 self.db.ty(typeable).subst(&substs) 580 self.db.ty(typeable).substitute(&Interner, &substs)
520 } 581 }
521 582
522 /// Collect generic arguments from a path into a `Substs`. See also 583 /// Collect generic arguments from a path into a `Substs`. See also
@@ -569,13 +630,13 @@ impl<'a> TyLoweringContext<'a> {
569 def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split()); 630 def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split());
570 let total_len = parent_params + self_params + type_params + impl_trait_params; 631 let total_len = parent_params + self_params + type_params + impl_trait_params;
571 632
572 substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(parent_params)); 633 substs.extend(iter::repeat(TyKind::Error.intern(&Interner)).take(parent_params));
573 634
574 let fill_self_params = || { 635 let fill_self_params = || {
575 substs.extend( 636 substs.extend(
576 explicit_self_ty 637 explicit_self_ty
577 .into_iter() 638 .into_iter()
578 .chain(iter::repeat(TyKind::Unknown.intern(&Interner))) 639 .chain(iter::repeat(TyKind::Error.intern(&Interner)))
579 .take(self_params), 640 .take(self_params),
580 ) 641 )
581 }; 642 };
@@ -620,7 +681,7 @@ impl<'a> TyLoweringContext<'a> {
620 for default_ty in defaults.iter().skip(substs.len()) { 681 for default_ty in defaults.iter().skip(substs.len()) {
621 // each default can depend on the previous parameters 682 // each default can depend on the previous parameters
622 let substs_so_far = Substitution::from_iter(&Interner, substs.clone()); 683 let substs_so_far = Substitution::from_iter(&Interner, substs.clone());
623 substs.push(default_ty.clone().subst(&substs_so_far)); 684 substs.push(default_ty.clone().substitute(&Interner, &substs_so_far));
624 } 685 }
625 } 686 }
626 } 687 }
@@ -628,7 +689,7 @@ impl<'a> TyLoweringContext<'a> {
628 // add placeholders for args that were not provided 689 // add placeholders for args that were not provided
629 // FIXME: emit diagnostics in contexts where this is not allowed 690 // FIXME: emit diagnostics in contexts where this is not allowed
630 for _ in substs.len()..total_len { 691 for _ in substs.len()..total_len {
631 substs.push(TyKind::Unknown.intern(&Interner)); 692 substs.push(TyKind::Error.intern(&Interner));
632 } 693 }
633 assert_eq!(substs.len(), total_len); 694 assert_eq!(substs.len(), total_len);
634 695
@@ -720,7 +781,7 @@ impl<'a> TyLoweringContext<'a> {
720 let trait_ref = match bound { 781 let trait_ref = match bound {
721 TypeBound::Path(path) => { 782 TypeBound::Path(path) => {
722 bindings = self.lower_trait_ref_from_path(path, Some(self_ty)); 783 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
723 bindings.clone().map(WhereClause::Implemented).map(|b| Binders::wrap_empty(b)) 784 bindings.clone().map(WhereClause::Implemented).map(|b| crate::wrap_empty_binders(b))
724 } 785 }
725 TypeBound::Lifetime(_) => None, 786 TypeBound::Lifetime(_) => None,
726 TypeBound::Error => None, 787 TypeBound::Error => None,
@@ -767,7 +828,7 @@ impl<'a> TyLoweringContext<'a> {
767 let ty = self.lower_ty(type_ref); 828 let ty = self.lower_ty(type_ref);
768 let alias_eq = 829 let alias_eq =
769 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty }; 830 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
770 preds.push(Binders::wrap_empty(WhereClause::AliasEq(alias_eq))); 831 preds.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
771 } 832 }
772 for bound in &binding.bounds { 833 for bound in &binding.bounds {
773 preds.extend(self.lower_type_bound( 834 preds.extend(self.lower_type_bound(
@@ -787,7 +848,7 @@ impl<'a> TyLoweringContext<'a> {
787 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { 848 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
788 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)).collect() 849 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)).collect()
789 }); 850 });
790 ReturnTypeImplTrait { bounds: Binders::new(1, predicates) } 851 ReturnTypeImplTrait { bounds: crate::make_only_type_binders(1, predicates) }
791 } 852 }
792} 853}
793 854
@@ -831,17 +892,20 @@ pub fn associated_type_shorthand_candidates<R>(
831 }; 892 };
832 893
833 match res { 894 match res {
834 // FIXME: how to correctly handle higher-ranked bounds here? 895 TypeNs::SelfType(impl_id) => search(
835 TypeNs::SelfType(impl_id) => { 896 // we're _in_ the impl -- the binders get added back later. Correct,
836 search(db.impl_trait(impl_id)?.value.shift_bound_vars_out(DebruijnIndex::ONE)) 897 // but it would be nice to make this more explicit
837 } 898 db.impl_trait(impl_id)?.into_value_and_skipped_binders().0,
899 ),
838 TypeNs::GenericParam(param_id) => { 900 TypeNs::GenericParam(param_id) => {
839 let predicates = db.generic_predicates_for_param(param_id); 901 let predicates = db.generic_predicates_for_param(param_id);
840 let res = predicates.iter().find_map(|pred| match &pred.value.value { 902 let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() {
841 // FIXME: how to correctly handle higher-ranked bounds here? 903 // FIXME: how to correctly handle higher-ranked bounds here?
842 WhereClause::Implemented(tr) => { 904 WhereClause::Implemented(tr) => search(
843 search(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE)) 905 tr.clone()
844 } 906 .shifted_out_to(&Interner, DebruijnIndex::ONE)
907 .expect("FIXME unexpected higher-ranked trait bound"),
908 ),
845 _ => None, 909 _ => None,
846 }); 910 });
847 if let res @ Some(_) = res { 911 if let res @ Some(_) = res {
@@ -870,7 +934,7 @@ pub(crate) fn field_types_query(
870 db: &dyn HirDatabase, 934 db: &dyn HirDatabase,
871 variant_id: VariantId, 935 variant_id: VariantId,
872) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>> { 936) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>> {
873 let var_data = variant_data(db.upcast(), variant_id); 937 let var_data = variant_id.variant_data(db.upcast());
874 let (resolver, def): (_, GenericDefId) = match variant_id { 938 let (resolver, def): (_, GenericDefId) = match variant_id {
875 VariantId::StructId(it) => (it.resolver(db.upcast()), it.into()), 939 VariantId::StructId(it) => (it.resolver(db.upcast()), it.into()),
876 VariantId::UnionId(it) => (it.resolver(db.upcast()), it.into()), 940 VariantId::UnionId(it) => (it.resolver(db.upcast()), it.into()),
@@ -881,7 +945,7 @@ pub(crate) fn field_types_query(
881 let ctx = 945 let ctx =
882 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 946 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
883 for (field_id, field_data) in var_data.fields().iter() { 947 for (field_id, field_data) in var_data.fields().iter() {
884 res.insert(field_id, Binders::new(generics.len(), ctx.lower_ty(&field_data.type_ref))) 948 res.insert(field_id, make_binders(&generics, ctx.lower_ty(&field_data.type_ref)))
885 } 949 }
886 Arc::new(res) 950 Arc::new(res)
887} 951}
@@ -915,9 +979,7 @@ pub(crate) fn generic_predicates_for_param_query(
915 }, 979 },
916 WherePredicate::Lifetime { .. } => false, 980 WherePredicate::Lifetime { .. } => false,
917 }) 981 })
918 .flat_map(|pred| { 982 .flat_map(|pred| ctx.lower_where_predicate(pred, true).map(|p| make_binders(&generics, p)))
919 ctx.lower_where_predicate(pred, true).map(|p| Binders::new(generics.len(), p))
920 })
921 .collect() 983 .collect()
922} 984}
923 985
@@ -941,10 +1003,10 @@ pub(crate) fn trait_environment_query(
941 for pred in resolver.where_predicates_in_scope() { 1003 for pred in resolver.where_predicates_in_scope() {
942 for pred in ctx.lower_where_predicate(pred, false) { 1004 for pred in ctx.lower_where_predicate(pred, false) {
943 if let WhereClause::Implemented(tr) = &pred.skip_binders() { 1005 if let WhereClause::Implemented(tr) = &pred.skip_binders() {
944 traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id())); 1006 traits_in_scope
1007 .push((tr.self_type_parameter(&Interner).clone(), tr.hir_trait_id()));
945 } 1008 }
946 let program_clause: chalk_ir::ProgramClause<Interner> = 1009 let program_clause: chalk_ir::ProgramClause<Interner> = pred.clone().cast(&Interner);
947 pred.clone().to_chalk(db).cast(&Interner);
948 clauses.push(program_clause.into_from_env_clause(&Interner)); 1010 clauses.push(program_clause.into_from_env_clause(&Interner));
949 } 1011 }
950 } 1012 }
@@ -967,7 +1029,7 @@ pub(crate) fn trait_environment_query(
967 let substs = TyBuilder::type_params_subst(db, trait_id); 1029 let substs = TyBuilder::type_params_subst(db, trait_id);
968 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs }; 1030 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
969 let pred = WhereClause::Implemented(trait_ref); 1031 let pred = WhereClause::Implemented(trait_ref);
970 let program_clause: chalk_ir::ProgramClause<Interner> = pred.to_chalk(db).cast(&Interner); 1032 let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(&Interner);
971 clauses.push(program_clause.into_from_env_clause(&Interner)); 1033 clauses.push(program_clause.into_from_env_clause(&Interner));
972 } 1034 }
973 1035
@@ -987,9 +1049,7 @@ pub(crate) fn generic_predicates_query(
987 let generics = generics(db.upcast(), def); 1049 let generics = generics(db.upcast(), def);
988 resolver 1050 resolver
989 .where_predicates_in_scope() 1051 .where_predicates_in_scope()
990 .flat_map(|pred| { 1052 .flat_map(|pred| ctx.lower_where_predicate(pred, false).map(|p| make_binders(&generics, p)))
991 ctx.lower_where_predicate(pred, false).map(|p| Binders::new(generics.len(), p))
992 })
993 .collect() 1053 .collect()
994} 1054}
995 1055
@@ -1008,25 +1068,21 @@ pub(crate) fn generic_defaults_query(
1008 .enumerate() 1068 .enumerate()
1009 .map(|(idx, (_, p))| { 1069 .map(|(idx, (_, p))| {
1010 let mut ty = 1070 let mut ty =
1011 p.default.as_ref().map_or(TyKind::Unknown.intern(&Interner), |t| ctx.lower_ty(t)); 1071 p.default.as_ref().map_or(TyKind::Error.intern(&Interner), |t| ctx.lower_ty(t));
1012 1072
1013 // Each default can only refer to previous parameters. 1073 // Each default can only refer to previous parameters.
1014 ty.walk_mut_binders( 1074 ty = crate::fold_free_vars(ty, |bound, binders| {
1015 &mut |ty, binders| match ty.interned_mut() { 1075 if bound.index >= idx && bound.debruijn == DebruijnIndex::INNERMOST {
1016 TyKind::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => { 1076 // type variable default referring to parameter coming
1017 if *index >= idx { 1077 // after it. This is forbidden (FIXME: report
1018 // type variable default referring to parameter coming 1078 // diagnostic)
1019 // after it. This is forbidden (FIXME: report 1079 TyKind::Error.intern(&Interner)
1020 // diagnostic) 1080 } else {
1021 *ty = TyKind::Unknown.intern(&Interner); 1081 bound.shifted_in_from(binders).to_ty(&Interner)
1022 } 1082 }
1023 } 1083 });
1024 _ => {}
1025 },
1026 DebruijnIndex::INNERMOST,
1027 );
1028 1084
1029 Binders::new(idx, ty) 1085 crate::make_only_type_binders(idx, ty)
1030 }) 1086 })
1031 .collect(); 1087 .collect();
1032 1088
@@ -1039,14 +1095,13 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1039 let ctx_params = TyLoweringContext::new(db, &resolver) 1095 let ctx_params = TyLoweringContext::new(db, &resolver)
1040 .with_impl_trait_mode(ImplTraitLoweringMode::Variable) 1096 .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
1041 .with_type_param_mode(TypeParamLoweringMode::Variable); 1097 .with_type_param_mode(TypeParamLoweringMode::Variable);
1042 let params = data.params.iter().map(|tr| (&ctx_params).lower_ty(tr)).collect::<Vec<_>>(); 1098 let params = data.params.iter().map(|tr| ctx_params.lower_ty(tr)).collect::<Vec<_>>();
1043 let ctx_ret = TyLoweringContext::new(db, &resolver) 1099 let ctx_ret = TyLoweringContext::new(db, &resolver)
1044 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) 1100 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1045 .with_type_param_mode(TypeParamLoweringMode::Variable); 1101 .with_type_param_mode(TypeParamLoweringMode::Variable);
1046 let ret = (&ctx_ret).lower_ty(&data.ret_type); 1102 let ret = ctx_ret.lower_ty(&data.ret_type);
1047 let generics = generics(db.upcast(), def.into()); 1103 let generics = generics(db.upcast(), def.into());
1048 let num_binders = generics.len(); 1104 make_binders(&generics, CallableSig::from_params_and_return(params, ret, data.is_varargs()))
1049 Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs()))
1050} 1105}
1051 1106
1052/// Build the declared type of a function. This should not need to look at the 1107/// Build the declared type of a function. This should not need to look at the
@@ -1054,8 +1109,8 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1054fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { 1109fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1055 let generics = generics(db.upcast(), def.into()); 1110 let generics = generics(db.upcast(), def.into());
1056 let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); 1111 let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST);
1057 Binders::new( 1112 make_binders(
1058 substs.len(&Interner), 1113 &generics,
1059 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner), 1114 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner),
1060 ) 1115 )
1061} 1116}
@@ -1068,7 +1123,7 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
1068 let ctx = 1123 let ctx =
1069 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1124 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1070 1125
1071 Binders::new(generics.len(), ctx.lower_ty(&data.type_ref)) 1126 make_binders(&generics, ctx.lower_ty(&data.type_ref))
1072} 1127}
1073 1128
1074/// Build the declared type of a static. 1129/// Build the declared type of a static.
@@ -1077,7 +1132,7 @@ fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
1077 let resolver = def.resolver(db.upcast()); 1132 let resolver = def.resolver(db.upcast());
1078 let ctx = TyLoweringContext::new(db, &resolver); 1133 let ctx = TyLoweringContext::new(db, &resolver);
1079 1134
1080 Binders::new(0, ctx.lower_ty(&data.type_ref)) 1135 Binders::empty(&Interner, ctx.lower_ty(&data.type_ref))
1081} 1136}
1082 1137
1083fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig { 1138fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig {
@@ -1087,8 +1142,8 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
1087 let ctx = 1142 let ctx =
1088 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1143 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1089 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>(); 1144 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1090 let ret = type_for_adt(db, def.into()); 1145 let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
1091 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) 1146 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1092} 1147}
1093 1148
1094/// Build the type of a tuple struct constructor. 1149/// Build the type of a tuple struct constructor.
@@ -1099,8 +1154,8 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T
1099 } 1154 }
1100 let generics = generics(db.upcast(), def.into()); 1155 let generics = generics(db.upcast(), def.into());
1101 let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); 1156 let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST);
1102 Binders::new( 1157 make_binders(
1103 substs.len(&Interner), 1158 &generics,
1104 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner), 1159 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner),
1105 ) 1160 )
1106} 1161}
@@ -1113,8 +1168,8 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
1113 let ctx = 1168 let ctx =
1114 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1169 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1115 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>(); 1170 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1116 let ret = type_for_adt(db, def.parent.into()); 1171 let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
1117 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) 1172 Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
1118} 1173}
1119 1174
1120/// Build the type of a tuple enum variant constructor. 1175/// Build the type of a tuple enum variant constructor.
@@ -1126,17 +1181,17 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
1126 } 1181 }
1127 let generics = generics(db.upcast(), def.parent.into()); 1182 let generics = generics(db.upcast(), def.parent.into());
1128 let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST); 1183 let substs = generics.bound_vars_subst(DebruijnIndex::INNERMOST);
1129 Binders::new( 1184 make_binders(
1130 substs.len(&Interner), 1185 &generics,
1131 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner), 1186 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner),
1132 ) 1187 )
1133} 1188}
1134 1189
1135fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { 1190fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1191 let generics = generics(db.upcast(), adt.into());
1136 let b = TyBuilder::adt(db, adt); 1192 let b = TyBuilder::adt(db, adt);
1137 let num_binders = b.remaining();
1138 let ty = b.fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build(); 1193 let ty = b.fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build();
1139 Binders::new(num_binders, ty) 1194 make_binders(&generics, ty)
1140} 1195}
1141 1196
1142fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { 1197fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
@@ -1145,11 +1200,11 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1145 let ctx = 1200 let ctx =
1146 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1201 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1147 if db.type_alias_data(t).is_extern { 1202 if db.type_alias_data(t).is_extern {
1148 Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner)) 1203 Binders::empty(&Interner, TyKind::Foreign(crate::to_foreign_def_id(t)).intern(&Interner))
1149 } else { 1204 } else {
1150 let type_ref = &db.type_alias_data(t).type_ref; 1205 let type_ref = &db.type_alias_data(t).type_ref;
1151 let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error)); 1206 let inner = ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error));
1152 Binders::new(generics.len(), inner) 1207 make_binders(&generics, inner)
1153 } 1208 }
1154} 1209}
1155 1210
@@ -1208,19 +1263,21 @@ impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for V
1208/// namespace. 1263/// namespace.
1209pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> { 1264pub(crate) fn ty_query(db: &dyn HirDatabase, def: TyDefId) -> Binders<Ty> {
1210 match def { 1265 match def {
1211 TyDefId::BuiltinType(it) => Binders::new(0, TyBuilder::builtin(it)), 1266 TyDefId::BuiltinType(it) => Binders::empty(&Interner, TyBuilder::builtin(it)),
1212 TyDefId::AdtId(it) => type_for_adt(db, it), 1267 TyDefId::AdtId(it) => type_for_adt(db, it),
1213 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it), 1268 TyDefId::TypeAliasId(it) => type_for_type_alias(db, it),
1214 } 1269 }
1215} 1270}
1216 1271
1217pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> { 1272pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) -> Binders<Ty> {
1218 let num_binders = match *def { 1273 let generics = match *def {
1219 TyDefId::BuiltinType(_) => 0, 1274 TyDefId::BuiltinType(_) => {
1220 TyDefId::AdtId(it) => generics(db.upcast(), it.into()).len(), 1275 return Binders::empty(&Interner, TyKind::Error.intern(&Interner))
1221 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()).len(), 1276 }
1277 TyDefId::AdtId(it) => generics(db.upcast(), it.into()),
1278 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()),
1222 }; 1279 };
1223 Binders::new(num_binders, TyKind::Unknown.intern(&Interner)) 1280 make_binders(&generics, TyKind::Error.intern(&Interner))
1224} 1281}
1225 1282
1226pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> { 1283pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
@@ -1240,7 +1297,7 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde
1240 let generics = generics(db.upcast(), impl_id.into()); 1297 let generics = generics(db.upcast(), impl_id.into());
1241 let ctx = 1298 let ctx =
1242 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1299 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1243 Binders::new(generics.len(), ctx.lower_ty(&impl_data.self_ty)) 1300 make_binders(&generics, ctx.lower_ty(&impl_data.self_ty))
1244} 1301}
1245 1302
1246pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { 1303pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
@@ -1258,7 +1315,7 @@ pub(crate) fn impl_self_ty_recover(
1258 impl_id: &ImplId, 1315 impl_id: &ImplId,
1259) -> Binders<Ty> { 1316) -> Binders<Ty> {
1260 let generics = generics(db.upcast(), (*impl_id).into()); 1317 let generics = generics(db.upcast(), (*impl_id).into());
1261 Binders::new(generics.len(), TyKind::Unknown.intern(&Interner)) 1318 make_binders(&generics, TyKind::Error.intern(&Interner))
1262} 1319}
1263 1320
1264pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { 1321pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
@@ -1266,9 +1323,9 @@ pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<
1266 let resolver = impl_id.resolver(db.upcast()); 1323 let resolver = impl_id.resolver(db.upcast());
1267 let ctx = 1324 let ctx =
1268 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1325 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1269 let self_ty = db.impl_self_ty(impl_id); 1326 let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
1270 let target_trait = impl_data.target_trait.as_ref()?; 1327 let target_trait = impl_data.target_trait.as_ref()?;
1271 Some(Binders::new(self_ty.num_binders, ctx.lower_trait_ref(target_trait, Some(self_ty.value))?)) 1328 Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?))
1272} 1329}
1273 1330
1274pub(crate) fn return_type_impl_traits( 1331pub(crate) fn return_type_impl_traits(
@@ -1283,13 +1340,12 @@ pub(crate) fn return_type_impl_traits(
1283 .with_type_param_mode(TypeParamLoweringMode::Variable); 1340 .with_type_param_mode(TypeParamLoweringMode::Variable);
1284 let _ret = (&ctx_ret).lower_ty(&data.ret_type); 1341 let _ret = (&ctx_ret).lower_ty(&data.ret_type);
1285 let generics = generics(db.upcast(), def.into()); 1342 let generics = generics(db.upcast(), def.into());
1286 let num_binders = generics.len();
1287 let return_type_impl_traits = 1343 let return_type_impl_traits =
1288 ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() }; 1344 ReturnTypeImplTraits { impl_traits: ctx_ret.opaque_type_data.into_inner() };
1289 if return_type_impl_traits.impl_traits.is_empty() { 1345 if return_type_impl_traits.impl_traits.is_empty() {
1290 None 1346 None
1291 } else { 1347 } else {
1292 Some(Arc::new(Binders::new(num_binders, return_type_impl_traits))) 1348 Some(Arc::new(make_binders(&generics, return_type_impl_traits)))
1293 } 1349 }
1294} 1350}
1295 1351
@@ -1299,3 +1355,7 @@ pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mut
1299 hir_def::type_ref::Mutability::Mut => Mutability::Mut, 1355 hir_def::type_ref::Mutability::Mut => Mutability::Mut,
1300 } 1356 }
1301} 1357}
1358
1359fn make_binders<T: HasInterner<Interner = Interner>>(generics: &Generics, value: T) -> Binders<T> {
1360 crate::make_only_type_binders(generics.len(), value)
1361}
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 a76586f0c..48bbcfd9f 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,51 +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 static_lifetime,
22 utils::all_super_traits, 23 utils::all_super_traits,
23 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, 24 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, ForeignDefId, InEnvironment, Interner,
24 InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, Ty, TyBuilder, TyKind, 25 Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyExt, TyKind,
25 TypeWalk,
26}; 26};
27 27
28/// This is used as a key for indexing impls. 28/// This is used as a key for indexing impls.
29#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 29#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
30pub enum TyFingerprint { 30pub enum TyFingerprint {
31 // These are lang item impls:
31 Str, 32 Str,
32 Slice, 33 Slice,
33 Array, 34 Array,
34 Never, 35 Never,
35 RawPtr(Mutability), 36 RawPtr(Mutability),
36 Scalar(Scalar), 37 Scalar(Scalar),
38 // These can have user-defined impls:
37 Adt(hir_def::AdtId), 39 Adt(hir_def::AdtId),
38 Dyn(TraitId), 40 Dyn(TraitId),
39 Tuple(usize),
40 ForeignType(ForeignDefId), 41 ForeignType(ForeignDefId),
41 FnPtr(usize, FnSig), 42 // These only exist for trait impls
43 Unit,
44 Unnameable,
45 Function(u32),
42} 46}
43 47
44impl TyFingerprint { 48impl TyFingerprint {
45 /// Creates a TyFingerprint for looking up an impl. Only certain types can 49 /// Creates a TyFingerprint for looking up an inherent impl. Only certain
46 /// 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
47 /// `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
48 pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> { 52 /// reference types and such.
49 let fp = match *ty.kind(&Interner) { 53 pub fn for_inherent_impl(ty: &Ty) -> Option<TyFingerprint> {
54 let fp = match ty.kind(&Interner) {
50 TyKind::Str => TyFingerprint::Str, 55 TyKind::Str => TyFingerprint::Str,
51 TyKind::Never => TyFingerprint::Never, 56 TyKind::Never => TyFingerprint::Never,
52 TyKind::Slice(..) => TyFingerprint::Slice, 57 TyKind::Slice(..) => TyFingerprint::Slice,
53 TyKind::Array(..) => TyFingerprint::Array, 58 TyKind::Array(..) => TyFingerprint::Array,
54 TyKind::Scalar(scalar) => TyFingerprint::Scalar(scalar), 59 TyKind::Scalar(scalar) => TyFingerprint::Scalar(*scalar),
55 TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt), 60 TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(*adt),
56 TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), 61 TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(*mutability),
57 TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), 62 TyKind::Foreign(alias_id, ..) => TyFingerprint::ForeignType(*alias_id),
58 TyKind::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id),
59 TyKind::Function(FnPointer { num_args, sig, .. }) => {
60 TyFingerprint::FnPtr(num_args, sig)
61 }
62 TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, 63 TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
63 _ => return None, 64 _ => return None,
64 }; 65 };
65 Some(fp) 66 Some(fp)
66 } 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 }
67} 107}
68 108
69pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ 109pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
@@ -99,25 +139,38 @@ impl TraitImpls {
99 let mut impls = Self { map: FxHashMap::default() }; 139 let mut impls = Self { map: FxHashMap::default() };
100 140
101 let crate_def_map = db.crate_def_map(krate); 141 let crate_def_map = db.crate_def_map(krate);
102 for (_module_id, module_data) in crate_def_map.modules() { 142 collect_def_map(db, &crate_def_map, &mut impls);
103 for impl_id in module_data.scope.impls() { 143
104 let target_trait = match db.impl_trait(impl_id) { 144 return Arc::new(impls);
105 Some(tr) => tr.value.hir_trait_id(), 145
106 None => continue, 146 fn collect_def_map(db: &dyn HirDatabase, def_map: &DefMap, impls: &mut TraitImpls) {
107 }; 147 for (_module_id, module_data) in def_map.modules() {
108 let self_ty = db.impl_self_ty(impl_id); 148 for impl_id in module_data.scope.impls() {
109 let self_ty_fp = TyFingerprint::for_impl(&self_ty.value); 149 let target_trait = match db.impl_trait(impl_id) {
110 impls 150 Some(tr) => tr.skip_binders().hir_trait_id(),
111 .map 151 None => continue,
112 .entry(target_trait) 152 };
113 .or_default() 153 let self_ty = db.impl_self_ty(impl_id);
114 .entry(self_ty_fp) 154 let self_ty_fp = TyFingerprint::for_trait_impl(self_ty.skip_binders());
115 .or_default() 155 impls
116 .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 }
117 } 172 }
118 } 173 }
119
120 Arc::new(impls)
121 } 174 }
122 175
123 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> {
@@ -143,10 +196,13 @@ impl TraitImpls {
143 } 196 }
144 197
145 /// Queries all trait impls for the given type. 198 /// Queries all trait impls for the given type.
146 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> + '_ {
147 self.map 203 self.map
148 .values() 204 .values()
149 .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())
150 .flat_map(|it| it.iter().copied()) 206 .flat_map(|it| it.iter().copied())
151 } 207 }
152 208
@@ -190,28 +246,43 @@ pub struct InherentImpls {
190 246
191impl InherentImpls { 247impl InherentImpls {
192 pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> { 248 pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
193 let mut map: FxHashMap<_, Vec<_>> = FxHashMap::default(); 249 let mut impls = Self { map: FxHashMap::default() };
194 250
195 let crate_def_map = db.crate_def_map(krate); 251 let crate_def_map = db.crate_def_map(krate);
196 for (_module_id, module_data) in crate_def_map.modules() { 252 collect_def_map(db, &crate_def_map, &mut impls);
197 for impl_id in module_data.scope.impls() { 253
198 let data = db.impl_data(impl_id); 254 return Arc::new(impls);
199 if data.target_trait.is_some() { 255
200 continue; 256 fn collect_def_map(db: &dyn HirDatabase, def_map: &DefMap, impls: &mut InherentImpls) {
257 for (_module_id, module_data) in def_map.modules() {
258 for impl_id in module_data.scope.impls() {
259 let data = db.impl_data(impl_id);
260 if data.target_trait.is_some() {
261 continue;
262 }
263
264 let self_ty = db.impl_self_ty(impl_id);
265 let fp = TyFingerprint::for_inherent_impl(self_ty.skip_binders());
266 if let Some(fp) = fp {
267 impls.map.entry(fp).or_default().push(impl_id);
268 }
269 // `fp` should only be `None` in error cases (either erroneous code or incomplete name resolution)
201 } 270 }
202 271
203 let self_ty = db.impl_self_ty(impl_id); 272 // To better support custom derives, collect impls in all unnamed const items.
204 if let Some(fp) = TyFingerprint::for_impl(&self_ty.value) { 273 // const _: () = { ... };
205 map.entry(fp).or_default().push(impl_id); 274 for konst in module_data.scope.unnamed_consts() {
275 let body = db.body(konst.into());
276 for (_, block_def_map) in body.blocks(db.upcast()) {
277 collect_def_map(db, &block_def_map, impls);
278 }
206 } 279 }
207 } 280 }
208 } 281 }
209
210 Arc::new(Self { map })
211 } 282 }
212 283
213 pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] { 284 pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] {
214 match TyFingerprint::for_impl(self_ty) { 285 match TyFingerprint::for_inherent_impl(self_ty) {
215 Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]), 286 Some(fp) => self.map.get(&fp).map(|vec| vec.as_ref()).unwrap_or(&[]),
216 None => &[], 287 None => &[],
217 } 288 }
@@ -222,15 +293,14 @@ impl InherentImpls {
222 } 293 }
223} 294}
224 295
225impl Ty { 296pub fn def_crates(
226 pub fn def_crates( 297 db: &dyn HirDatabase,
227 &self, 298 ty: &Ty,
228 db: &dyn HirDatabase, 299 cur_crate: CrateId,
229 cur_crate: CrateId, 300) -> Option<ArrayVec<CrateId, 2>> {
230 ) -> Option<ArrayVec<CrateId, 2>> { 301 // Types like slice can have inherent impls in several crates, (core and alloc).
231 // Types like slice can have inherent impls in several crates, (core and alloc). 302 // The corresponding impls are marked with lang items, so we can use them to find the required crates.
232 // The corresponding impls are marked with lang items, so we can use them to find the required crates. 303 macro_rules! lang_item_crate {
233 macro_rules! lang_item_crate {
234 ($($name:expr),+ $(,)?) => {{ 304 ($($name:expr),+ $(,)?) => {{
235 let mut v = ArrayVec::<LangItemTarget, 2>::new(); 305 let mut v = ArrayVec::<LangItemTarget, 2>::new();
236 $( 306 $(
@@ -240,51 +310,50 @@ impl Ty {
240 }}; 310 }};
241 } 311 }
242 312
243 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); 313 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect());
244 314
245 let lang_item_targets = match self.kind(&Interner) { 315 let lang_item_targets = match ty.kind(&Interner) {
246 TyKind::Adt(AdtId(def_id), _) => { 316 TyKind::Adt(AdtId(def_id), _) => {
247 return mod_to_crate_ids(def_id.module(db.upcast())); 317 return mod_to_crate_ids(def_id.module(db.upcast()));
248 } 318 }
249 TyKind::ForeignType(id) => { 319 TyKind::Foreign(id) => {
250 return mod_to_crate_ids( 320 return mod_to_crate_ids(
251 from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()), 321 from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()),
252 ); 322 );
253 } 323 }
254 TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"), 324 TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
255 TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"), 325 TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"),
256 TyKind::Scalar(Scalar::Float(f)) => match f { 326 TyKind::Scalar(Scalar::Float(f)) => match f {
257 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 327 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
258 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), 328 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
259 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), 329 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
260 }, 330 },
261 &TyKind::Scalar(Scalar::Int(t)) => { 331 &TyKind::Scalar(Scalar::Int(t)) => {
262 lang_item_crate!(primitive::int_ty_to_string(t)) 332 lang_item_crate!(primitive::int_ty_to_string(t))
263 } 333 }
264 &TyKind::Scalar(Scalar::Uint(t)) => { 334 &TyKind::Scalar(Scalar::Uint(t)) => {
265 lang_item_crate!(primitive::uint_ty_to_string(t)) 335 lang_item_crate!(primitive::uint_ty_to_string(t))
266 } 336 }
267 TyKind::Str => lang_item_crate!("str_alloc", "str"), 337 TyKind::Str => lang_item_crate!("str_alloc", "str"),
268 TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"), 338 TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"),
269 TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), 339 TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"),
270 TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), 340 TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"),
271 TyKind::Dyn(_) => { 341 TyKind::Dyn(_) => {
272 return self.dyn_trait().and_then(|trait_| { 342 return ty.dyn_trait().and_then(|trait_| {
273 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) 343 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast()))
274 }); 344 });
275 } 345 }
276 _ => return None, 346 _ => return None,
277 }; 347 };
278 let res = lang_item_targets 348 let res = lang_item_targets
279 .into_iter() 349 .into_iter()
280 .filter_map(|it| match it { 350 .filter_map(|it| match it {
281 LangItemTarget::ImplDefId(it) => Some(it), 351 LangItemTarget::ImplDefId(it) => Some(it),
282 _ => None, 352 _ => None,
283 }) 353 })
284 .map(|it| it.lookup(db.upcast()).container.krate()) 354 .map(|it| it.lookup(db.upcast()).container.krate())
285 .collect(); 355 .collect();
286 Some(res) 356 Some(res)
287 }
288} 357}
289 358
290/// Look up the method with the given name, returning the actual autoderefed 359/// Look up the method with the given name, returning the actual autoderefed
@@ -453,7 +522,8 @@ fn iterate_method_candidates_with_autoref(
453 } 522 }
454 let refed = Canonical { 523 let refed = Canonical {
455 binders: deref_chain[0].binders.clone(), 524 binders: deref_chain[0].binders.clone(),
456 value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner), 525 value: TyKind::Ref(Mutability::Not, static_lifetime(), deref_chain[0].value.clone())
526 .intern(&Interner),
457 }; 527 };
458 if iterate_method_candidates_by_receiver( 528 if iterate_method_candidates_by_receiver(
459 &refed, 529 &refed,
@@ -470,7 +540,8 @@ fn iterate_method_candidates_with_autoref(
470 } 540 }
471 let ref_muted = Canonical { 541 let ref_muted = Canonical {
472 binders: deref_chain[0].binders.clone(), 542 binders: deref_chain[0].binders.clone(),
473 value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner), 543 value: TyKind::Ref(Mutability::Mut, static_lifetime(), deref_chain[0].value.clone())
544 .intern(&Interner),
474 }; 545 };
475 if iterate_method_candidates_by_receiver( 546 if iterate_method_candidates_by_receiver(
476 &ref_muted, 547 &ref_muted,
@@ -592,6 +663,7 @@ fn iterate_trait_method_candidates(
592 } 663 }
593 } 664 }
594 known_implemented = true; 665 known_implemented = true;
666 // FIXME: we shouldn't be ignoring the binders here
595 if callback(&self_ty.value, *item) { 667 if callback(&self_ty.value, *item) {
596 return true; 668 return true;
597 } 669 }
@@ -609,7 +681,7 @@ fn iterate_inherent_methods(
609 visible_from_module: Option<ModuleId>, 681 visible_from_module: Option<ModuleId>,
610 callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, 682 callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
611) -> bool { 683) -> bool {
612 let def_crates = match self_ty.value.def_crates(db, krate) { 684 let def_crates = match def_crates(db, &self_ty.value, krate) {
613 Some(k) => k, 685 Some(k) => k,
614 None => return false, 686 None => return false,
615 }; 687 };
@@ -709,10 +781,11 @@ pub(crate) fn inherent_impl_substs(
709) -> Option<Substitution> { 781) -> Option<Substitution> {
710 // we create a var for each type parameter of the impl; we need to keep in 782 // we create a var for each type parameter of the impl; we need to keep in
711 // mind here that `self_ty` might have vars of its own 783 // mind here that `self_ty` might have vars of its own
784 let self_ty_vars = self_ty.binders.len(&Interner);
712 let vars = TyBuilder::subst_for_def(db, impl_id) 785 let vars = TyBuilder::subst_for_def(db, impl_id)
713 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner)) 786 .fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty_vars)
714 .build(); 787 .build();
715 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); 788 let self_ty_with_vars = db.impl_self_ty(impl_id).substitute(&Interner, &vars);
716 let mut kinds = self_ty.binders.interned().to_vec(); 789 let mut kinds = self_ty.binders.interned().to_vec();
717 kinds.extend( 790 kinds.extend(
718 iter::repeat(chalk_ir::WithKind::new( 791 iter::repeat(chalk_ir::WithKind::new(
@@ -725,33 +798,27 @@ pub(crate) fn inherent_impl_substs(
725 binders: CanonicalVarKinds::from_iter(&Interner, kinds), 798 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
726 value: (self_ty_with_vars, self_ty.value.clone()), 799 value: (self_ty_with_vars, self_ty.value.clone()),
727 }; 800 };
728 let substs = super::infer::unify(&tys); 801 let substs = super::infer::unify(&tys)?;
729 // We only want the substs for the vars we added, not the ones from self_ty. 802 // We only want the substs for the vars we added, not the ones from self_ty.
730 // Also, if any of the vars we added are still in there, we replace them by 803 // Also, if any of the vars we added are still in there, we replace them by
731 // Unknown. I think this can only really happen if self_ty contained 804 // Unknown. I think this can only really happen if self_ty contained
732 // Unknown, and in that case we want the result to contain Unknown in those 805 // Unknown, and in that case we want the result to contain Unknown in those
733 // places again. 806 // places again.
734 substs 807 let suffix =
735 .map(|s| fallback_bound_vars(s.suffix(vars.len(&Interner)), self_ty.binders.len(&Interner))) 808 Substitution::from_iter(&Interner, substs.iter(&Interner).cloned().skip(self_ty_vars));
809 Some(fallback_bound_vars(suffix, self_ty_vars))
736} 810}
737 811
738/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past 812/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
739/// num_vars_to_keep) by `TyKind::Unknown`. 813/// num_vars_to_keep) by `TyKind::Unknown`.
740fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { 814fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution {
741 s.fold_binders( 815 crate::fold_free_vars(s, |bound, binders| {
742 &mut |ty, binders| { 816 if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
743 if let TyKind::BoundVar(bound) = ty.kind(&Interner) { 817 TyKind::Error.intern(&Interner)
744 if bound.index >= num_vars_to_keep && bound.debruijn >= binders { 818 } else {
745 TyKind::Unknown.intern(&Interner) 819 bound.shifted_in_from(binders).to_ty(&Interner)
746 } else { 820 }
747 ty 821 })
748 }
749 } else {
750 ty
751 }
752 },
753 DebruijnIndex::INNERMOST,
754 )
755} 822}
756 823
757fn transform_receiver_ty( 824fn transform_receiver_ty(
@@ -774,7 +841,7 @@ fn transform_receiver_ty(
774 AssocContainerId::ModuleId(_) => unreachable!(), 841 AssocContainerId::ModuleId(_) => unreachable!(),
775 }; 842 };
776 let sig = db.callable_item_signature(function_id.into()); 843 let sig = db.callable_item_signature(function_id.into());
777 Some(sig.value.params()[0].clone().subst_bound_vars(&substs)) 844 Some(sig.map(|s| s.params()[0].clone()).substitute(&Interner, &substs))
778} 845}
779 846
780pub fn implements_trait( 847pub fn implements_trait(
@@ -800,7 +867,7 @@ pub fn implements_trait_unique(
800 let goal = generic_implements_goal(db, env, trait_, ty.clone()); 867 let goal = generic_implements_goal(db, env, trait_, ty.clone());
801 let solution = db.trait_solve(krate, goal); 868 let solution = db.trait_solve(krate, goal);
802 869
803 matches!(solution, Some(crate::traits::Solution::Unique(_))) 870 matches!(solution, Some(crate::Solution::Unique(_)))
804} 871}
805 872
806/// This creates Substs for a trait with the given Self type and type variables 873/// This creates Substs for a trait with the given Self type and type variables
@@ -826,7 +893,7 @@ fn generic_implements_goal(
826 let obligation = trait_ref.cast(&Interner); 893 let obligation = trait_ref.cast(&Interner);
827 Canonical { 894 Canonical {
828 binders: CanonicalVarKinds::from_iter(&Interner, kinds), 895 binders: CanonicalVarKinds::from_iter(&Interner, kinds),
829 value: InEnvironment::new(env.env.clone(), obligation), 896 value: InEnvironment::new(&env.env, obligation),
830 } 897 }
831} 898}
832 899
@@ -837,7 +904,9 @@ fn autoderef_method_receiver(
837) -> Vec<Canonical<Ty>> { 904) -> Vec<Canonical<Ty>> {
838 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); 905 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect();
839 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) 906 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
840 if let Some(TyKind::Array(parameters)) = deref_chain.last().map(|ty| ty.value.kind(&Interner)) { 907 if let Some(TyKind::Array(parameters, _)) =
908 deref_chain.last().map(|ty| ty.value.kind(&Interner))
909 {
841 let kinds = deref_chain.last().unwrap().binders.clone(); 910 let kinds = deref_chain.last().unwrap().binders.clone();
842 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); 911 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner);
843 deref_chain.push(Canonical { value: unsized_ty, binders: kinds }) 912 deref_chain.push(Canonical { value: unsized_ty, binders: kinds })
diff --git a/crates/hir_ty/src/op.rs b/crates/hir_ty/src/op.rs
index 90dd31a35..0222de2bc 100644
--- a/crates/hir_ty/src/op.rs
+++ b/crates/hir_ty/src/op.rs
@@ -9,22 +9,56 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
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 { .. } => TyBuilder::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.kind(&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.kind(&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}
@@ -37,10 +71,10 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
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(_) }
@@ -50,7 +84,7 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
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/macros.rs b/crates/hir_ty/src/tests/macros.rs
index 86e3d8b86..6588aa46c 100644
--- a/crates/hir_ty/src/tests/macros.rs
+++ b/crates/hir_ty/src/tests/macros.rs
@@ -1065,12 +1065,211 @@ fn macro_in_arm() {
1065 } 1065 }
1066 "#, 1066 "#,
1067 expect![[r#" 1067 expect![[r#"
1068 !0..2 '()': ()
1068 51..110 '{ ... }; }': () 1069 51..110 '{ ... }; }': ()
1069 61..62 'x': u32 1070 61..62 'x': u32
1070 65..107 'match ... }': u32 1071 65..107 'match ... }': u32
1071 71..73 '()': () 1072 71..73 '()': ()
1072 84..91 'unit!()': ()
1073 95..100 '92u32': u32 1073 95..100 '92u32': u32
1074 "#]], 1074 "#]],
1075 ); 1075 );
1076} 1076}
1077
1078#[test]
1079fn macro_in_type_alias_position() {
1080 check_infer(
1081 r#"
1082 macro_rules! U32 {
1083 () => { u32 };
1084 }
1085
1086 trait Foo {
1087 type Ty;
1088 }
1089
1090 impl<T> Foo for T {
1091 type Ty = U32!();
1092 }
1093
1094 type TayTo = U32!();
1095
1096 fn testy() {
1097 let a: <() as Foo>::Ty;
1098 let b: TayTo;
1099 }
1100 "#,
1101 expect![[r#"
1102 147..196 '{ ...yTo; }': ()
1103 157..158 'a': u32
1104 185..186 'b': u32
1105 "#]],
1106 );
1107}
1108
1109#[test]
1110fn nested_macro_in_type_alias_position() {
1111 check_infer(
1112 r#"
1113 macro_rules! U32Inner2 {
1114 () => { u32 };
1115 }
1116
1117 macro_rules! U32Inner1 {
1118 () => { U32Inner2!() };
1119 }
1120
1121 macro_rules! U32 {
1122 () => { U32Inner1!() };
1123 }
1124
1125 trait Foo {
1126 type Ty;
1127 }
1128
1129 impl<T> Foo for T {
1130 type Ty = U32!();
1131 }
1132
1133 type TayTo = U32!();
1134
1135 fn testy() {
1136 let a: <() as Foo>::Ty;
1137 let b: TayTo;
1138 }
1139 "#,
1140 expect![[r#"
1141 259..308 '{ ...yTo; }': ()
1142 269..270 'a': u32
1143 297..298 'b': u32
1144 "#]],
1145 );
1146}
1147
1148#[test]
1149fn macros_in_type_alias_position_generics() {
1150 check_infer(
1151 r#"
1152 struct Foo<A, B>(A, B);
1153
1154 macro_rules! U32 {
1155 () => { u32 };
1156 }
1157
1158 macro_rules! Bar {
1159 () => { Foo<U32!(), U32!()> };
1160 }
1161
1162 trait Moo {
1163 type Ty;
1164 }
1165
1166 impl<T> Moo for T {
1167 type Ty = Bar!();
1168 }
1169
1170 type TayTo = Bar!();
1171
1172 fn main() {
1173 let a: <() as Moo>::Ty;
1174 let b: TayTo;
1175 }
1176 "#,
1177 expect![[r#"
1178 228..277 '{ ...yTo; }': ()
1179 238..239 'a': Foo<u32, u32>
1180 266..267 'b': Foo<u32, u32>
1181 "#]],
1182 );
1183}
1184
1185#[test]
1186fn macros_in_type_position() {
1187 check_infer(
1188 r#"
1189 struct Foo<A, B>(A, B);
1190
1191 macro_rules! U32 {
1192 () => { u32 };
1193 }
1194
1195 macro_rules! Bar {
1196 () => { Foo<U32!(), U32!()> };
1197 }
1198
1199 fn main() {
1200 let a: Bar!();
1201 }
1202 "#,
1203 expect![[r#"
1204 133..155 '{ ...!(); }': ()
1205 143..144 'a': Foo<u32, u32>
1206 "#]],
1207 );
1208}
1209
1210#[test]
1211fn macros_in_type_generics() {
1212 check_infer(
1213 r#"
1214 struct Foo<A, B>(A, B);
1215
1216 macro_rules! U32 {
1217 () => { u32 };
1218 }
1219
1220 macro_rules! Bar {
1221 () => { Foo<U32!(), U32!()> };
1222 }
1223
1224 trait Moo {
1225 type Ty;
1226 }
1227
1228 impl<T> Moo for T {
1229 type Ty = Foo<Bar!(), Bar!()>;
1230 }
1231
1232 type TayTo = Foo<Bar!(), U32!()>;
1233
1234 fn main() {
1235 let a: <() as Moo>::Ty;
1236 let b: TayTo;
1237 }
1238 "#,
1239 expect![[r#"
1240 254..303 '{ ...yTo; }': ()
1241 264..265 'a': Foo<Foo<u32, u32>, Foo<u32, u32>>
1242 292..293 'b': Foo<Foo<u32, u32>, u32>
1243 "#]],
1244 );
1245}
1246
1247#[test]
1248fn infinitely_recursive_macro_type() {
1249 check_infer(
1250 r#"
1251 struct Bar<T, X>(T, X);
1252
1253 macro_rules! Foo {
1254 () => { Foo!() }
1255 }
1256
1257 macro_rules! U32 {
1258 () => { u32 }
1259 }
1260
1261 type A = Foo!();
1262 type B = Bar<Foo!(), U32!()>;
1263
1264 fn main() {
1265 let a: A;
1266 let b: B;
1267 }
1268 "#,
1269 expect![[r#"
1270 166..197 '{ ...: B; }': ()
1271 176..177 'a': {unknown}
1272 190..191 'b': Bar<{unknown}, u32>
1273 "#]],
1274 );
1275}
diff --git a/crates/hir_ty/src/tests/method_resolution.rs b/crates/hir_ty/src/tests/method_resolution.rs
index 61f18b0d2..a4c132bc5 100644
--- a/crates/hir_ty/src/tests/method_resolution.rs
+++ b/crates/hir_ty/src/tests/method_resolution.rs
@@ -1292,3 +1292,60 @@ mod b {
1292 "#]], 1292 "#]],
1293 ) 1293 )
1294} 1294}
1295
1296#[test]
1297fn trait_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}
1317
1318#[test]
1319fn inherent_impl_in_unnamed_const() {
1320 check_types(
1321 r#"
1322struct S;
1323
1324const _: () = {
1325 impl S {
1326 fn method(&self) -> u16 { 0 }
1327
1328 pub(super) fn super_method(&self) -> u16 { 0 }
1329
1330 pub(crate) fn crate_method(&self) -> u16 { 0 }
1331
1332 pub fn pub_method(&self) -> u16 { 0 }
1333 }
1334};
1335
1336fn f() {
1337 S.method();
1338 //^^^^^^^^^^ u16
1339
1340 S.super_method();
1341 //^^^^^^^^^^^^^^^^ u16
1342
1343 S.crate_method();
1344 //^^^^^^^^^^^^^^^^ u16
1345
1346 S.pub_method();
1347 //^^^^^^^^^^^^^^ u16
1348}
1349 "#,
1350 );
1351}
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 65b71fdfa..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
@@ -3399,9 +3386,7 @@ impl foo::Bar for F {
3399fn foo() { 3386fn foo() {
3400 use foo::Bar; 3387 use foo::Bar;
3401 let x = <F as Bar>::boo(); 3388 let x = <F as Bar>::boo();
3402} 3389}"#,
3403
3404 "#,
3405 expect![[r#" 3390 expect![[r#"
3406 132..163 '{ ... }': Bar::Output<Self> 3391 132..163 '{ ... }': Bar::Output<Self>
3407 146..153 'loop {}': ! 3392 146..153 'loop {}': !
@@ -3413,3 +3398,79 @@ fn foo() {
3413 "#]], 3398 "#]],
3414 ); 3399 );
3415} 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 e5e8cff33..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.self_type_parameter().kind(&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 452b357e8..000000000
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ /dev/null
@@ -1,575 +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, GenericArg, 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(&Interner) - 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 GenericArg {
220 type Chalk = chalk_ir::GenericArg<Interner>;
221
222 fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk {
223 match self.interned {
224 crate::GenericArgData::Ty(ty) => ty.to_chalk(db).cast(&Interner),
225 }
226 }
227
228 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
229 match chalk.interned() {
230 chalk_ir::GenericArgData::Ty(ty) => Ty::from_chalk(db, ty.clone()).cast(&Interner),
231 chalk_ir::GenericArgData::Lifetime(_) => unimplemented!(),
232 chalk_ir::GenericArgData::Const(_) => unimplemented!(),
233 }
234 }
235}
236
237impl ToChalk for Substitution {
238 type Chalk = chalk_ir::Substitution<Interner>;
239
240 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
241 chalk_ir::Substitution::from_iter(
242 &Interner,
243 self.iter(&Interner).map(|ty| ty.clone().to_chalk(db)),
244 )
245 }
246
247 fn from_chalk(
248 db: &dyn HirDatabase,
249 parameters: chalk_ir::Substitution<Interner>,
250 ) -> Substitution {
251 let tys = parameters.iter(&Interner).map(|p| from_chalk(db, p.clone())).collect();
252 Substitution(tys)
253 }
254}
255
256impl ToChalk for TraitRef {
257 type Chalk = chalk_ir::TraitRef<Interner>;
258
259 fn to_chalk(self: TraitRef, db: &dyn HirDatabase) -> chalk_ir::TraitRef<Interner> {
260 let trait_id = self.trait_id;
261 let substitution = self.substitution.to_chalk(db);
262 chalk_ir::TraitRef { trait_id, substitution }
263 }
264
265 fn from_chalk(db: &dyn HirDatabase, trait_ref: chalk_ir::TraitRef<Interner>) -> Self {
266 let trait_id = trait_ref.trait_id;
267 let substs = from_chalk(db, trait_ref.substitution);
268 TraitRef { trait_id, substitution: substs }
269 }
270}
271
272impl ToChalk for hir_def::TraitId {
273 type Chalk = TraitId;
274
275 fn to_chalk(self, _db: &dyn HirDatabase) -> TraitId {
276 chalk_ir::TraitId(self.as_intern_id())
277 }
278
279 fn from_chalk(_db: &dyn HirDatabase, trait_id: TraitId) -> hir_def::TraitId {
280 InternKey::from_intern_id(trait_id.0)
281 }
282}
283
284impl ToChalk for hir_def::ImplId {
285 type Chalk = ImplId;
286
287 fn to_chalk(self, _db: &dyn HirDatabase) -> ImplId {
288 chalk_ir::ImplId(self.as_intern_id())
289 }
290
291 fn from_chalk(_db: &dyn HirDatabase, impl_id: ImplId) -> hir_def::ImplId {
292 InternKey::from_intern_id(impl_id.0)
293 }
294}
295
296impl ToChalk for CallableDefId {
297 type Chalk = FnDefId;
298
299 fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId {
300 db.intern_callable_def(self).into()
301 }
302
303 fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDefId {
304 db.lookup_intern_callable_def(fn_def_id.into())
305 }
306}
307
308pub(crate) struct TypeAliasAsValue(pub(crate) TypeAliasId);
309
310impl ToChalk for TypeAliasAsValue {
311 type Chalk = AssociatedTyValueId;
312
313 fn to_chalk(self, _db: &dyn HirDatabase) -> AssociatedTyValueId {
314 rust_ir::AssociatedTyValueId(self.0.as_intern_id())
315 }
316
317 fn from_chalk(
318 _db: &dyn HirDatabase,
319 assoc_ty_value_id: AssociatedTyValueId,
320 ) -> TypeAliasAsValue {
321 TypeAliasAsValue(TypeAliasId::from_intern_id(assoc_ty_value_id.0))
322 }
323}
324
325impl ToChalk for WhereClause {
326 type Chalk = chalk_ir::WhereClause<Interner>;
327
328 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::WhereClause<Interner> {
329 match self {
330 WhereClause::Implemented(trait_ref) => {
331 chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db))
332 }
333 WhereClause::AliasEq(alias_eq) => chalk_ir::WhereClause::AliasEq(alias_eq.to_chalk(db)),
334 }
335 }
336
337 fn from_chalk(
338 db: &dyn HirDatabase,
339 where_clause: chalk_ir::WhereClause<Interner>,
340 ) -> WhereClause {
341 match where_clause {
342 chalk_ir::WhereClause::Implemented(tr) => WhereClause::Implemented(from_chalk(db, tr)),
343 chalk_ir::WhereClause::AliasEq(alias_eq) => {
344 WhereClause::AliasEq(from_chalk(db, alias_eq))
345 }
346
347 chalk_ir::WhereClause::LifetimeOutlives(_) => {
348 // we shouldn't get these from Chalk
349 panic!("encountered LifetimeOutlives from Chalk")
350 }
351
352 chalk_ir::WhereClause::TypeOutlives(_) => {
353 // we shouldn't get these from Chalk
354 panic!("encountered TypeOutlives from Chalk")
355 }
356 }
357 }
358}
359
360impl ToChalk for ProjectionTy {
361 type Chalk = chalk_ir::ProjectionTy<Interner>;
362
363 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy<Interner> {
364 chalk_ir::ProjectionTy {
365 associated_ty_id: self.associated_ty_id,
366 substitution: self.substitution.to_chalk(db),
367 }
368 }
369
370 fn from_chalk(
371 db: &dyn HirDatabase,
372 projection_ty: chalk_ir::ProjectionTy<Interner>,
373 ) -> ProjectionTy {
374 ProjectionTy {
375 associated_ty_id: projection_ty.associated_ty_id,
376 substitution: from_chalk(db, projection_ty.substitution),
377 }
378 }
379}
380impl ToChalk for OpaqueTy {
381 type Chalk = chalk_ir::OpaqueTy<Interner>;
382
383 fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk {
384 chalk_ir::OpaqueTy {
385 opaque_ty_id: self.opaque_ty_id,
386 substitution: self.substitution.to_chalk(db),
387 }
388 }
389
390 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
391 OpaqueTy {
392 opaque_ty_id: chalk.opaque_ty_id,
393 substitution: from_chalk(db, chalk.substitution),
394 }
395 }
396}
397
398impl ToChalk for AliasTy {
399 type Chalk = chalk_ir::AliasTy<Interner>;
400
401 fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk {
402 match self {
403 AliasTy::Projection(projection_ty) => {
404 chalk_ir::AliasTy::Projection(projection_ty.to_chalk(db))
405 }
406 AliasTy::Opaque(opaque_ty) => chalk_ir::AliasTy::Opaque(opaque_ty.to_chalk(db)),
407 }
408 }
409
410 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
411 match chalk {
412 chalk_ir::AliasTy::Projection(projection_ty) => {
413 AliasTy::Projection(from_chalk(db, projection_ty))
414 }
415 chalk_ir::AliasTy::Opaque(opaque_ty) => AliasTy::Opaque(from_chalk(db, opaque_ty)),
416 }
417 }
418}
419
420impl ToChalk for AliasEq {
421 type Chalk = chalk_ir::AliasEq<Interner>;
422
423 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> {
424 chalk_ir::AliasEq { alias: self.alias.to_chalk(db), ty: self.ty.to_chalk(db) }
425 }
426
427 fn from_chalk(db: &dyn HirDatabase, alias_eq: chalk_ir::AliasEq<Interner>) -> Self {
428 AliasEq { alias: from_chalk(db, alias_eq.alias), ty: from_chalk(db, alias_eq.ty) }
429 }
430}
431
432impl ToChalk for DomainGoal {
433 type Chalk = chalk_ir::DomainGoal<Interner>;
434
435 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> {
436 match self {
437 DomainGoal::Holds(WhereClause::Implemented(tr)) => tr.to_chalk(db).cast(&Interner),
438 DomainGoal::Holds(WhereClause::AliasEq(alias_eq)) => {
439 alias_eq.to_chalk(db).cast(&Interner)
440 }
441 }
442 }
443
444 fn from_chalk(_db: &dyn HirDatabase, _goal: chalk_ir::DomainGoal<Interner>) -> Self {
445 unimplemented!()
446 }
447}
448
449impl<T> ToChalk for Canonical<T>
450where
451 T: ToChalk,
452 T::Chalk: HasInterner<Interner = Interner>,
453{
454 type Chalk = chalk_ir::Canonical<T::Chalk>;
455
456 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> {
457 let value = self.value.to_chalk(db);
458 chalk_ir::Canonical { value, binders: self.binders }
459 }
460
461 fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> {
462 Canonical { binders: canonical.binders, value: from_chalk(db, canonical.value) }
463 }
464}
465
466impl<T: ToChalk> ToChalk for InEnvironment<T>
467where
468 T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>,
469{
470 type Chalk = chalk_ir::InEnvironment<T::Chalk>;
471
472 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> {
473 chalk_ir::InEnvironment { environment: self.environment, goal: self.goal.to_chalk(db) }
474 }
475
476 fn from_chalk(
477 _db: &dyn HirDatabase,
478 _in_env: chalk_ir::InEnvironment<T::Chalk>,
479 ) -> InEnvironment<T> {
480 unimplemented!()
481 }
482}
483
484impl<T: ToChalk> ToChalk for crate::Binders<T>
485where
486 T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>,
487{
488 type Chalk = chalk_ir::Binders<T::Chalk>;
489
490 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Binders<T::Chalk> {
491 chalk_ir::Binders::new(
492 chalk_ir::VariableKinds::from_iter(
493 &Interner,
494 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
495 .take(self.num_binders),
496 ),
497 self.value.to_chalk(db),
498 )
499 }
500
501 fn from_chalk(db: &dyn HirDatabase, binders: chalk_ir::Binders<T::Chalk>) -> crate::Binders<T> {
502 let (v, b) = binders.into_value_and_skipped_binders();
503 crate::Binders::new(b.len(&Interner), from_chalk(db, v))
504 }
505}
506
507pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T>
508where
509 T: HasInterner<Interner = Interner>,
510{
511 chalk_ir::Binders::new(
512 chalk_ir::VariableKinds::from_iter(
513 &Interner,
514 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
515 .take(num_vars),
516 ),
517 value,
518 )
519}
520
521pub(super) fn convert_where_clauses(
522 db: &dyn HirDatabase,
523 def: GenericDefId,
524 substs: &Substitution,
525) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> {
526 let generic_predicates = db.generic_predicates(def);
527 let mut result = Vec::with_capacity(generic_predicates.len());
528 for pred in generic_predicates.iter() {
529 result.push(pred.clone().subst(substs).to_chalk(db));
530 }
531 result
532}
533
534pub(super) fn generic_predicate_to_inline_bound(
535 db: &dyn HirDatabase,
536 pred: &QuantifiedWhereClause,
537 self_ty: &Ty,
538) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> {
539 // An InlineBound is like a GenericPredicate, except the self type is left out.
540 // We don't have a special type for this, but Chalk does.
541 let self_ty_shifted_in = self_ty.clone().shift_bound_vars(DebruijnIndex::ONE);
542 match &pred.value {
543 WhereClause::Implemented(trait_ref) => {
544 if trait_ref.self_type_parameter() != &self_ty_shifted_in {
545 // we can only convert predicates back to type bounds if they
546 // have the expected self type
547 return None;
548 }
549 let args_no_self = trait_ref.substitution.interned(&Interner)[1..]
550 .iter()
551 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
552 .collect();
553 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
554 Some(make_binders(rust_ir::InlineBound::TraitBound(trait_bound), pred.num_binders))
555 }
556 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
557 if projection_ty.self_type_parameter() != &self_ty_shifted_in {
558 return None;
559 }
560 let trait_ = projection_ty.trait_(db);
561 let args_no_self = projection_ty.substitution.interned(&Interner)[1..]
562 .iter()
563 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
564 .collect();
565 let alias_eq_bound = rust_ir::AliasEqBound {
566 value: ty.clone().to_chalk(db),
567 trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self },
568 associated_ty_id: projection_ty.associated_ty_id,
569 parameters: Vec::new(), // FIXME we don't support generic associated types yet
570 };
571 Some(make_binders(rust_ir::InlineBound::AliasEqBound(alias_eq_bound), pred.num_binders))
572 }
573 _ => None,
574 }
575}
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index b23e91b1b..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::{BoundVar, 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, Interner, Substitution, TraitRef, TyKind, 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
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}