diff options
-rw-r--r-- | crates/ra_hir/src/db.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/lang_item.rs | 48 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 11 |
3 files changed, 34 insertions, 32 deletions
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index b27efcbe3..8af0a3176 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_syntax::{SyntaxNode, TreeArc, SourceFile, ast}; | 3 | use ra_syntax::{SyntaxNode, TreeArc, SourceFile, SmolStr, ast}; |
4 | use ra_db::{SourceDatabase, salsa}; | 4 | use ra_db::{SourceDatabase, salsa}; |
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
@@ -16,7 +16,7 @@ use crate::{ | |||
16 | generics::{GenericParams, GenericDef}, | 16 | generics::{GenericParams, GenericDef}, |
17 | type_ref::TypeRef, | 17 | type_ref::TypeRef, |
18 | traits::TraitData, Trait, ty::TraitRef, | 18 | traits::TraitData, Trait, ty::TraitRef, |
19 | lang_item::LangItems, | 19 | lang_item::{LangItems, LangItemTarget}, |
20 | ids | 20 | ids |
21 | }; | 21 | }; |
22 | 22 | ||
@@ -104,6 +104,9 @@ pub trait DefDatabase: SourceDatabase { | |||
104 | 104 | ||
105 | #[salsa::invoke(crate::lang_item::LangItems::lang_items_query)] | 105 | #[salsa::invoke(crate::lang_item::LangItems::lang_items_query)] |
106 | fn lang_items(&self, krate: Crate) -> Arc<LangItems>; | 106 | fn lang_items(&self, krate: Crate) -> Arc<LangItems>; |
107 | |||
108 | #[salsa::invoke(crate::lang_item::LangItems::lang_item_query)] | ||
109 | fn lang_item(&self, start_crate: Crate, item: SmolStr) -> Option<LangItemTarget>; | ||
107 | } | 110 | } |
108 | 111 | ||
109 | #[salsa::query_group(HirDatabaseStorage)] | 112 | #[salsa::query_group(HirDatabaseStorage)] |
diff --git a/crates/ra_hir/src/lang_item.rs b/crates/ra_hir/src/lang_item.rs index a25d419e7..5f3f91cba 100644 --- a/crates/ra_hir/src/lang_item.rs +++ b/crates/ra_hir/src/lang_item.rs | |||
@@ -40,7 +40,7 @@ impl LangItems { | |||
40 | self.items.get(item) | 40 | self.items.get(item) |
41 | } | 41 | } |
42 | 42 | ||
43 | /// Salsa query. This will query a specific crate for lang items. | 43 | /// Salsa query. This will look for lang items in a specific crate. |
44 | pub(crate) fn lang_items_query(db: &impl DefDatabase, krate: Crate) -> Arc<LangItems> { | 44 | pub(crate) fn lang_items_query(db: &impl DefDatabase, krate: Crate) -> Arc<LangItems> { |
45 | let mut lang_items = LangItems { items: FxHashMap::default() }; | 45 | let mut lang_items = LangItems { items: FxHashMap::default() }; |
46 | 46 | ||
@@ -51,6 +51,29 @@ impl LangItems { | |||
51 | Arc::new(lang_items) | 51 | Arc::new(lang_items) |
52 | } | 52 | } |
53 | 53 | ||
54 | /// Salsa query. Look for a lang item, starting from the specified crate and recursively | ||
55 | /// traversing its dependencies. | ||
56 | pub(crate) fn lang_item_query( | ||
57 | db: &impl DefDatabase, | ||
58 | start_crate: Crate, | ||
59 | item: SmolStr, | ||
60 | ) -> Option<LangItemTarget> { | ||
61 | let lang_items = db.lang_items(start_crate); | ||
62 | let start_crate_target = lang_items.items.get(&item); | ||
63 | if let Some(target) = start_crate_target { | ||
64 | Some(*target) | ||
65 | } else { | ||
66 | for dep in start_crate.dependencies(db) { | ||
67 | let dep_crate = dep.krate; | ||
68 | let dep_target = db.lang_item(dep_crate, item.clone()); | ||
69 | if dep_target.is_some() { | ||
70 | return dep_target; | ||
71 | } | ||
72 | } | ||
73 | None | ||
74 | } | ||
75 | } | ||
76 | |||
54 | fn collect_lang_items_recursive(&mut self, db: &impl DefDatabase, module: &Module) { | 77 | fn collect_lang_items_recursive(&mut self, db: &impl DefDatabase, module: &Module) { |
55 | // Look for impl targets | 78 | // Look for impl targets |
56 | let (impl_blocks, source_map) = db.impls_in_module_with_source_map(module.clone()); | 79 | let (impl_blocks, source_map) = db.impls_in_module_with_source_map(module.clone()); |
@@ -77,26 +100,3 @@ impl LangItems { | |||
77 | } | 100 | } |
78 | } | 101 | } |
79 | } | 102 | } |
80 | |||
81 | /// Look for a lang item, starting from the specified crate and recursively traversing its | ||
82 | /// dependencies. | ||
83 | pub(crate) fn lang_item_lookup( | ||
84 | db: &impl DefDatabase, | ||
85 | start_krate: Crate, | ||
86 | item: &str, | ||
87 | ) -> Option<LangItemTarget> { | ||
88 | let lang_items = db.lang_items(start_krate); | ||
89 | let start_krate_target = lang_items.items.get(item); | ||
90 | if start_krate_target.is_some() { | ||
91 | start_krate_target.map(|t| *t) | ||
92 | } else { | ||
93 | for dep in start_krate.dependencies(db) { | ||
94 | let dep_krate = dep.krate; | ||
95 | let dep_target = lang_item_lookup(db, dep_krate, item); | ||
96 | if dep_target.is_some() { | ||
97 | return dep_target; | ||
98 | } | ||
99 | } | ||
100 | None | ||
101 | } | ||
102 | } | ||
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index dca56a434..ea6e0dc0f 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -14,7 +14,6 @@ use crate::{ | |||
14 | resolve::Resolver, | 14 | resolve::Resolver, |
15 | traits::TraitItem, | 15 | traits::TraitItem, |
16 | generics::HasGenericParams, | 16 | generics::HasGenericParams, |
17 | lang_item::lang_item_lookup, | ||
18 | ty::primitive::{UncertainIntTy, UncertainFloatTy} | 17 | ty::primitive::{UncertainIntTy, UncertainFloatTy} |
19 | }; | 18 | }; |
20 | use super::{TraitRef, Substs}; | 19 | use super::{TraitRef, Substs}; |
@@ -116,15 +115,15 @@ fn def_crate(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<Crate> | |||
116 | match ty { | 115 | match ty { |
117 | Ty::Apply(a_ty) => match a_ty.ctor { | 116 | Ty::Apply(a_ty) => match a_ty.ctor { |
118 | TypeCtor::Adt(def_id) => def_id.krate(db), | 117 | TypeCtor::Adt(def_id) => def_id.krate(db), |
119 | TypeCtor::Bool => lang_item_lookup(db, cur_crate, "bool")?.krate(db), | 118 | TypeCtor::Bool => db.lang_item(cur_crate, "bool".into())?.krate(db), |
120 | TypeCtor::Char => lang_item_lookup(db, cur_crate, "char")?.krate(db), | 119 | TypeCtor::Char => db.lang_item(cur_crate, "char".into())?.krate(db), |
121 | TypeCtor::Float(UncertainFloatTy::Known(f)) => { | 120 | TypeCtor::Float(UncertainFloatTy::Known(f)) => { |
122 | lang_item_lookup(db, cur_crate, f.ty_to_string())?.krate(db) | 121 | db.lang_item(cur_crate, f.ty_to_string().into())?.krate(db) |
123 | } | 122 | } |
124 | TypeCtor::Int(UncertainIntTy::Known(i)) => { | 123 | TypeCtor::Int(UncertainIntTy::Known(i)) => { |
125 | lang_item_lookup(db, cur_crate, i.ty_to_string())?.krate(db) | 124 | db.lang_item(cur_crate, i.ty_to_string().into())?.krate(db) |
126 | } | 125 | } |
127 | TypeCtor::Str => lang_item_lookup(db, cur_crate, "str")?.krate(db), | 126 | TypeCtor::Str => db.lang_item(cur_crate, "str".into())?.krate(db), |
128 | _ => None, | 127 | _ => None, |
129 | }, | 128 | }, |
130 | _ => None, | 129 | _ => None, |