aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/infer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/infer.rs')
-rw-r--r--crates/ra_hir_ty/src/infer.rs29
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