Skip to content

Commit bc59f83

Browse files
committed
Use traits from prelude for method resolution
1 parent 7fda874 commit bc59f83

File tree

3 files changed

+42
-14
lines changed

3 files changed

+42
-14
lines changed

crates/ra_hir/src/resolve.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::sync::Arc;
33

44
use ra_syntax::ast;
55

6-
use rustc_hash::FxHashMap;
6+
use rustc_hash::{FxHashMap, FxHashSet};
77

88
use crate::{
99
ModuleDef, Trait,
@@ -193,19 +193,18 @@ impl Resolver {
193193
names
194194
}
195195

196-
pub(crate) fn traits_in_scope<'a>(&'a self) -> impl Iterator<Item = Trait> + 'a {
197-
// FIXME prelude
198-
self.scopes
199-
.iter()
200-
.rev()
201-
.flat_map(|scope| {
202-
match scope {
203-
Scope::ModuleScope(m) => Some(m.crate_def_map[m.module_id].scope.traits()),
204-
_ => None,
196+
pub(crate) fn traits_in_scope(&self, db: &impl HirDatabase) -> FxHashSet<Trait> {
197+
let mut traits = FxHashSet::default();
198+
for scope in &self.scopes {
199+
if let Scope::ModuleScope(m) = scope {
200+
if let Some(prelude) = m.crate_def_map.prelude() {
201+
let prelude_def_map = db.crate_def_map(prelude.krate);
202+
traits.extend(prelude_def_map[prelude.module_id].scope.traits());
205203
}
206-
.into_iter()
207-
})
208-
.flatten()
204+
traits.extend(m.crate_def_map[m.module_id].scope.traits());
205+
}
206+
}
207+
traits
209208
}
210209

211210
fn module(&self) -> Option<(&CrateDefMap, CrateModuleId)> {

crates/ra_hir/src/ty/method_resolution.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ fn iterate_trait_method_candidates<T>(
185185
mut callback: impl FnMut(&Ty, Function) -> Option<T>,
186186
) -> Option<T> {
187187
let krate = resolver.krate()?;
188-
'traits: for t in resolver.traits_in_scope() {
188+
'traits: for t in resolver.traits_in_scope(db) {
189189
let data = t.trait_data(db);
190190
// we'll be lazy about checking whether the type implements the
191191
// trait, but if we find out it doesn't, we'll skip the rest of the

crates/ra_hir/src/ty/tests.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2501,6 +2501,35 @@ fn test() { (&S).foo()<|>; }
25012501
assert_eq!(t, "u128");
25022502
}
25032503

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+
25042533
#[test]
25052534
fn method_resolution_where_clause_for_unknown_trait() {
25062535
// The blanket impl shouldn't apply because we can't even resolve UnknownTrait

0 commit comments

Comments
 (0)