@@ -9,8 +9,8 @@ use hir_ty::{
99use itertools:: Itertools ;
1010
1111use crate :: {
12- Adt , AsAssocItem , Const , ConstParam , Field , Function , GenericDef , Local , ModuleDef ,
13- SemanticsScope , Static , Struct , StructKind , Trait , Type , Variant ,
12+ Adt , AsAssocItem , AssocItemContainer , Const , ConstParam , Field , Function , GenericDef , Local ,
13+ ModuleDef , SemanticsScope , Static , Struct , StructKind , Trait , Type , Variant ,
1414} ;
1515
1616/// Helper function to get path to `ModuleDef`
@@ -138,7 +138,17 @@ impl Expr {
138138 let db = sema_scope. db ;
139139 let mod_item_path_str = |s, def| mod_item_path_str ( s, def, cfg) ;
140140 match self {
141- Expr :: Const ( it) => mod_item_path_str ( sema_scope, & ModuleDef :: Const ( * it) ) ,
141+ Expr :: Const ( it) => match it. as_assoc_item ( db) . map ( |it| it. container ( db) ) {
142+ Some ( container) => {
143+ let container_name = container_name ( container, sema_scope, cfg) ?;
144+ let const_name = it
145+ . name ( db)
146+ . map ( |c| c. display ( db. upcast ( ) ) . to_string ( ) )
147+ . unwrap_or ( String :: new ( ) ) ;
148+ Ok ( format ! ( "{container_name}::{const_name}" ) )
149+ }
150+ None => mod_item_path_str ( sema_scope, & ModuleDef :: Const ( * it) ) ,
151+ } ,
142152 Expr :: Static ( it) => mod_item_path_str ( sema_scope, & ModuleDef :: Static ( * it) ) ,
143153 Expr :: Local ( it) => Ok ( it. name ( db) . display ( db. upcast ( ) ) . to_string ( ) ) ,
144154 Expr :: ConstParam ( it) => Ok ( it. name ( db) . display ( db. upcast ( ) ) . to_string ( ) ) ,
@@ -153,22 +163,7 @@ impl Expr {
153163
154164 match func. as_assoc_item ( db) . map ( |it| it. container ( db) ) {
155165 Some ( container) => {
156- let container_name = match container {
157- crate :: AssocItemContainer :: Trait ( trait_) => {
158- mod_item_path_str ( sema_scope, & ModuleDef :: Trait ( trait_) ) ?
159- }
160- crate :: AssocItemContainer :: Impl ( imp) => {
161- let self_ty = imp. self_ty ( db) ;
162- // Should it be guaranteed that `mod_item_path` always exists?
163- match self_ty
164- . as_adt ( )
165- . and_then ( |adt| mod_item_path ( sema_scope, & adt. into ( ) , cfg) )
166- {
167- Some ( path) => path. display ( sema_scope. db . upcast ( ) ) . to_string ( ) ,
168- None => self_ty. display ( db) . to_string ( ) ,
169- }
170- }
171- } ;
166+ let container_name = container_name ( container, sema_scope, cfg) ?;
172167 let fn_name = func. name ( db) . display ( db. upcast ( ) ) . to_string ( ) ;
173168 Ok ( format ! ( "{container_name}::{fn_name}({args})" ) )
174169 }
@@ -414,3 +409,25 @@ impl Expr {
414409 matches ! ( self , Expr :: Many ( _) )
415410 }
416411}
412+
413+ /// Helper function to find name of container
414+ fn container_name (
415+ container : AssocItemContainer ,
416+ sema_scope : & SemanticsScope < ' _ > ,
417+ cfg : ImportPathConfig ,
418+ ) -> Result < String , DisplaySourceCodeError > {
419+ let container_name = match container {
420+ crate :: AssocItemContainer :: Trait ( trait_) => {
421+ mod_item_path_str ( sema_scope, & ModuleDef :: Trait ( trait_) , cfg) ?
422+ }
423+ crate :: AssocItemContainer :: Impl ( imp) => {
424+ let self_ty = imp. self_ty ( sema_scope. db ) ;
425+ // Should it be guaranteed that `mod_item_path` always exists?
426+ match self_ty. as_adt ( ) . and_then ( |adt| mod_item_path ( sema_scope, & adt. into ( ) , cfg) ) {
427+ Some ( path) => path. display ( sema_scope. db . upcast ( ) ) . to_string ( ) ,
428+ None => self_ty. display ( sema_scope. db ) . to_string ( ) ,
429+ }
430+ }
431+ } ;
432+ Ok ( container_name)
433+ }
0 commit comments