diff options
Diffstat (limited to 'crates/ra_hir_ty/src/lower.rs')
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 232 |
1 files changed, 110 insertions, 122 deletions
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 2c2ecee9c..87c984e3f 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs | |||
@@ -31,47 +31,50 @@ use crate::{ | |||
31 | Ty, TypeCtor, TypeWalk, | 31 | Ty, TypeCtor, TypeWalk, |
32 | }; | 32 | }; |
33 | 33 | ||
34 | #[derive(Clone, Debug)] | ||
35 | pub struct TyLoweringContext<'a, DB: HirDatabase> { | ||
36 | pub db: &'a DB, | ||
37 | pub resolver: &'a Resolver, | ||
38 | } | ||
39 | |||
34 | impl Ty { | 40 | impl Ty { |
35 | pub fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self { | 41 | pub fn from_hir(ctx: &TyLoweringContext<'_, impl HirDatabase>, type_ref: &TypeRef) -> Self { |
36 | match type_ref { | 42 | match type_ref { |
37 | TypeRef::Never => Ty::simple(TypeCtor::Never), | 43 | TypeRef::Never => Ty::simple(TypeCtor::Never), |
38 | TypeRef::Tuple(inner) => { | 44 | TypeRef::Tuple(inner) => { |
39 | let inner_tys: Arc<[Ty]> = | 45 | let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| Ty::from_hir(ctx, tr)).collect(); |
40 | inner.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect(); | ||
41 | Ty::apply( | 46 | Ty::apply( |
42 | TypeCtor::Tuple { cardinality: inner_tys.len() as u16 }, | 47 | TypeCtor::Tuple { cardinality: inner_tys.len() as u16 }, |
43 | Substs(inner_tys), | 48 | Substs(inner_tys), |
44 | ) | 49 | ) |
45 | } | 50 | } |
46 | TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path), | 51 | TypeRef::Path(path) => Ty::from_hir_path(ctx, path), |
47 | TypeRef::RawPtr(inner, mutability) => { | 52 | TypeRef::RawPtr(inner, mutability) => { |
48 | let inner_ty = Ty::from_hir(db, resolver, inner); | 53 | let inner_ty = Ty::from_hir(ctx, inner); |
49 | Ty::apply_one(TypeCtor::RawPtr(*mutability), inner_ty) | 54 | Ty::apply_one(TypeCtor::RawPtr(*mutability), inner_ty) |
50 | } | 55 | } |
51 | TypeRef::Array(inner) => { | 56 | TypeRef::Array(inner) => { |
52 | let inner_ty = Ty::from_hir(db, resolver, inner); | 57 | let inner_ty = Ty::from_hir(ctx, inner); |
53 | Ty::apply_one(TypeCtor::Array, inner_ty) | 58 | Ty::apply_one(TypeCtor::Array, inner_ty) |
54 | } | 59 | } |
55 | TypeRef::Slice(inner) => { | 60 | TypeRef::Slice(inner) => { |
56 | let inner_ty = Ty::from_hir(db, resolver, inner); | 61 | let inner_ty = Ty::from_hir(ctx, inner); |
57 | Ty::apply_one(TypeCtor::Slice, inner_ty) | 62 | Ty::apply_one(TypeCtor::Slice, inner_ty) |
58 | } | 63 | } |
59 | TypeRef::Reference(inner, mutability) => { | 64 | TypeRef::Reference(inner, mutability) => { |
60 | let inner_ty = Ty::from_hir(db, resolver, inner); | 65 | let inner_ty = Ty::from_hir(ctx, inner); |
61 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) | 66 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) |
62 | } | 67 | } |
63 | TypeRef::Placeholder => Ty::Unknown, | 68 | TypeRef::Placeholder => Ty::Unknown, |
64 | TypeRef::Fn(params) => { | 69 | TypeRef::Fn(params) => { |
65 | let sig = Substs(params.iter().map(|tr| Ty::from_hir(db, resolver, tr)).collect()); | 70 | let sig = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect()); |
66 | Ty::apply(TypeCtor::FnPtr { num_args: sig.len() as u16 - 1 }, sig) | 71 | Ty::apply(TypeCtor::FnPtr { num_args: sig.len() as u16 - 1 }, sig) |
67 | } | 72 | } |
68 | TypeRef::DynTrait(bounds) => { | 73 | TypeRef::DynTrait(bounds) => { |
69 | let self_ty = Ty::Bound(0); | 74 | let self_ty = Ty::Bound(0); |
70 | let predicates = bounds | 75 | let predicates = bounds |
71 | .iter() | 76 | .iter() |
72 | .flat_map(|b| { | 77 | .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone())) |
73 | GenericPredicate::from_type_bound(db, resolver, b, self_ty.clone()) | ||
74 | }) | ||
75 | .collect(); | 78 | .collect(); |
76 | Ty::Dyn(predicates) | 79 | Ty::Dyn(predicates) |
77 | } | 80 | } |
@@ -79,9 +82,7 @@ impl Ty { | |||
79 | let self_ty = Ty::Bound(0); | 82 | let self_ty = Ty::Bound(0); |
80 | let predicates = bounds | 83 | let predicates = bounds |
81 | .iter() | 84 | .iter() |
82 | .flat_map(|b| { | 85 | .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone())) |
83 | GenericPredicate::from_type_bound(db, resolver, b, self_ty.clone()) | ||
84 | }) | ||
85 | .collect(); | 86 | .collect(); |
86 | Ty::Opaque(predicates) | 87 | Ty::Opaque(predicates) |
87 | } | 88 | } |
@@ -93,8 +94,7 @@ impl Ty { | |||
93 | /// lower the self types of the predicates since that could lead to cycles. | 94 | /// lower the self types of the predicates since that could lead to cycles. |
94 | /// So we just check here if the `type_ref` resolves to a generic param, and which. | 95 | /// So we just check here if the `type_ref` resolves to a generic param, and which. |
95 | fn from_hir_only_param( | 96 | fn from_hir_only_param( |
96 | db: &impl HirDatabase, | 97 | ctx: &TyLoweringContext<'_, impl HirDatabase>, |
97 | resolver: &Resolver, | ||
98 | type_ref: &TypeRef, | 98 | type_ref: &TypeRef, |
99 | ) -> Option<u32> { | 99 | ) -> Option<u32> { |
100 | let path = match type_ref { | 100 | let path = match type_ref { |
@@ -107,12 +107,12 @@ impl Ty { | |||
107 | if path.segments().len() > 1 { | 107 | if path.segments().len() > 1 { |
108 | return None; | 108 | return None; |
109 | } | 109 | } |
110 | let resolution = match resolver.resolve_path_in_type_ns(db, path.mod_path()) { | 110 | let resolution = match ctx.resolver.resolve_path_in_type_ns(ctx.db, path.mod_path()) { |
111 | Some((it, None)) => it, | 111 | Some((it, None)) => it, |
112 | _ => return None, | 112 | _ => return None, |
113 | }; | 113 | }; |
114 | if let TypeNs::GenericParam(param_id) = resolution { | 114 | if let TypeNs::GenericParam(param_id) = resolution { |
115 | let generics = generics(db, resolver.generic_def().expect("generics in scope")); | 115 | let generics = generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope")); |
116 | let idx = generics.param_idx(param_id); | 116 | let idx = generics.param_idx(param_id); |
117 | Some(idx) | 117 | Some(idx) |
118 | } else { | 118 | } else { |
@@ -121,15 +121,14 @@ impl Ty { | |||
121 | } | 121 | } |
122 | 122 | ||
123 | pub(crate) fn from_type_relative_path( | 123 | pub(crate) fn from_type_relative_path( |
124 | db: &impl HirDatabase, | 124 | ctx: &TyLoweringContext<'_, impl HirDatabase>, |
125 | resolver: &Resolver, | ||
126 | ty: Ty, | 125 | ty: Ty, |
127 | remaining_segments: PathSegments<'_>, | 126 | remaining_segments: PathSegments<'_>, |
128 | ) -> Ty { | 127 | ) -> Ty { |
129 | if remaining_segments.len() == 1 { | 128 | if remaining_segments.len() == 1 { |
130 | // resolve unselected assoc types | 129 | // resolve unselected assoc types |
131 | let segment = remaining_segments.first().unwrap(); | 130 | let segment = remaining_segments.first().unwrap(); |
132 | Ty::select_associated_type(db, resolver, ty, segment) | 131 | Ty::select_associated_type(ctx, ty, segment) |
133 | } else if remaining_segments.len() > 1 { | 132 | } else if remaining_segments.len() > 1 { |
134 | // FIXME report error (ambiguous associated type) | 133 | // FIXME report error (ambiguous associated type) |
135 | Ty::Unknown | 134 | Ty::Unknown |
@@ -139,20 +138,18 @@ impl Ty { | |||
139 | } | 138 | } |
140 | 139 | ||
141 | pub(crate) fn from_partly_resolved_hir_path( | 140 | pub(crate) fn from_partly_resolved_hir_path( |
142 | db: &impl HirDatabase, | 141 | ctx: &TyLoweringContext<'_, impl HirDatabase>, |
143 | resolver: &Resolver, | ||
144 | resolution: TypeNs, | 142 | resolution: TypeNs, |
145 | resolved_segment: PathSegment<'_>, | 143 | resolved_segment: PathSegment<'_>, |
146 | remaining_segments: PathSegments<'_>, | 144 | remaining_segments: PathSegments<'_>, |
147 | ) -> Ty { | 145 | ) -> Ty { |
148 | let ty = match resolution { | 146 | let ty = match resolution { |
149 | TypeNs::TraitId(trait_) => { | 147 | TypeNs::TraitId(trait_) => { |
150 | let trait_ref = | 148 | let trait_ref = TraitRef::from_resolved_path(ctx, trait_, resolved_segment, None); |
151 | TraitRef::from_resolved_path(db, resolver, trait_, resolved_segment, None); | ||
152 | return if remaining_segments.len() == 1 { | 149 | return if remaining_segments.len() == 1 { |
153 | let segment = remaining_segments.first().unwrap(); | 150 | let segment = remaining_segments.first().unwrap(); |
154 | let associated_ty = associated_type_by_name_including_super_traits( | 151 | let associated_ty = associated_type_by_name_including_super_traits( |
155 | db, | 152 | ctx.db, |
156 | trait_ref.trait_, | 153 | trait_ref.trait_, |
157 | &segment.name, | 154 | &segment.name, |
158 | ); | 155 | ); |
@@ -177,37 +174,34 @@ impl Ty { | |||
177 | }; | 174 | }; |
178 | } | 175 | } |
179 | TypeNs::GenericParam(param_id) => { | 176 | TypeNs::GenericParam(param_id) => { |
180 | let generics = generics(db, resolver.generic_def().expect("generics in scope")); | 177 | let generics = |
178 | generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope")); | ||
181 | let idx = generics.param_idx(param_id); | 179 | let idx = generics.param_idx(param_id); |
182 | // FIXME: maybe return name in resolution? | 180 | // FIXME: maybe return name in resolution? |
183 | let name = generics.param_name(param_id); | 181 | let name = generics.param_name(param_id); |
184 | Ty::Param { idx, name } | 182 | Ty::Param { idx, name } |
185 | } | 183 | } |
186 | TypeNs::SelfType(impl_id) => db.impl_self_ty(impl_id).clone(), | 184 | TypeNs::SelfType(impl_id) => ctx.db.impl_self_ty(impl_id).clone(), |
187 | TypeNs::AdtSelfType(adt) => db.ty(adt.into()), | 185 | TypeNs::AdtSelfType(adt) => ctx.db.ty(adt.into()), |
188 | 186 | ||
189 | TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), | 187 | TypeNs::AdtId(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), |
190 | TypeNs::BuiltinType(it) => { | 188 | TypeNs::BuiltinType(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), |
191 | Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) | 189 | TypeNs::TypeAliasId(it) => Ty::from_hir_path_inner(ctx, resolved_segment, it.into()), |
192 | } | ||
193 | TypeNs::TypeAliasId(it) => { | ||
194 | Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) | ||
195 | } | ||
196 | // FIXME: report error | 190 | // FIXME: report error |
197 | TypeNs::EnumVariantId(_) => return Ty::Unknown, | 191 | TypeNs::EnumVariantId(_) => return Ty::Unknown, |
198 | }; | 192 | }; |
199 | 193 | ||
200 | Ty::from_type_relative_path(db, resolver, ty, remaining_segments) | 194 | Ty::from_type_relative_path(ctx, ty, remaining_segments) |
201 | } | 195 | } |
202 | 196 | ||
203 | pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Ty { | 197 | pub(crate) fn from_hir_path(ctx: &TyLoweringContext<'_, impl HirDatabase>, path: &Path) -> Ty { |
204 | // Resolve the path (in type namespace) | 198 | // Resolve the path (in type namespace) |
205 | if let Some(type_ref) = path.type_anchor() { | 199 | if let Some(type_ref) = path.type_anchor() { |
206 | let ty = Ty::from_hir(db, resolver, &type_ref); | 200 | let ty = Ty::from_hir(ctx, &type_ref); |
207 | return Ty::from_type_relative_path(db, resolver, ty, path.segments()); | 201 | return Ty::from_type_relative_path(ctx, ty, path.segments()); |
208 | } | 202 | } |
209 | let (resolution, remaining_index) = | 203 | let (resolution, remaining_index) = |
210 | match resolver.resolve_path_in_type_ns(db, path.mod_path()) { | 204 | match ctx.resolver.resolve_path_in_type_ns(ctx.db, path.mod_path()) { |
211 | Some(it) => it, | 205 | Some(it) => it, |
212 | None => return Ty::Unknown, | 206 | None => return Ty::Unknown, |
213 | }; | 207 | }; |
@@ -218,18 +212,11 @@ impl Ty { | |||
218 | ), | 212 | ), |
219 | Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)), | 213 | Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)), |
220 | }; | 214 | }; |
221 | Ty::from_partly_resolved_hir_path( | 215 | Ty::from_partly_resolved_hir_path(ctx, resolution, resolved_segment, remaining_segments) |
222 | db, | ||
223 | resolver, | ||
224 | resolution, | ||
225 | resolved_segment, | ||
226 | remaining_segments, | ||
227 | ) | ||
228 | } | 216 | } |
229 | 217 | ||
230 | fn select_associated_type( | 218 | fn select_associated_type( |
231 | db: &impl HirDatabase, | 219 | ctx: &TyLoweringContext<'_, impl HirDatabase>, |
232 | resolver: &Resolver, | ||
233 | self_ty: Ty, | 220 | self_ty: Ty, |
234 | segment: PathSegment<'_>, | 221 | segment: PathSegment<'_>, |
235 | ) -> Ty { | 222 | ) -> Ty { |
@@ -237,20 +224,23 @@ impl Ty { | |||
237 | Ty::Param { idx, .. } => idx, | 224 | Ty::Param { idx, .. } => idx, |
238 | _ => return Ty::Unknown, // Error: Ambiguous associated type | 225 | _ => return Ty::Unknown, // Error: Ambiguous associated type |
239 | }; | 226 | }; |
240 | let def = match resolver.generic_def() { | 227 | let def = match ctx.resolver.generic_def() { |
241 | Some(def) => def, | 228 | Some(def) => def, |
242 | None => return Ty::Unknown, // this can't actually happen | 229 | None => return Ty::Unknown, // this can't actually happen |
243 | }; | 230 | }; |
244 | let predicates = db.generic_predicates_for_param(def.into(), param_idx); | 231 | let predicates = ctx.db.generic_predicates_for_param(def.into(), param_idx); |
245 | let traits_from_env = predicates.iter().filter_map(|pred| match pred { | 232 | let traits_from_env = predicates.iter().filter_map(|pred| match pred { |
246 | GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), | 233 | GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), |
247 | _ => None, | 234 | _ => None, |
248 | }); | 235 | }); |
249 | let traits = traits_from_env.flat_map(|t| all_super_traits(db, t)); | 236 | let traits = traits_from_env.flat_map(|t| all_super_traits(ctx.db, t)); |
250 | for t in traits { | 237 | for t in traits { |
251 | if let Some(associated_ty) = db.trait_data(t).associated_type_by_name(&segment.name) { | 238 | if let Some(associated_ty) = ctx.db.trait_data(t).associated_type_by_name(&segment.name) |
252 | let substs = | 239 | { |
253 | Substs::build_for_def(db, t).push(self_ty.clone()).fill_with_unknown().build(); | 240 | let substs = Substs::build_for_def(ctx.db, t) |
241 | .push(self_ty.clone()) | ||
242 | .fill_with_unknown() | ||
243 | .build(); | ||
254 | // FIXME handle type parameters on the segment | 244 | // FIXME handle type parameters on the segment |
255 | return Ty::Projection(ProjectionTy { associated_ty, parameters: substs }); | 245 | return Ty::Projection(ProjectionTy { associated_ty, parameters: substs }); |
256 | } | 246 | } |
@@ -259,8 +249,7 @@ impl Ty { | |||
259 | } | 249 | } |
260 | 250 | ||
261 | fn from_hir_path_inner( | 251 | fn from_hir_path_inner( |
262 | db: &impl HirDatabase, | 252 | ctx: &TyLoweringContext<'_, impl HirDatabase>, |
263 | resolver: &Resolver, | ||
264 | segment: PathSegment<'_>, | 253 | segment: PathSegment<'_>, |
265 | typable: TyDefId, | 254 | typable: TyDefId, |
266 | ) -> Ty { | 255 | ) -> Ty { |
@@ -269,15 +258,14 @@ impl Ty { | |||
269 | TyDefId::AdtId(it) => Some(it.into()), | 258 | TyDefId::AdtId(it) => Some(it.into()), |
270 | TyDefId::TypeAliasId(it) => Some(it.into()), | 259 | TyDefId::TypeAliasId(it) => Some(it.into()), |
271 | }; | 260 | }; |
272 | let substs = substs_from_path_segment(db, resolver, segment, generic_def, false); | 261 | let substs = substs_from_path_segment(ctx, segment, generic_def, false); |
273 | db.ty(typable).subst(&substs) | 262 | ctx.db.ty(typable).subst(&substs) |
274 | } | 263 | } |
275 | 264 | ||
276 | /// Collect generic arguments from a path into a `Substs`. See also | 265 | /// Collect generic arguments from a path into a `Substs`. See also |
277 | /// `create_substs_for_ast_path` and `def_to_ty` in rustc. | 266 | /// `create_substs_for_ast_path` and `def_to_ty` in rustc. |
278 | pub(super) fn substs_from_path( | 267 | pub(super) fn substs_from_path( |
279 | db: &impl HirDatabase, | 268 | ctx: &TyLoweringContext<'_, impl HirDatabase>, |
280 | resolver: &Resolver, | ||
281 | path: &Path, | 269 | path: &Path, |
282 | // Note that we don't call `db.value_type(resolved)` here, | 270 | // Note that we don't call `db.value_type(resolved)` here, |
283 | // `ValueTyDefId` is just a convenient way to pass generics and | 271 | // `ValueTyDefId` is just a convenient way to pass generics and |
@@ -305,19 +293,18 @@ impl Ty { | |||
305 | (segment, Some(var.parent.into())) | 293 | (segment, Some(var.parent.into())) |
306 | } | 294 | } |
307 | }; | 295 | }; |
308 | substs_from_path_segment(db, resolver, segment, generic_def, false) | 296 | substs_from_path_segment(ctx, segment, generic_def, false) |
309 | } | 297 | } |
310 | } | 298 | } |
311 | 299 | ||
312 | pub(super) fn substs_from_path_segment( | 300 | pub(super) fn substs_from_path_segment( |
313 | db: &impl HirDatabase, | 301 | ctx: &TyLoweringContext<'_, impl HirDatabase>, |
314 | resolver: &Resolver, | ||
315 | segment: PathSegment<'_>, | 302 | segment: PathSegment<'_>, |
316 | def_generic: Option<GenericDefId>, | 303 | def_generic: Option<GenericDefId>, |
317 | add_self_param: bool, | 304 | add_self_param: bool, |
318 | ) -> Substs { | 305 | ) -> Substs { |
319 | let mut substs = Vec::new(); | 306 | let mut substs = Vec::new(); |
320 | let def_generics = def_generic.map(|def| generics(db, def.into())); | 307 | let def_generics = def_generic.map(|def| generics(ctx.db, def.into())); |
321 | 308 | ||
322 | let (total_len, parent_len, child_len) = def_generics.map_or((0, 0, 0), |g| g.len_split()); | 309 | let (total_len, parent_len, child_len) = def_generics.map_or((0, 0, 0), |g| g.len_split()); |
323 | substs.extend(iter::repeat(Ty::Unknown).take(parent_len)); | 310 | substs.extend(iter::repeat(Ty::Unknown).take(parent_len)); |
@@ -335,7 +322,7 @@ pub(super) fn substs_from_path_segment( | |||
335 | for arg in generic_args.args.iter().take(child_len) { | 322 | for arg in generic_args.args.iter().take(child_len) { |
336 | match arg { | 323 | match arg { |
337 | GenericArg::Type(type_ref) => { | 324 | GenericArg::Type(type_ref) => { |
338 | let ty = Ty::from_hir(db, resolver, type_ref); | 325 | let ty = Ty::from_hir(ctx, type_ref); |
339 | substs.push(ty); | 326 | substs.push(ty); |
340 | } | 327 | } |
341 | } | 328 | } |
@@ -350,7 +337,7 @@ pub(super) fn substs_from_path_segment( | |||
350 | 337 | ||
351 | // handle defaults | 338 | // handle defaults |
352 | if let Some(def_generic) = def_generic { | 339 | if let Some(def_generic) = def_generic { |
353 | let default_substs = db.generic_defaults(def_generic.into()); | 340 | let default_substs = ctx.db.generic_defaults(def_generic.into()); |
354 | assert_eq!(substs.len(), default_substs.len()); | 341 | assert_eq!(substs.len(), default_substs.len()); |
355 | 342 | ||
356 | for (i, default_ty) in default_substs.iter().enumerate() { | 343 | for (i, default_ty) in default_substs.iter().enumerate() { |
@@ -365,27 +352,25 @@ pub(super) fn substs_from_path_segment( | |||
365 | 352 | ||
366 | impl TraitRef { | 353 | impl TraitRef { |
367 | fn from_path( | 354 | fn from_path( |
368 | db: &impl HirDatabase, | 355 | ctx: &TyLoweringContext<'_, impl HirDatabase>, |
369 | resolver: &Resolver, | ||
370 | path: &Path, | 356 | path: &Path, |
371 | explicit_self_ty: Option<Ty>, | 357 | explicit_self_ty: Option<Ty>, |
372 | ) -> Option<Self> { | 358 | ) -> Option<Self> { |
373 | let resolved = match resolver.resolve_path_in_type_ns_fully(db, path.mod_path())? { | 359 | let resolved = match ctx.resolver.resolve_path_in_type_ns_fully(ctx.db, path.mod_path())? { |
374 | TypeNs::TraitId(tr) => tr, | 360 | TypeNs::TraitId(tr) => tr, |
375 | _ => return None, | 361 | _ => return None, |
376 | }; | 362 | }; |
377 | let segment = path.segments().last().expect("path should have at least one segment"); | 363 | let segment = path.segments().last().expect("path should have at least one segment"); |
378 | Some(TraitRef::from_resolved_path(db, resolver, resolved.into(), segment, explicit_self_ty)) | 364 | Some(TraitRef::from_resolved_path(ctx, resolved.into(), segment, explicit_self_ty)) |
379 | } | 365 | } |
380 | 366 | ||
381 | pub(crate) fn from_resolved_path( | 367 | pub(crate) fn from_resolved_path( |
382 | db: &impl HirDatabase, | 368 | ctx: &TyLoweringContext<'_, impl HirDatabase>, |
383 | resolver: &Resolver, | ||
384 | resolved: TraitId, | 369 | resolved: TraitId, |
385 | segment: PathSegment<'_>, | 370 | segment: PathSegment<'_>, |
386 | explicit_self_ty: Option<Ty>, | 371 | explicit_self_ty: Option<Ty>, |
387 | ) -> Self { | 372 | ) -> Self { |
388 | let mut substs = TraitRef::substs_from_path(db, resolver, segment, resolved); | 373 | let mut substs = TraitRef::substs_from_path(ctx, segment, resolved); |
389 | if let Some(self_ty) = explicit_self_ty { | 374 | if let Some(self_ty) = explicit_self_ty { |
390 | make_mut_slice(&mut substs.0)[0] = self_ty; | 375 | make_mut_slice(&mut substs.0)[0] = self_ty; |
391 | } | 376 | } |
@@ -393,8 +378,7 @@ impl TraitRef { | |||
393 | } | 378 | } |
394 | 379 | ||
395 | fn from_hir( | 380 | fn from_hir( |
396 | db: &impl HirDatabase, | 381 | ctx: &TyLoweringContext<'_, impl HirDatabase>, |
397 | resolver: &Resolver, | ||
398 | type_ref: &TypeRef, | 382 | type_ref: &TypeRef, |
399 | explicit_self_ty: Option<Ty>, | 383 | explicit_self_ty: Option<Ty>, |
400 | ) -> Option<Self> { | 384 | ) -> Option<Self> { |
@@ -402,28 +386,26 @@ impl TraitRef { | |||
402 | TypeRef::Path(path) => path, | 386 | TypeRef::Path(path) => path, |
403 | _ => return None, | 387 | _ => return None, |
404 | }; | 388 | }; |
405 | TraitRef::from_path(db, resolver, path, explicit_self_ty) | 389 | TraitRef::from_path(ctx, path, explicit_self_ty) |
406 | } | 390 | } |
407 | 391 | ||
408 | fn substs_from_path( | 392 | fn substs_from_path( |
409 | db: &impl HirDatabase, | 393 | ctx: &TyLoweringContext<'_, impl HirDatabase>, |
410 | resolver: &Resolver, | ||
411 | segment: PathSegment<'_>, | 394 | segment: PathSegment<'_>, |
412 | resolved: TraitId, | 395 | resolved: TraitId, |
413 | ) -> Substs { | 396 | ) -> Substs { |
414 | let has_self_param = | 397 | let has_self_param = |
415 | segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false); | 398 | segment.args_and_bindings.as_ref().map(|a| a.has_self_type).unwrap_or(false); |
416 | substs_from_path_segment(db, resolver, segment, Some(resolved.into()), !has_self_param) | 399 | substs_from_path_segment(ctx, segment, Some(resolved.into()), !has_self_param) |
417 | } | 400 | } |
418 | 401 | ||
419 | pub(crate) fn from_type_bound( | 402 | pub(crate) fn from_type_bound( |
420 | db: &impl HirDatabase, | 403 | ctx: &TyLoweringContext<'_, impl HirDatabase>, |
421 | resolver: &Resolver, | ||
422 | bound: &TypeBound, | 404 | bound: &TypeBound, |
423 | self_ty: Ty, | 405 | self_ty: Ty, |
424 | ) -> Option<TraitRef> { | 406 | ) -> Option<TraitRef> { |
425 | match bound { | 407 | match bound { |
426 | TypeBound::Path(path) => TraitRef::from_path(db, resolver, path, Some(self_ty)), | 408 | TypeBound::Path(path) => TraitRef::from_path(ctx, path, Some(self_ty)), |
427 | TypeBound::Error => None, | 409 | TypeBound::Error => None, |
428 | } | 410 | } |
429 | } | 411 | } |
@@ -431,33 +413,30 @@ impl TraitRef { | |||
431 | 413 | ||
432 | impl GenericPredicate { | 414 | impl GenericPredicate { |
433 | pub(crate) fn from_where_predicate<'a>( | 415 | pub(crate) fn from_where_predicate<'a>( |
434 | db: &'a impl HirDatabase, | 416 | ctx: &'a TyLoweringContext<'a, impl HirDatabase>, |
435 | resolver: &'a Resolver, | ||
436 | where_predicate: &'a WherePredicate, | 417 | where_predicate: &'a WherePredicate, |
437 | ) -> impl Iterator<Item = GenericPredicate> + 'a { | 418 | ) -> impl Iterator<Item = GenericPredicate> + 'a { |
438 | let self_ty = Ty::from_hir(db, resolver, &where_predicate.type_ref); | 419 | let self_ty = Ty::from_hir(ctx, &where_predicate.type_ref); |
439 | GenericPredicate::from_type_bound(db, resolver, &where_predicate.bound, self_ty) | 420 | GenericPredicate::from_type_bound(ctx, &where_predicate.bound, self_ty) |
440 | } | 421 | } |
441 | 422 | ||
442 | pub(crate) fn from_type_bound<'a>( | 423 | pub(crate) fn from_type_bound<'a>( |
443 | db: &'a impl HirDatabase, | 424 | ctx: &'a TyLoweringContext<'a, impl HirDatabase>, |
444 | resolver: &'a Resolver, | ||
445 | bound: &'a TypeBound, | 425 | bound: &'a TypeBound, |
446 | self_ty: Ty, | 426 | self_ty: Ty, |
447 | ) -> impl Iterator<Item = GenericPredicate> + 'a { | 427 | ) -> impl Iterator<Item = GenericPredicate> + 'a { |
448 | let trait_ref = TraitRef::from_type_bound(db, &resolver, bound, self_ty); | 428 | let trait_ref = TraitRef::from_type_bound(ctx, bound, self_ty); |
449 | iter::once(trait_ref.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented)) | 429 | iter::once(trait_ref.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented)) |
450 | .chain( | 430 | .chain( |
451 | trait_ref.into_iter().flat_map(move |tr| { | 431 | trait_ref |
452 | assoc_type_bindings_from_type_bound(db, resolver, bound, tr) | 432 | .into_iter() |
453 | }), | 433 | .flat_map(move |tr| assoc_type_bindings_from_type_bound(ctx, bound, tr)), |
454 | ) | 434 | ) |
455 | } | 435 | } |
456 | } | 436 | } |
457 | 437 | ||
458 | fn assoc_type_bindings_from_type_bound<'a>( | 438 | fn assoc_type_bindings_from_type_bound<'a>( |
459 | db: &'a impl HirDatabase, | 439 | ctx: &'a TyLoweringContext<'a, impl HirDatabase>, |
460 | resolver: &'a Resolver, | ||
461 | bound: &'a TypeBound, | 440 | bound: &'a TypeBound, |
462 | trait_ref: TraitRef, | 441 | trait_ref: TraitRef, |
463 | ) -> impl Iterator<Item = GenericPredicate> + 'a { | 442 | ) -> impl Iterator<Item = GenericPredicate> + 'a { |
@@ -471,14 +450,14 @@ fn assoc_type_bindings_from_type_bound<'a>( | |||
471 | .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) | 450 | .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) |
472 | .map(move |(name, type_ref)| { | 451 | .map(move |(name, type_ref)| { |
473 | let associated_ty = | 452 | let associated_ty = |
474 | associated_type_by_name_including_super_traits(db, trait_ref.trait_, &name); | 453 | associated_type_by_name_including_super_traits(ctx.db, trait_ref.trait_, &name); |
475 | let associated_ty = match associated_ty { | 454 | let associated_ty = match associated_ty { |
476 | None => return GenericPredicate::Error, | 455 | None => return GenericPredicate::Error, |
477 | Some(t) => t, | 456 | Some(t) => t, |
478 | }; | 457 | }; |
479 | let projection_ty = | 458 | let projection_ty = |
480 | ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() }; | 459 | ProjectionTy { associated_ty, parameters: trait_ref.substs.clone() }; |
481 | let ty = Ty::from_hir(db, resolver, type_ref); | 460 | let ty = Ty::from_hir(ctx, type_ref); |
482 | let projection_predicate = ProjectionPredicate { projection_ty, ty }; | 461 | let projection_predicate = ProjectionPredicate { projection_ty, ty }; |
483 | GenericPredicate::Projection(projection_predicate) | 462 | GenericPredicate::Projection(projection_predicate) |
484 | }) | 463 | }) |
@@ -505,8 +484,9 @@ pub(crate) fn field_types_query( | |||
505 | VariantId::EnumVariantId(it) => it.parent.resolver(db), | 484 | VariantId::EnumVariantId(it) => it.parent.resolver(db), |
506 | }; | 485 | }; |
507 | let mut res = ArenaMap::default(); | 486 | let mut res = ArenaMap::default(); |
487 | let ctx = TyLoweringContext { db, resolver: &resolver }; | ||
508 | for (field_id, field_data) in var_data.fields().iter() { | 488 | for (field_id, field_data) in var_data.fields().iter() { |
509 | res.insert(field_id, Ty::from_hir(db, &resolver, &field_data.type_ref)) | 489 | res.insert(field_id, Ty::from_hir(&ctx, &field_data.type_ref)) |
510 | } | 490 | } |
511 | Arc::new(res) | 491 | Arc::new(res) |
512 | } | 492 | } |
@@ -525,11 +505,12 @@ pub(crate) fn generic_predicates_for_param_query( | |||
525 | param_idx: u32, | 505 | param_idx: u32, |
526 | ) -> Arc<[GenericPredicate]> { | 506 | ) -> Arc<[GenericPredicate]> { |
527 | let resolver = def.resolver(db); | 507 | let resolver = def.resolver(db); |
508 | let ctx = TyLoweringContext { db, resolver: &resolver }; | ||
528 | resolver | 509 | resolver |
529 | .where_predicates_in_scope() | 510 | .where_predicates_in_scope() |
530 | // we have to filter out all other predicates *first*, before attempting to lower them | 511 | // we have to filter out all other predicates *first*, before attempting to lower them |
531 | .filter(|pred| Ty::from_hir_only_param(db, &resolver, &pred.type_ref) == Some(param_idx)) | 512 | .filter(|pred| Ty::from_hir_only_param(&ctx, &pred.type_ref) == Some(param_idx)) |
532 | .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) | 513 | .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) |
533 | .collect() | 514 | .collect() |
534 | } | 515 | } |
535 | 516 | ||
@@ -543,10 +524,11 @@ pub(crate) fn generic_predicates_for_param_recover( | |||
543 | } | 524 | } |
544 | 525 | ||
545 | impl TraitEnvironment { | 526 | impl TraitEnvironment { |
546 | pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { | 527 | pub fn lower(ctx: &TyLoweringContext<'_, impl HirDatabase>) -> Arc<TraitEnvironment> { |
547 | let predicates = resolver | 528 | let predicates = ctx |
529 | .resolver | ||
548 | .where_predicates_in_scope() | 530 | .where_predicates_in_scope() |
549 | .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) | 531 | .flat_map(|pred| GenericPredicate::from_where_predicate(ctx, pred)) |
550 | .collect::<Vec<_>>(); | 532 | .collect::<Vec<_>>(); |
551 | 533 | ||
552 | Arc::new(TraitEnvironment { predicates }) | 534 | Arc::new(TraitEnvironment { predicates }) |
@@ -559,20 +541,22 @@ pub(crate) fn generic_predicates_query( | |||
559 | def: GenericDefId, | 541 | def: GenericDefId, |
560 | ) -> Arc<[GenericPredicate]> { | 542 | ) -> Arc<[GenericPredicate]> { |
561 | let resolver = def.resolver(db); | 543 | let resolver = def.resolver(db); |
544 | let ctx = TyLoweringContext { db, resolver: &resolver }; | ||
562 | resolver | 545 | resolver |
563 | .where_predicates_in_scope() | 546 | .where_predicates_in_scope() |
564 | .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) | 547 | .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) |
565 | .collect() | 548 | .collect() |
566 | } | 549 | } |
567 | 550 | ||
568 | /// Resolve the default type params from generics | 551 | /// Resolve the default type params from generics |
569 | pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs { | 552 | pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs { |
570 | let resolver = def.resolver(db); | 553 | let resolver = def.resolver(db); |
554 | let ctx = TyLoweringContext { db, resolver: &resolver }; | ||
571 | let generic_params = generics(db, def.into()); | 555 | let generic_params = generics(db, def.into()); |
572 | 556 | ||
573 | let defaults = generic_params | 557 | let defaults = generic_params |
574 | .iter() | 558 | .iter() |
575 | .map(|(_idx, p)| p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(db, &resolver, t))) | 559 | .map(|(_idx, p)| p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(&ctx, t))) |
576 | .collect(); | 560 | .collect(); |
577 | 561 | ||
578 | Substs(defaults) | 562 | Substs(defaults) |
@@ -581,8 +565,9 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) - | |||
581 | fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig { | 565 | fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig { |
582 | let data = db.function_data(def); | 566 | let data = db.function_data(def); |
583 | let resolver = def.resolver(db); | 567 | let resolver = def.resolver(db); |
584 | let params = data.params.iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>(); | 568 | let ctx = TyLoweringContext { db, resolver: &resolver }; |
585 | let ret = Ty::from_hir(db, &resolver, &data.ret_type); | 569 | let params = data.params.iter().map(|tr| Ty::from_hir(&ctx, tr)).collect::<Vec<_>>(); |
570 | let ret = Ty::from_hir(&ctx, &data.ret_type); | ||
586 | FnSig::from_params_and_return(params, ret) | 571 | FnSig::from_params_and_return(params, ret) |
587 | } | 572 | } |
588 | 573 | ||
@@ -598,16 +583,18 @@ fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Ty { | |||
598 | fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Ty { | 583 | fn type_for_const(db: &impl HirDatabase, def: ConstId) -> Ty { |
599 | let data = db.const_data(def); | 584 | let data = db.const_data(def); |
600 | let resolver = def.resolver(db); | 585 | let resolver = def.resolver(db); |
586 | let ctx = TyLoweringContext { db, resolver: &resolver }; | ||
601 | 587 | ||
602 | Ty::from_hir(db, &resolver, &data.type_ref) | 588 | Ty::from_hir(&ctx, &data.type_ref) |
603 | } | 589 | } |
604 | 590 | ||
605 | /// Build the declared type of a static. | 591 | /// Build the declared type of a static. |
606 | fn type_for_static(db: &impl HirDatabase, def: StaticId) -> Ty { | 592 | fn type_for_static(db: &impl HirDatabase, def: StaticId) -> Ty { |
607 | let data = db.static_data(def); | 593 | let data = db.static_data(def); |
608 | let resolver = def.resolver(db); | 594 | let resolver = def.resolver(db); |
595 | let ctx = TyLoweringContext { db, resolver: &resolver }; | ||
609 | 596 | ||
610 | Ty::from_hir(db, &resolver, &data.type_ref) | 597 | Ty::from_hir(&ctx, &data.type_ref) |
611 | } | 598 | } |
612 | 599 | ||
613 | /// Build the declared type of a static. | 600 | /// Build the declared type of a static. |
@@ -625,10 +612,9 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig | |||
625 | let struct_data = db.struct_data(def.into()); | 612 | let struct_data = db.struct_data(def.into()); |
626 | let fields = struct_data.variant_data.fields(); | 613 | let fields = struct_data.variant_data.fields(); |
627 | let resolver = def.resolver(db); | 614 | let resolver = def.resolver(db); |
628 | let params = fields | 615 | let ctx = TyLoweringContext { db, resolver: &resolver }; |
629 | .iter() | 616 | let params = |
630 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) | 617 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); |
631 | .collect::<Vec<_>>(); | ||
632 | let ret = type_for_adt(db, def.into()); | 618 | let ret = type_for_adt(db, def.into()); |
633 | FnSig::from_params_and_return(params, ret) | 619 | FnSig::from_params_and_return(params, ret) |
634 | } | 620 | } |
@@ -649,10 +635,9 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId | |||
649 | let var_data = &enum_data.variants[def.local_id]; | 635 | let var_data = &enum_data.variants[def.local_id]; |
650 | let fields = var_data.variant_data.fields(); | 636 | let fields = var_data.variant_data.fields(); |
651 | let resolver = def.parent.resolver(db); | 637 | let resolver = def.parent.resolver(db); |
652 | let params = fields | 638 | let ctx = TyLoweringContext { db, resolver: &resolver }; |
653 | .iter() | 639 | let params = |
654 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) | 640 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); |
655 | .collect::<Vec<_>>(); | ||
656 | let generics = generics(db, def.parent.into()); | 641 | let generics = generics(db, def.parent.into()); |
657 | let substs = Substs::identity(&generics); | 642 | let substs = Substs::identity(&generics); |
658 | let ret = type_for_adt(db, def.parent.into()).subst(&substs); | 643 | let ret = type_for_adt(db, def.parent.into()).subst(&substs); |
@@ -679,9 +664,10 @@ fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Ty { | |||
679 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty { | 664 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty { |
680 | let generics = generics(db, t.into()); | 665 | let generics = generics(db, t.into()); |
681 | let resolver = t.resolver(db); | 666 | let resolver = t.resolver(db); |
667 | let ctx = TyLoweringContext { db, resolver: &resolver }; | ||
682 | let type_ref = &db.type_alias_data(t).type_ref; | 668 | let type_ref = &db.type_alias_data(t).type_ref; |
683 | let substs = Substs::identity(&generics); | 669 | let substs = Substs::identity(&generics); |
684 | let inner = Ty::from_hir(db, &resolver, type_ref.as_ref().unwrap_or(&TypeRef::Error)); | 670 | let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error)); |
685 | inner.subst(&substs) | 671 | inner.subst(&substs) |
686 | } | 672 | } |
687 | 673 | ||
@@ -761,7 +747,8 @@ pub(crate) fn value_ty_query(db: &impl HirDatabase, def: ValueTyDefId) -> Ty { | |||
761 | pub(crate) fn impl_self_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> Ty { | 747 | pub(crate) fn impl_self_ty_query(db: &impl HirDatabase, impl_id: ImplId) -> Ty { |
762 | let impl_data = db.impl_data(impl_id); | 748 | let impl_data = db.impl_data(impl_id); |
763 | let resolver = impl_id.resolver(db); | 749 | let resolver = impl_id.resolver(db); |
764 | Ty::from_hir(db, &resolver, &impl_data.target_type) | 750 | let ctx = TyLoweringContext { db, resolver: &resolver }; |
751 | Ty::from_hir(&ctx, &impl_data.target_type) | ||
765 | } | 752 | } |
766 | 753 | ||
767 | pub(crate) fn impl_self_ty_recover( | 754 | pub(crate) fn impl_self_ty_recover( |
@@ -775,7 +762,8 @@ pub(crate) fn impl_self_ty_recover( | |||
775 | pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<TraitRef> { | 762 | pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<TraitRef> { |
776 | let impl_data = db.impl_data(impl_id); | 763 | let impl_data = db.impl_data(impl_id); |
777 | let resolver = impl_id.resolver(db); | 764 | let resolver = impl_id.resolver(db); |
765 | let ctx = TyLoweringContext { db, resolver: &resolver }; | ||
778 | let self_ty = db.impl_self_ty(impl_id); | 766 | let self_ty = db.impl_self_ty(impl_id); |
779 | let target_trait = impl_data.target_trait.as_ref()?; | 767 | let target_trait = impl_data.target_trait.as_ref()?; |
780 | TraitRef::from_hir(db, &resolver, target_trait, Some(self_ty.clone())) | 768 | TraitRef::from_hir(&ctx, target_trait, Some(self_ty.clone())) |
781 | } | 769 | } |