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