@@ -1388,9 +1388,13 @@ impl Function {
1388
1388
let loc = self . id . lookup ( db. upcast ( ) ) ;
1389
1389
let krate = loc. krate ( db) ;
1390
1390
let def_map = db. crate_def_map ( krate. into ( ) ) ;
1391
- let name = & function_data. name ;
1391
+ let ast_id =
1392
+ InFile :: new ( loc. id . file_id ( ) , loc. id . item_tree ( db. upcast ( ) ) [ loc. id . value ] . ast_id ) ;
1393
+
1392
1394
let mut exported_proc_macros = def_map. exported_proc_macros ( ) ;
1393
- exported_proc_macros. find ( |( _, mac_name) | mac_name == name) . map ( |( id, _) | MacroDef { id } )
1395
+ exported_proc_macros
1396
+ . find ( |& ( id, _) | matches ! ( id. kind, MacroDefKind :: ProcMacro ( _, _, id) if id == ast_id) )
1397
+ . map ( |( id, _) | MacroDef { id } )
1394
1398
}
1395
1399
1396
1400
/// A textual representation of the HIR of this function for debugging purposes.
@@ -2436,7 +2440,7 @@ impl Impl {
2436
2440
2437
2441
#[ derive( Clone , PartialEq , Eq , Debug ) ]
2438
2442
pub struct Type {
2439
- krate : CrateId ,
2443
+ krate : CrateId , // FIXME this is probably redundant with the TraitEnvironment
2440
2444
env : Arc < TraitEnvironment > ,
2441
2445
ty : Ty ,
2442
2446
}
@@ -2503,6 +2507,10 @@ impl Type {
2503
2507
matches ! ( self . ty. kind( Interner ) , TyKind :: Ref ( ..) )
2504
2508
}
2505
2509
2510
+ pub fn is_slice ( & self ) -> bool {
2511
+ matches ! ( self . ty. kind( Interner ) , TyKind :: Slice ( ..) )
2512
+ }
2513
+
2506
2514
pub fn is_usize ( & self ) -> bool {
2507
2515
matches ! ( self . ty. kind( Interner ) , TyKind :: Scalar ( Scalar :: Uint ( UintTy :: Usize ) ) )
2508
2516
}
@@ -2525,36 +2533,25 @@ impl Type {
2525
2533
/// Checks that particular type `ty` implements `std::future::Future`.
2526
2534
/// This function is used in `.await` syntax completion.
2527
2535
pub fn impls_future ( & self , db : & dyn HirDatabase ) -> bool {
2528
- // No special case for the type of async block, since Chalk can figure it out.
2529
-
2530
- let krate = self . krate ;
2531
-
2532
- let std_future_trait =
2533
- db. lang_item ( krate, SmolStr :: new_inline ( "future_trait" ) ) . and_then ( |it| it. as_trait ( ) ) ;
2536
+ let std_future_trait = db
2537
+ . lang_item ( self . krate , SmolStr :: new_inline ( "future_trait" ) )
2538
+ . and_then ( |it| it. as_trait ( ) ) ;
2534
2539
let std_future_trait = match std_future_trait {
2535
2540
Some ( it) => it,
2536
2541
None => return false ,
2537
2542
} ;
2538
2543
2539
2544
let canonical_ty =
2540
2545
Canonical { value : self . ty . clone ( ) , binders : CanonicalVarKinds :: empty ( Interner ) } ;
2541
- method_resolution:: implements_trait (
2542
- & canonical_ty,
2543
- db,
2544
- self . env . clone ( ) ,
2545
- krate,
2546
- std_future_trait,
2547
- )
2546
+ method_resolution:: implements_trait ( & canonical_ty, db, self . env . clone ( ) , std_future_trait)
2548
2547
}
2549
2548
2550
2549
/// Checks that particular type `ty` implements `std::ops::FnOnce`.
2551
2550
///
2552
2551
/// This function can be used to check if a particular type is callable, since FnOnce is a
2553
2552
/// supertrait of Fn and FnMut, so all callable types implements at least FnOnce.
2554
2553
pub fn impls_fnonce ( & self , db : & dyn HirDatabase ) -> bool {
2555
- let krate = self . krate ;
2556
-
2557
- let fnonce_trait = match FnTrait :: FnOnce . get_id ( db, krate) {
2554
+ let fnonce_trait = match FnTrait :: FnOnce . get_id ( db, self . krate ) {
2558
2555
Some ( it) => it,
2559
2556
None => return false ,
2560
2557
} ;
@@ -2565,7 +2562,6 @@ impl Type {
2565
2562
& canonical_ty,
2566
2563
db,
2567
2564
self . env . clone ( ) ,
2568
- krate,
2569
2565
fnonce_trait,
2570
2566
)
2571
2567
}
@@ -2736,9 +2732,8 @@ impl Type {
2736
2732
pub fn autoderef_ < ' a > ( & ' a self , db : & ' a dyn HirDatabase ) -> impl Iterator < Item = Ty > + ' a {
2737
2733
// There should be no inference vars in types passed here
2738
2734
let canonical = hir_ty:: replace_errors_with_variables ( & self . ty ) ;
2739
- let environment = self . env . env . clone ( ) ;
2740
- let ty = InEnvironment { goal : canonical, environment } ;
2741
- autoderef ( db, Some ( self . krate ) , ty) . map ( |canonical| canonical. value )
2735
+ let environment = self . env . clone ( ) ;
2736
+ autoderef ( db, environment, canonical) . map ( |canonical| canonical. value )
2742
2737
}
2743
2738
2744
2739
// This would be nicer if it just returned an iterator, but that runs into
@@ -2793,24 +2788,26 @@ impl Type {
2793
2788
pub fn iterate_method_candidates < T > (
2794
2789
& self ,
2795
2790
db : & dyn HirDatabase ,
2796
- krate : Crate ,
2791
+ scope : & SemanticsScope ,
2792
+ // FIXME this can be retrieved from `scope`, except autoimport uses this
2793
+ // to specify a different set, so the method needs to be split
2797
2794
traits_in_scope : & FxHashSet < TraitId > ,
2798
2795
with_local_impls : Option < Module > ,
2799
2796
name : Option < & Name > ,
2800
- mut callback : impl FnMut ( Type , Function ) -> Option < T > ,
2797
+ mut callback : impl FnMut ( Function ) -> Option < T > ,
2801
2798
) -> Option < T > {
2802
2799
let _p = profile:: span ( "iterate_method_candidates" ) ;
2803
2800
let mut slot = None ;
2804
2801
2805
2802
self . iterate_method_candidates_dyn (
2806
2803
db,
2807
- krate ,
2804
+ scope ,
2808
2805
traits_in_scope,
2809
2806
with_local_impls,
2810
2807
name,
2811
- & mut |ty , assoc_item_id| {
2808
+ & mut |assoc_item_id| {
2812
2809
if let AssocItemId :: FunctionId ( func) = assoc_item_id {
2813
- if let Some ( res) = callback ( self . derived ( ty . clone ( ) ) , func. into ( ) ) {
2810
+ if let Some ( res) = callback ( func. into ( ) ) {
2814
2811
slot = Some ( res) ;
2815
2812
return ControlFlow :: Break ( ( ) ) ;
2816
2813
}
@@ -2824,50 +2821,55 @@ impl Type {
2824
2821
fn iterate_method_candidates_dyn (
2825
2822
& self ,
2826
2823
db : & dyn HirDatabase ,
2827
- krate : Crate ,
2824
+ scope : & SemanticsScope ,
2828
2825
traits_in_scope : & FxHashSet < TraitId > ,
2829
2826
with_local_impls : Option < Module > ,
2830
2827
name : Option < & Name > ,
2831
- callback : & mut dyn FnMut ( & Ty , AssocItemId ) -> ControlFlow < ( ) > ,
2828
+ callback : & mut dyn FnMut ( AssocItemId ) -> ControlFlow < ( ) > ,
2832
2829
) {
2833
2830
// There should be no inference vars in types passed here
2834
2831
let canonical = hir_ty:: replace_errors_with_variables ( & self . ty ) ;
2835
2832
2836
- let env = self . env . clone ( ) ;
2837
- let krate = krate. id ;
2833
+ let krate = match scope. krate ( ) {
2834
+ Some ( k) => k,
2835
+ None => return ,
2836
+ } ;
2837
+ let environment = scope. resolver ( ) . generic_def ( ) . map_or_else (
2838
+ || Arc :: new ( TraitEnvironment :: empty ( krate. id ) ) ,
2839
+ |d| db. trait_environment ( d) ,
2840
+ ) ;
2838
2841
2839
2842
method_resolution:: iterate_method_candidates_dyn (
2840
2843
& canonical,
2841
2844
db,
2842
- env,
2843
- krate,
2845
+ environment,
2844
2846
traits_in_scope,
2845
2847
with_local_impls. and_then ( |b| b. id . containing_block ( ) ) . into ( ) ,
2846
2848
name,
2847
2849
method_resolution:: LookupMode :: MethodCall ,
2848
- & mut |ty , id| callback ( & ty . value , id) ,
2850
+ & mut |_adj , id| callback ( id) ,
2849
2851
) ;
2850
2852
}
2851
2853
2852
2854
pub fn iterate_path_candidates < T > (
2853
2855
& self ,
2854
2856
db : & dyn HirDatabase ,
2855
- krate : Crate ,
2857
+ scope : & SemanticsScope ,
2856
2858
traits_in_scope : & FxHashSet < TraitId > ,
2857
2859
with_local_impls : Option < Module > ,
2858
2860
name : Option < & Name > ,
2859
- mut callback : impl FnMut ( Type , AssocItem ) -> Option < T > ,
2861
+ mut callback : impl FnMut ( AssocItem ) -> Option < T > ,
2860
2862
) -> Option < T > {
2861
2863
let _p = profile:: span ( "iterate_path_candidates" ) ;
2862
2864
let mut slot = None ;
2863
2865
self . iterate_path_candidates_dyn (
2864
2866
db,
2865
- krate ,
2867
+ scope ,
2866
2868
traits_in_scope,
2867
2869
with_local_impls,
2868
2870
name,
2869
- & mut |ty , assoc_item_id| {
2870
- if let Some ( res) = callback ( self . derived ( ty . clone ( ) ) , assoc_item_id. into ( ) ) {
2871
+ & mut |assoc_item_id| {
2872
+ if let Some ( res) = callback ( assoc_item_id. into ( ) ) {
2871
2873
slot = Some ( res) ;
2872
2874
return ControlFlow :: Break ( ( ) ) ;
2873
2875
}
@@ -2880,27 +2882,31 @@ impl Type {
2880
2882
fn iterate_path_candidates_dyn (
2881
2883
& self ,
2882
2884
db : & dyn HirDatabase ,
2883
- krate : Crate ,
2885
+ scope : & SemanticsScope ,
2884
2886
traits_in_scope : & FxHashSet < TraitId > ,
2885
2887
with_local_impls : Option < Module > ,
2886
2888
name : Option < & Name > ,
2887
- callback : & mut dyn FnMut ( & Ty , AssocItemId ) -> ControlFlow < ( ) > ,
2889
+ callback : & mut dyn FnMut ( AssocItemId ) -> ControlFlow < ( ) > ,
2888
2890
) {
2889
2891
let canonical = hir_ty:: replace_errors_with_variables ( & self . ty ) ;
2890
2892
2891
- let env = self . env . clone ( ) ;
2892
- let krate = krate. id ;
2893
+ let krate = match scope. krate ( ) {
2894
+ Some ( k) => k,
2895
+ None => return ,
2896
+ } ;
2897
+ let environment = scope. resolver ( ) . generic_def ( ) . map_or_else (
2898
+ || Arc :: new ( TraitEnvironment :: empty ( krate. id ) ) ,
2899
+ |d| db. trait_environment ( d) ,
2900
+ ) ;
2893
2901
2894
- method_resolution:: iterate_method_candidates_dyn (
2902
+ method_resolution:: iterate_path_candidates (
2895
2903
& canonical,
2896
2904
db,
2897
- env,
2898
- krate,
2905
+ environment,
2899
2906
traits_in_scope,
2900
2907
with_local_impls. and_then ( |b| b. id . containing_block ( ) ) . into ( ) ,
2901
2908
name,
2902
- method_resolution:: LookupMode :: Path ,
2903
- & mut |ty, id| callback ( & ty. value , id) ,
2909
+ & mut |id| callback ( id) ,
2904
2910
) ;
2905
2911
}
2906
2912
0 commit comments