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.rs64
1 files changed, 47 insertions, 17 deletions
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index d16f1eb46..f1b7e9442 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -24,20 +24,20 @@ use hir_def::{
24 body::Body, 24 body::Body,
25 data::{ConstData, FunctionData}, 25 data::{ConstData, FunctionData},
26 expr::{BindingAnnotation, ExprId, PatId}, 26 expr::{BindingAnnotation, ExprId, PatId},
27 path::{known, Path}, 27 path::{path, Path},
28 resolver::{HasResolver, Resolver, TypeNs}, 28 resolver::{HasResolver, Resolver, TypeNs},
29 type_ref::{Mutability, TypeRef}, 29 type_ref::{Mutability, TypeRef},
30 AdtId, AssocItemId, DefWithBodyId, FunctionId, StructFieldId, TypeAliasId, VariantId, 30 AdtId, AssocItemId, DefWithBodyId, FunctionId, StructFieldId, TypeAliasId, VariantId,
31}; 31};
32use hir_expand::{diagnostics::DiagnosticSink, name}; 32use hir_expand::{diagnostics::DiagnosticSink, name::name};
33use ra_arena::map::ArenaMap; 33use ra_arena::map::ArenaMap;
34use ra_prof::profile; 34use ra_prof::profile;
35 35
36use super::{ 36use super::{
37 primitive::{FloatTy, IntTy}, 37 primitive::{FloatTy, IntTy},
38 traits::{Guidance, Obligation, ProjectionPredicate, Solution}, 38 traits::{Guidance, Obligation, ProjectionPredicate, Solution},
39 ApplicationTy, InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, 39 ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor,
40 Uncertain, 40 TypeWalk, Uncertain,
41}; 41};
42use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic}; 42use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic};
43 43
@@ -338,6 +338,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
338 self.table.resolve_ty_shallow(ty) 338 self.table.resolve_ty_shallow(ty)
339 } 339 }
340 340
341 fn resolve_associated_type(&mut self, inner_ty: Ty, assoc_ty: Option<TypeAliasId>) -> Ty {
342 match assoc_ty {
343 Some(res_assoc_ty) => {
344 let ty = self.table.new_type_var();
345 let projection = ProjectionPredicate {
346 ty: ty.clone(),
347 projection_ty: ProjectionTy {
348 associated_ty: res_assoc_ty,
349 parameters: Substs::single(inner_ty),
350 },
351 };
352 self.obligations.push(Obligation::Projection(projection));
353 self.resolve_ty_as_possible(ty)
354 }
355 None => Ty::Unknown,
356 }
357 }
358
341 /// Recurses through the given type, normalizing associated types mentioned 359 /// Recurses through the given type, normalizing associated types mentioned
342 /// in it by replacing them by type variables and registering obligations to 360 /// in it by replacing them by type variables and registering obligations to
343 /// resolve later. This should be done once for every type we get from some 361 /// resolve later. This should be done once for every type we get from some
@@ -404,61 +422,73 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
404 } 422 }
405 423
406 fn resolve_into_iter_item(&self) -> Option<TypeAliasId> { 424 fn resolve_into_iter_item(&self) -> Option<TypeAliasId> {
407 let path = known::std_iter_into_iterator(); 425 let path = path![std::iter::IntoIterator];
408 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; 426 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
409 self.db.trait_data(trait_).associated_type_by_name(&name::ITEM_TYPE) 427 self.db.trait_data(trait_).associated_type_by_name(&name![Item])
410 } 428 }
411 429
412 fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> { 430 fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> {
413 let path = known::std_ops_try(); 431 let path = path![std::ops::Try];
432 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
433 self.db.trait_data(trait_).associated_type_by_name(&name![Ok])
434 }
435
436 fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> {
437 let path = path![std::ops::Neg];
438 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
439 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
440 }
441
442 fn resolve_ops_not_output(&self) -> Option<TypeAliasId> {
443 let path = path![std::ops::Not];
414 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; 444 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
415 self.db.trait_data(trait_).associated_type_by_name(&name::OK_TYPE) 445 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
416 } 446 }
417 447
418 fn resolve_future_future_output(&self) -> Option<TypeAliasId> { 448 fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
419 let path = known::std_future_future(); 449 let path = path![std::future::Future];
420 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; 450 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
421 self.db.trait_data(trait_).associated_type_by_name(&name::OUTPUT_TYPE) 451 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
422 } 452 }
423 453
424 fn resolve_boxed_box(&self) -> Option<AdtId> { 454 fn resolve_boxed_box(&self) -> Option<AdtId> {
425 let path = known::std_boxed_box(); 455 let path = path![std::boxed::Box];
426 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 456 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
427 Some(struct_.into()) 457 Some(struct_.into())
428 } 458 }
429 459
430 fn resolve_range_full(&self) -> Option<AdtId> { 460 fn resolve_range_full(&self) -> Option<AdtId> {
431 let path = known::std_ops_range_full(); 461 let path = path![std::ops::RangeFull];
432 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 462 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
433 Some(struct_.into()) 463 Some(struct_.into())
434 } 464 }
435 465
436 fn resolve_range(&self) -> Option<AdtId> { 466 fn resolve_range(&self) -> Option<AdtId> {
437 let path = known::std_ops_range(); 467 let path = path![std::ops::Range];
438 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 468 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
439 Some(struct_.into()) 469 Some(struct_.into())
440 } 470 }
441 471
442 fn resolve_range_inclusive(&self) -> Option<AdtId> { 472 fn resolve_range_inclusive(&self) -> Option<AdtId> {
443 let path = known::std_ops_range_inclusive(); 473 let path = path![std::ops::RangeInclusive];
444 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 474 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
445 Some(struct_.into()) 475 Some(struct_.into())
446 } 476 }
447 477
448 fn resolve_range_from(&self) -> Option<AdtId> { 478 fn resolve_range_from(&self) -> Option<AdtId> {
449 let path = known::std_ops_range_from(); 479 let path = path![std::ops::RangeFrom];
450 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 480 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
451 Some(struct_.into()) 481 Some(struct_.into())
452 } 482 }
453 483
454 fn resolve_range_to(&self) -> Option<AdtId> { 484 fn resolve_range_to(&self) -> Option<AdtId> {
455 let path = known::std_ops_range_to(); 485 let path = path![std::ops::RangeTo];
456 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 486 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
457 Some(struct_.into()) 487 Some(struct_.into())
458 } 488 }
459 489
460 fn resolve_range_to_inclusive(&self) -> Option<AdtId> { 490 fn resolve_range_to_inclusive(&self) -> Option<AdtId> {
461 let path = known::std_ops_range_to_inclusive(); 491 let path = path![std::ops::RangeToInclusive];
462 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 492 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
463 Some(struct_.into()) 493 Some(struct_.into())
464 } 494 }