@@ -42,7 +42,7 @@ use hir_def::{
42
42
adt:: VariantData ,
43
43
body:: { BodyDiagnostic , SyntheticSyntax } ,
44
44
expr:: { BindingAnnotation , ExprOrPatId , LabelId , Pat , PatId } ,
45
- generics:: { ConstParamData , LifetimeParamData , TypeOrConstParamData , TypeParamProvenance } ,
45
+ generics:: { LifetimeParamData , TypeOrConstParamData , TypeParamProvenance } ,
46
46
item_tree:: ItemTreeNode ,
47
47
lang_item:: { LangItem , LangItemTarget } ,
48
48
layout:: { Layout , LayoutError , ReprOptions } ,
@@ -1189,31 +1189,6 @@ impl Adt {
1189
1189
. map ( |arena| arena. 1 . clone ( ) )
1190
1190
}
1191
1191
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
-
1217
1192
pub fn as_enum ( & self ) -> Option < Enum > {
1218
1193
if let Self :: Enum ( v) = self {
1219
1194
Some ( * v)
@@ -3373,6 +3348,24 @@ impl Type {
3373
3348
}
3374
3349
}
3375
3350
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
+ /// ```
3376
3369
pub fn type_arguments ( & self ) -> impl Iterator < Item = Type > + ' _ {
3377
3370
self . ty
3378
3371
. strip_references ( )
@@ -3383,6 +3376,46 @@ impl Type {
3383
3376
. map ( move |ty| self . derived ( ty) )
3384
3377
}
3385
3378
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
+
3386
3419
/// Combines lifetime indicators, type and constant parameters into a single `Iterator`
3387
3420
pub fn lifetime_type_const_paramaters < ' a > (
3388
3421
& ' a self ,
@@ -3392,12 +3425,8 @@ impl Type {
3392
3425
self . as_adt ( )
3393
3426
. and_then ( |a| a. lifetime ( db) . and_then ( |lt| Some ( ( & lt. name ) . to_smol_str ( ) ) ) )
3394
3427
. 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) )
3401
3430
}
3402
3431
3403
3432
pub fn iterate_method_candidates_with_traits < T > (
0 commit comments