aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir_def/src/lang_item.rs44
-rw-r--r--crates/ra_hir_def/src/path.rs4
-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
5 files changed, 63 insertions, 14 deletions
diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs
index cef061837..37c861a87 100644
--- a/crates/ra_hir_def/src/lang_item.rs
+++ b/crates/ra_hir_def/src/lang_item.rs
@@ -22,6 +22,50 @@ pub enum LangItemTarget {
22 TraitId(TraitId), 22 TraitId(TraitId),
23} 23}
24 24
25impl LangItemTarget {
26 pub fn as_enum(self) -> Option<EnumId> {
27 match self {
28 LangItemTarget::EnumId(id) => Some(id),
29 _ => None,
30 }
31 }
32
33 pub fn as_function(self) -> Option<FunctionId> {
34 match self {
35 LangItemTarget::FunctionId(id) => Some(id),
36 _ => None,
37 }
38 }
39
40 pub fn as_impl_block(self) -> Option<ImplId> {
41 match self {
42 LangItemTarget::ImplBlockId(id) => Some(id),
43 _ => None,
44 }
45 }
46
47 pub fn as_static(self) -> Option<StaticId> {
48 match self {
49 LangItemTarget::StaticId(id) => Some(id),
50 _ => None,
51 }
52 }
53
54 pub fn as_struct(self) -> Option<StructId> {
55 match self {
56 LangItemTarget::StructId(id) => Some(id),
57 _ => None,
58 }
59 }
60
61 pub fn as_trait(self) -> Option<TraitId> {
62 match self {
63 LangItemTarget::TraitId(id) => Some(id),
64 _ => None,
65 }
66 }
67}
68
25#[derive(Default, Debug, Clone, PartialEq, Eq)] 69#[derive(Default, Debug, Clone, PartialEq, Eq)]
26pub struct LangItems { 70pub struct LangItems {
27 items: FxHashMap<SmolStr, LangItemTarget>, 71 items: FxHashMap<SmolStr, LangItemTarget>,
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs
index 107d2d799..82cfa67a9 100644
--- a/crates/ra_hir_def/src/path.rs
+++ b/crates/ra_hir_def/src/path.rs
@@ -260,12 +260,8 @@ macro_rules! __known_path {
260 (std::ops::RangeTo) => {}; 260 (std::ops::RangeTo) => {};
261 (std::ops::RangeToInclusive) => {}; 261 (std::ops::RangeToInclusive) => {};
262 (std::ops::RangeInclusive) => {}; 262 (std::ops::RangeInclusive) => {};
263 (std::boxed::Box) => {};
264 (std::future::Future) => {}; 263 (std::future::Future) => {};
265 (std::ops::Try) => {}; 264 (std::ops::Try) => {};
266 (std::ops::Neg) => {};
267 (std::ops::Not) => {};
268 (std::ops::Index) => {};
269 ($path:path) => { 265 ($path:path) => {
270 compile_error!("Please register your known path in the path module") 266 compile_error!("Please register your known path in the path module")
271 }; 267 };
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 }