aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-12-29 16:58:29 +0000
committerGitHub <[email protected]>2019-12-29 16:58:29 +0000
commitb30de4ed49be362ed8fd71ac367c90554441b079 (patch)
tree57a73fd5f720d5890b82999fafa897eac70f0749 /crates/ra_hir_ty
parent232785251bc80bc32c2ab52b624ecffbf5e35185 (diff)
parent8280795a85a9a6d5ec43fea00a023e0b7dc9aaa8 (diff)
Merge #2679
2679: Resolve traits for infer using lang item infrastructure r=matklad a=kiljacken As we already have the infrastructure for collecting lang items, use it to find the right traits when doing type-inference. Co-authored-by: Emil Lauridsen <[email protected]>
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r--crates/ra_hir_ty/src/infer.rs23
-rw-r--r--crates/ra_hir_ty/src/tests/simple.rs1
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs5
3 files changed, 19 insertions, 10 deletions
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index 32c0d07a5..37e69599d 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -24,6 +24,7 @@ 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 lang_item::LangItemTarget,
27 path::{path, Path}, 28 path::{path, Path},
28 resolver::{HasResolver, Resolver, TypeNs}, 29 resolver::{HasResolver, Resolver, TypeNs},
29 type_ref::{Mutability, TypeRef}, 30 type_ref::{Mutability, TypeRef},
@@ -32,6 +33,7 @@ use hir_def::{
32use hir_expand::{diagnostics::DiagnosticSink, name::name}; 33use hir_expand::{diagnostics::DiagnosticSink, name::name};
33use ra_arena::map::ArenaMap; 34use ra_arena::map::ArenaMap;
34use ra_prof::profile; 35use ra_prof::profile;
36use ra_syntax::SmolStr;
35use test_utils::tested_by; 37use test_utils::tested_by;
36 38
37use super::{ 39use super::{
@@ -482,6 +484,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
482 self.infer_expr_coerce(self.body.body_expr, &Expectation::has_type(self.return_ty.clone())); 484 self.infer_expr_coerce(self.body.body_expr, &Expectation::has_type(self.return_ty.clone()));
483 } 485 }
484 486
487 fn resolve_lang_item(&self, name: &str) -> Option<LangItemTarget> {
488 let krate = self.resolver.krate()?;
489 let name = SmolStr::new_inline_from_ascii(name.len(), name.as_bytes());
490 self.db.lang_item(krate, name)
491 }
492
485 fn resolve_into_iter_item(&self) -> Option<TypeAliasId> { 493 fn resolve_into_iter_item(&self) -> Option<TypeAliasId> {
486 let path = path![std::iter::IntoIterator]; 494 let path = path![std::iter::IntoIterator];
487 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; 495 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
@@ -495,26 +503,22 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
495 } 503 }
496 504
497 fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> { 505 fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> {
498 let path = path![std::ops::Neg]; 506 let trait_ = self.resolve_lang_item("neg")?.as_trait()?;
499 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
500 self.db.trait_data(trait_).associated_type_by_name(&name![Output]) 507 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
501 } 508 }
502 509
503 fn resolve_ops_not_output(&self) -> Option<TypeAliasId> { 510 fn resolve_ops_not_output(&self) -> Option<TypeAliasId> {
504 let path = path![std::ops::Not]; 511 let trait_ = self.resolve_lang_item("not")?.as_trait()?;
505 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
506 self.db.trait_data(trait_).associated_type_by_name(&name![Output]) 512 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
507 } 513 }
508 514
509 fn resolve_future_future_output(&self) -> Option<TypeAliasId> { 515 fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
510 let path = path![std::future::Future]; 516 let trait_ = self.resolve_lang_item("future_trait")?.as_trait()?;
511 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
512 self.db.trait_data(trait_).associated_type_by_name(&name![Output]) 517 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
513 } 518 }
514 519
515 fn resolve_boxed_box(&self) -> Option<AdtId> { 520 fn resolve_boxed_box(&self) -> Option<AdtId> {
516 let path = path![std::boxed::Box]; 521 let struct_ = self.resolve_lang_item("owned_box")?.as_struct()?;
517 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
518 Some(struct_.into()) 522 Some(struct_.into())
519 } 523 }
520 524
@@ -555,8 +559,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
555 } 559 }
556 560
557 fn resolve_ops_index_output(&self) -> Option<TypeAliasId> { 561 fn resolve_ops_index_output(&self) -> Option<TypeAliasId> {
558 let path = path![std::ops::Index]; 562 let trait_ = self.resolve_lang_item("index")?.as_trait()?;
559 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
560 self.db.trait_data(trait_).associated_type_by_name(&name![Output]) 563 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
561 } 564 }
562} 565}
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs
index 00134c99b..f7e042c12 100644
--- a/crates/ra_hir_ty/src/tests/simple.rs
+++ b/crates/ra_hir_ty/src/tests/simple.rs
@@ -20,6 +20,7 @@ fn test() {
20mod prelude {} 20mod prelude {}
21 21
22mod boxed { 22mod boxed {
23 #[lang = "owned_box"]
23 pub struct Box<T: ?Sized> { 24 pub struct Box<T: ?Sized> {
24 inner: *mut T, 25 inner: *mut T,
25 } 26 }
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index 0bc72644a..4b268510c 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -27,6 +27,7 @@ fn test() {
27//- /std.rs crate:std 27//- /std.rs crate:std
28#[prelude_import] use future::*; 28#[prelude_import] use future::*;
29mod future { 29mod future {
30 #[lang = "future_trait"]
30 trait Future { 31 trait Future {
31 type Output; 32 type Output;
32 } 33 }
@@ -56,6 +57,7 @@ fn test() {
56//- /std.rs crate:std 57//- /std.rs crate:std
57#[prelude_import] use future::*; 58#[prelude_import] use future::*;
58mod future { 59mod future {
60 #[lang = "future_trait"]
59 trait Future { 61 trait Future {
60 type Output; 62 type Output;
61 } 63 }
@@ -198,6 +200,7 @@ fn test() {
198 200
199#[prelude_import] use ops::*; 201#[prelude_import] use ops::*;
200mod ops { 202mod ops {
203 #[lang = "neg"]
201 pub trait Neg { 204 pub trait Neg {
202 type Output; 205 type Output;
203 } 206 }
@@ -230,6 +233,7 @@ fn test() {
230 233
231#[prelude_import] use ops::*; 234#[prelude_import] use ops::*;
232mod ops { 235mod ops {
236 #[lang = "not"]
233 pub trait Not { 237 pub trait Not {
234 type Output; 238 type Output;
235 } 239 }
@@ -506,6 +510,7 @@ fn test() {
506 510
507#[prelude_import] use ops::*; 511#[prelude_import] use ops::*;
508mod ops { 512mod ops {
513 #[lang = "index"]
509 pub trait Index<Idx> { 514 pub trait Index<Idx> {
510 type Output; 515 type Output;
511 } 516 }