@@ -42,7 +42,7 @@ use hir_def::{
4242 adt:: VariantData ,
4343 body:: { BodyDiagnostic , SyntheticSyntax } ,
4444 expr:: { BindingAnnotation , ExprOrPatId , LabelId , Pat , PatId } ,
45- generics:: { ConstParamData , LifetimeParamData , TypeOrConstParamData , TypeParamProvenance } ,
45+ generics:: { LifetimeParamData , TypeOrConstParamData , TypeParamProvenance } ,
4646 item_tree:: ItemTreeNode ,
4747 lang_item:: { LangItem , LangItemTarget } ,
4848 layout:: { Layout , LayoutError , ReprOptions } ,
@@ -1189,31 +1189,6 @@ impl Adt {
11891189 . map ( |arena| arena. 1 . clone ( ) )
11901190 }
11911191
1192- /// Returns an iterator of all `const` generic paramaters
1193- ///
1194- /// This method is not well optimized, I could not statisfy the borrow
1195- /// checker. I'm sure there are smarter ways to return the consts names
1196- pub fn consts ( & self , db : & dyn HirDatabase ) -> impl Iterator < Item = ConstParamData > {
1197- let resolver = match self {
1198- Adt :: Struct ( s) => s. id . resolver ( db. upcast ( ) ) ,
1199- Adt :: Union ( u) => u. id . resolver ( db. upcast ( ) ) ,
1200- Adt :: Enum ( e) => e. id . resolver ( db. upcast ( ) ) ,
1201- } ;
1202- resolver
1203- . generic_params ( )
1204- . map_or ( vec ! [ ] , |gp| {
1205- gp. as_ref ( )
1206- . type_or_consts
1207- . iter ( )
1208- . filter_map ( |arena| match arena. 1 {
1209- TypeOrConstParamData :: ConstParamData ( consts) => Some ( consts. clone ( ) ) ,
1210- _ => None ,
1211- } )
1212- . collect :: < Vec < ConstParamData > > ( )
1213- } )
1214- . into_iter ( )
1215- }
1216-
12171192 pub fn as_enum ( & self ) -> Option < Enum > {
12181193 if let Self :: Enum ( v) = self {
12191194 Some ( * v)
@@ -3373,6 +3348,24 @@ impl Type {
33733348 }
33743349 }
33753350
3351+ /// Iterates its type arguments
3352+ ///
3353+ /// It iterates the actual type arguments when concrete types are used
3354+ /// and otherwise the generic names.
3355+ /// It does not include `const` arguments.
3356+ ///
3357+ /// For code, such as:
3358+ /// ```text
3359+ /// struct Foo<T, U>
3360+ ///
3361+ /// impl<U> Foo<String, U>
3362+ /// ```
3363+ ///
3364+ /// It iterates:
3365+ /// ```text
3366+ /// - "String"
3367+ /// - "U"
3368+ /// ```
33763369 pub fn type_arguments ( & self ) -> impl Iterator < Item = Type > + ' _ {
33773370 self . ty
33783371 . strip_references ( )
@@ -3383,6 +3376,46 @@ impl Type {
33833376 . map ( move |ty| self . derived ( ty) )
33843377 }
33853378
3379+ /// Iterates its type and const arguments
3380+ ///
3381+ /// It iterates the actual type and const arguments when concrete types
3382+ /// are used and otherwise the generic names.
3383+ ///
3384+ /// For code, such as:
3385+ /// ```text
3386+ /// struct Foo<T, const U: usize, const X: usize>
3387+ ///
3388+ /// impl<U> Foo<String, U, 12>
3389+ /// ```
3390+ ///
3391+ /// It iterates:
3392+ /// ```text
3393+ /// - "String"
3394+ /// - "U"
3395+ /// - "12"
3396+ /// ```
3397+ pub fn type_and_const_arguments < ' a > (
3398+ & ' a self ,
3399+ db : & ' a dyn HirDatabase ,
3400+ ) -> impl Iterator < Item = SmolStr > + ' a {
3401+ self . ty
3402+ . strip_references ( )
3403+ . as_adt ( )
3404+ . into_iter ( )
3405+ . flat_map ( |( _, substs) | substs. iter ( Interner ) )
3406+ . filter_map ( |arg| {
3407+ // arg can be either a `Ty` or `constant`
3408+ if let Some ( ty) = arg. ty ( Interner ) {
3409+ Some ( SmolStr :: new ( ty. display ( db) . to_string ( ) ) )
3410+ // Some(ty)
3411+ } else if let Some ( const_) = arg. constant ( Interner ) {
3412+ Some ( SmolStr :: new_inline ( & const_. display ( db) . to_string ( ) ) )
3413+ } else {
3414+ None
3415+ }
3416+ } )
3417+ }
3418+
33863419 /// Combines lifetime indicators, type and constant parameters into a single `Iterator`
33873420 pub fn lifetime_type_const_paramaters < ' a > (
33883421 & ' a self ,
@@ -3392,12 +3425,8 @@ impl Type {
33923425 self . as_adt ( )
33933426 . and_then ( |a| a. lifetime ( db) . and_then ( |lt| Some ( ( & lt. name ) . to_smol_str ( ) ) ) )
33943427 . into_iter ( )
3395- // add the type paramaters
3396- . chain ( self . type_arguments ( ) . map ( |ty| SmolStr :: new ( ty. display ( db) . to_string ( ) ) ) )
3397- // add const paramameters
3398- . chain ( self . as_adt ( ) . map_or ( vec ! [ ] , |a| {
3399- a. consts ( db) . map ( |cs| cs. name . to_smol_str ( ) ) . collect :: < Vec < SmolStr > > ( )
3400- } ) )
3428+ // add the type and const paramaters
3429+ . chain ( self . type_and_const_arguments ( db) )
34013430 }
34023431
34033432 pub fn iterate_method_candidates_with_traits < T > (
0 commit comments