File tree 3 files changed +42
-14
lines changed 3 files changed +42
-14
lines changed Original file line number Diff line number Diff line change @@ -3,7 +3,7 @@ use std::sync::Arc;
3
3
4
4
use ra_syntax:: ast;
5
5
6
- use rustc_hash:: FxHashMap ;
6
+ use rustc_hash:: { FxHashMap , FxHashSet } ;
7
7
8
8
use crate :: {
9
9
ModuleDef , Trait ,
@@ -193,19 +193,18 @@ impl Resolver {
193
193
names
194
194
}
195
195
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 ( ) ) ;
205
203
}
206
- . into_iter ( )
207
- } )
208
- . flatten ( )
204
+ traits. extend ( m. crate_def_map [ m. module_id ] . scope . traits ( ) ) ;
205
+ }
206
+ }
207
+ traits
209
208
}
210
209
211
210
fn module ( & self ) -> Option < ( & CrateDefMap , CrateModuleId ) > {
Original file line number Diff line number Diff line change @@ -185,7 +185,7 @@ fn iterate_trait_method_candidates<T>(
185
185
mut callback : impl FnMut ( & Ty , Function ) -> Option < T > ,
186
186
) -> Option < T > {
187
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
189
let data = t. trait_data ( db) ;
190
190
// we'll be lazy about checking whether the type implements the
191
191
// trait, but if we find out it doesn't, we'll skip the rest of the
Original file line number Diff line number Diff line change @@ -2501,6 +2501,35 @@ fn test() { (&S).foo()<|>; }
2501
2501
assert_eq ! ( t, "u128" ) ;
2502
2502
}
2503
2503
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
+
2504
2533
#[ test]
2505
2534
fn method_resolution_where_clause_for_unknown_trait ( ) {
2506
2535
// The blanket impl shouldn't apply because we can't even resolve UnknownTrait
You can’t perform that action at this time.
0 commit comments