@@ -719,6 +719,70 @@ fn classify_name_ref(
719
719
None
720
720
} ;
721
721
722
+ let generic_arg_location = |arg : ast:: GenericArg | {
723
+ let location = find_opt_node_in_file_compensated (
724
+ sema,
725
+ original_file,
726
+ arg. syntax ( ) . parent ( ) . and_then ( ast:: GenericArgList :: cast) ,
727
+ )
728
+ . map ( |args| {
729
+ // Determine the index of the parameter in the `GenericArgList`
730
+ // (subtract 1 because `siblings` includes the node itself)
731
+ let param_idx = arg. syntax ( ) . siblings ( Direction :: Prev ) . count ( ) - 1 ;
732
+ let parent = args. syntax ( ) . parent ( ) ;
733
+ let param = parent. and_then ( |parent| {
734
+ match_ast ! {
735
+ match parent {
736
+ ast:: PathSegment ( segment) => {
737
+ match sema. resolve_path( & segment. parent_path( ) . top_path( ) ) ? {
738
+ hir:: PathResolution :: Def ( def) => match def {
739
+ hir:: ModuleDef :: Function ( func) => {
740
+ let src = func. source( sema. db) ?;
741
+ let params = src. value. generic_param_list( ) ?;
742
+ params. generic_params( ) . nth( param_idx)
743
+ }
744
+ _ => None ,
745
+ } ,
746
+ _ => None ,
747
+ }
748
+ } ,
749
+ ast:: MethodCallExpr ( call) => {
750
+ let func = sema. resolve_method_call( & call) ?;
751
+ let src = func. source( sema. db) ?;
752
+ let params = src. value. generic_param_list( ) ?;
753
+ params. generic_params( ) . nth( param_idx)
754
+ } ,
755
+ ast:: AssocTypeArg ( arg) => {
756
+ let trait_ = ast:: PathSegment :: cast( arg. syntax( ) . parent( ) ?. parent( ) ?) ?;
757
+ match sema. resolve_path( & trait_. parent_path( ) . top_path( ) ) ? {
758
+ hir:: PathResolution :: Def ( def) => match def {
759
+ hir:: ModuleDef :: Trait ( trait_) => {
760
+ let trait_items = trait_. items( sema. db) ;
761
+ let assoc_ty = trait_items. iter( ) . find_map( |item| match item {
762
+ hir:: AssocItem :: TypeAlias ( assoc_ty) => {
763
+ ( assoc_ty. name( sema. db) . as_str( ) ? == arg. name_ref( ) ?. text( ) )
764
+ . then_some( assoc_ty)
765
+ } ,
766
+ _ => None ,
767
+ } ) ?;
768
+ let src = assoc_ty. source( sema. db) ?;
769
+ let params = src. value. generic_param_list( ) ?;
770
+ params. generic_params( ) . nth( param_idx)
771
+ }
772
+ _ => None ,
773
+ } ,
774
+ _ => None ,
775
+ }
776
+ } ,
777
+ _ => None ,
778
+ }
779
+ }
780
+ } ) ;
781
+ ( args, param)
782
+ } ) ;
783
+ TypeLocation :: GenericArgList ( location)
784
+ } ;
785
+
722
786
let type_location = |node : & SyntaxNode | {
723
787
let parent = node. parent ( ) ?;
724
788
let res = match_ast ! {
@@ -774,34 +838,8 @@ fn classify_name_ref(
774
838
ast:: TypeBound ( _) => TypeLocation :: TypeBound ,
775
839
// is this case needed?
776
840
ast:: TypeBoundList ( _) => TypeLocation :: TypeBound ,
777
- ast:: GenericArg ( it) => {
778
- let location = find_opt_node_in_file_compensated( sema, original_file, it. syntax( ) . parent( ) . and_then( ast:: GenericArgList :: cast) )
779
- . map( |args| {
780
- // Determine the index of the parameter in the `GenericArgList`
781
- // (subtract 1 because `siblings` includes the node itself)
782
- let param_idx = it. syntax( ) . siblings( Direction :: Prev ) . count( ) - 1 ;
783
- let param = args
784
- . syntax( )
785
- . parent( )
786
- . and_then( |p| ast:: PathSegment :: cast( p) )
787
- . and_then( |segment| sema. resolve_path( & segment. parent_path( ) . top_path( ) ) )
788
- . and_then( |resolved| {
789
- match resolved {
790
- hir:: PathResolution :: Def ( def) => match def {
791
- hir:: ModuleDef :: Function ( func) => {
792
- let src = func. source( sema. db) ?;
793
- let params = src. value. generic_param_list( ) ?;
794
- params. generic_params( ) . nth( param_idx)
795
- }
796
- _ => None ,
797
- } ,
798
- _ => None ,
799
- }
800
- } ) ;
801
- ( args, param)
802
- } ) ;
803
- TypeLocation :: GenericArgList ( location)
804
- } ,
841
+ ast:: TypeArg ( it) => generic_arg_location( ast:: GenericArg :: TypeArg ( it) ) ,
842
+ ast:: GenericArg ( it) => generic_arg_location( it) ,
805
843
// is this case needed?
806
844
ast:: GenericArgList ( it) => {
807
845
let location = find_opt_node_in_file_compensated( sema, original_file, Some ( it) )
0 commit comments