diff options
author | Florian Diebold <[email protected]> | 2019-05-12 13:58:37 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-05-12 19:25:26 +0100 |
commit | bc59f83991a6444ff2f2364b0e942e8a82943b6d (patch) | |
tree | e8aa2948b2bb301f453307c35311634cda5de43b /crates/ra_hir/src | |
parent | 7fda874dd4c84d4b53ed625e9eccc92c3fa9a48e (diff) |
Use traits from prelude for method resolution
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/resolve.rs | 25 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 29 |
3 files changed, 42 insertions, 14 deletions
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index 707556ef8..2fb219908 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs | |||
@@ -3,7 +3,7 @@ use std::sync::Arc; | |||
3 | 3 | ||
4 | use ra_syntax::ast; | 4 | use ra_syntax::ast; |
5 | 5 | ||
6 | use rustc_hash::FxHashMap; | 6 | use rustc_hash::{FxHashMap, FxHashSet}; |
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | ModuleDef, Trait, | 9 | ModuleDef, Trait, |
@@ -193,19 +193,18 @@ impl Resolver { | |||
193 | names | 193 | names |
194 | } | 194 | } |
195 | 195 | ||
196 | pub(crate) fn traits_in_scope<'a>(&'a self) -> impl Iterator<Item = Trait> + 'a { | 196 | pub(crate) fn traits_in_scope(&self, db: &impl HirDatabase) -> FxHashSet<Trait> { |
197 | // FIXME prelude | 197 | let mut traits = FxHashSet::default(); |
198 | self.scopes | 198 | for scope in &self.scopes { |
199 | .iter() | 199 | if let Scope::ModuleScope(m) = scope { |
200 | .rev() | 200 | if let Some(prelude) = m.crate_def_map.prelude() { |
201 | .flat_map(|scope| { | 201 | let prelude_def_map = db.crate_def_map(prelude.krate); |
202 | match scope { | 202 | traits.extend(prelude_def_map[prelude.module_id].scope.traits()); |
203 | Scope::ModuleScope(m) => Some(m.crate_def_map[m.module_id].scope.traits()), | ||
204 | _ => None, | ||
205 | } | 203 | } |
206 | .into_iter() | 204 | traits.extend(m.crate_def_map[m.module_id].scope.traits()); |
207 | }) | 205 | } |
208 | .flatten() | 206 | } |
207 | traits | ||
209 | } | 208 | } |
210 | 209 | ||
211 | fn module(&self) -> Option<(&CrateDefMap, CrateModuleId)> { | 210 | fn module(&self) -> Option<(&CrateDefMap, CrateModuleId)> { |
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index e8cfa0b85..34817a5ec 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -185,7 +185,7 @@ fn iterate_trait_method_candidates<T>( | |||
185 | mut callback: impl FnMut(&Ty, Function) -> Option<T>, | 185 | mut callback: impl FnMut(&Ty, Function) -> Option<T>, |
186 | ) -> Option<T> { | 186 | ) -> Option<T> { |
187 | let krate = resolver.krate()?; | 187 | let krate = resolver.krate()?; |
188 | 'traits: for t in resolver.traits_in_scope() { | 188 | 'traits: for t in resolver.traits_in_scope(db) { |
189 | let data = t.trait_data(db); | 189 | let data = t.trait_data(db); |
190 | // we'll be lazy about checking whether the type implements the | 190 | // we'll be lazy about checking whether the type implements the |
191 | // trait, but if we find out it doesn't, we'll skip the rest of the | 191 | // trait, but if we find out it doesn't, we'll skip the rest of the |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 510fa5333..978cc2587 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -2502,6 +2502,35 @@ fn test() { (&S).foo()<|>; } | |||
2502 | } | 2502 | } |
2503 | 2503 | ||
2504 | #[test] | 2504 | #[test] |
2505 | fn method_resolution_trait_from_prelude() { | ||
2506 | let (mut db, pos) = MockDatabase::with_position( | ||
2507 | r#" | ||
2508 | //- /main.rs | ||
2509 | struct S; | ||
2510 | impl Clone for S {} | ||
2511 | |||
2512 | fn test() { | ||
2513 | S.clone()<|>; | ||
2514 | } | ||
2515 | |||
2516 | //- /lib.rs | ||
2517 | #[prelude_import] use foo::*; | ||
2518 | |||
2519 | mod foo { | ||
2520 | trait Clone { | ||
2521 | fn clone(&self) -> Self; | ||
2522 | } | ||
2523 | } | ||
2524 | "#, | ||
2525 | ); | ||
2526 | db.set_crate_graph_from_fixture(crate_graph! { | ||
2527 | "main": ("/main.rs", ["other_crate"]), | ||
2528 | "other_crate": ("/lib.rs", []), | ||
2529 | }); | ||
2530 | assert_eq!("S", type_at_pos(&db, pos)); | ||
2531 | } | ||
2532 | |||
2533 | #[test] | ||
2505 | fn method_resolution_where_clause_for_unknown_trait() { | 2534 | fn method_resolution_where_clause_for_unknown_trait() { |
2506 | // The blanket impl shouldn't apply because we can't even resolve UnknownTrait | 2535 | // The blanket impl shouldn't apply because we can't even resolve UnknownTrait |
2507 | let t = type_at( | 2536 | let t = type_at( |