diff options
Diffstat (limited to 'crates/ra_hir_ty/src/infer.rs')
-rw-r--r-- | crates/ra_hir_ty/src/infer.rs | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs index 98ba05fc2..e97b81473 100644 --- a/crates/ra_hir_ty/src/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs | |||
@@ -196,7 +196,12 @@ struct InferenceContext<'a, D: HirDatabase> { | |||
196 | trait_env: Arc<TraitEnvironment>, | 196 | trait_env: Arc<TraitEnvironment>, |
197 | obligations: Vec<Obligation>, | 197 | obligations: Vec<Obligation>, |
198 | result: InferenceResult, | 198 | result: InferenceResult, |
199 | /// The return type of the function being inferred. | 199 | /// The return type of the function being inferred, or the closure if we're |
200 | /// currently within one. | ||
201 | /// | ||
202 | /// We might consider using a nested inference context for checking | ||
203 | /// closures, but currently this is the only field that will change there, | ||
204 | /// so it doesn't make sense. | ||
200 | return_ty: Ty, | 205 | return_ty: Ty, |
201 | 206 | ||
202 | /// Impls of `CoerceUnsized` used in coercion. | 207 | /// Impls of `CoerceUnsized` used in coercion. |
@@ -363,14 +368,26 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
363 | } | 368 | } |
364 | 369 | ||
365 | fn resolve_associated_type(&mut self, inner_ty: Ty, assoc_ty: Option<TypeAliasId>) -> Ty { | 370 | fn resolve_associated_type(&mut self, inner_ty: Ty, assoc_ty: Option<TypeAliasId>) -> Ty { |
371 | self.resolve_associated_type_with_params(inner_ty, assoc_ty, &[]) | ||
372 | } | ||
373 | |||
374 | fn resolve_associated_type_with_params( | ||
375 | &mut self, | ||
376 | inner_ty: Ty, | ||
377 | assoc_ty: Option<TypeAliasId>, | ||
378 | params: &[Ty], | ||
379 | ) -> Ty { | ||
366 | match assoc_ty { | 380 | match assoc_ty { |
367 | Some(res_assoc_ty) => { | 381 | Some(res_assoc_ty) => { |
368 | let ty = self.table.new_type_var(); | 382 | let ty = self.table.new_type_var(); |
383 | let builder = Substs::build_for_def(self.db, res_assoc_ty) | ||
384 | .push(inner_ty) | ||
385 | .fill(params.iter().cloned()); | ||
369 | let projection = ProjectionPredicate { | 386 | let projection = ProjectionPredicate { |
370 | ty: ty.clone(), | 387 | ty: ty.clone(), |
371 | projection_ty: ProjectionTy { | 388 | projection_ty: ProjectionTy { |
372 | associated_ty: res_assoc_ty, | 389 | associated_ty: res_assoc_ty, |
373 | parameters: Substs::single(inner_ty), | 390 | parameters: builder.build(), |
374 | }, | 391 | }, |
375 | }; | 392 | }; |
376 | self.obligations.push(Obligation::Projection(projection)); | 393 | self.obligations.push(Obligation::Projection(projection)); |
@@ -443,7 +460,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
443 | } | 460 | } |
444 | 461 | ||
445 | fn infer_body(&mut self) { | 462 | fn infer_body(&mut self) { |
446 | self.infer_expr(self.body.body_expr, &Expectation::has_type(self.return_ty.clone())); | 463 | self.infer_expr_coerce(self.body.body_expr, &Expectation::has_type(self.return_ty.clone())); |
447 | } | 464 | } |
448 | 465 | ||
449 | fn resolve_into_iter_item(&self) -> Option<TypeAliasId> { | 466 | fn resolve_into_iter_item(&self) -> Option<TypeAliasId> { |
@@ -517,6 +534,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
517 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; | 534 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; |
518 | Some(struct_.into()) | 535 | Some(struct_.into()) |
519 | } | 536 | } |
537 | |||
538 | fn resolve_ops_index_output(&self) -> Option<TypeAliasId> { | ||
539 | let path = path![std::ops::Index]; | ||
540 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; | ||
541 | self.db.trait_data(trait_).associated_type_by_name(&name![Output]) | ||
542 | } | ||
520 | } | 543 | } |
521 | 544 | ||
522 | /// The kinds of placeholders we need during type inference. There's separate | 545 | /// The kinds of placeholders we need during type inference. There's separate |