@@ -26,8 +26,8 @@ use hir_ty::{
26
26
autoderef,
27
27
display:: { HirDisplayError , HirFormatter } ,
28
28
expr:: ExprValidator ,
29
- method_resolution, ApplicationTy , Canonical , InEnvironment , Substs , TraitEnvironment , Ty ,
30
- TyDefId , TypeCtor ,
29
+ method_resolution, ApplicationTy , Canonical , GenericPredicate , InEnvironment , Substs ,
30
+ TraitEnvironment , Ty , TyDefId , TypeCtor ,
31
31
} ;
32
32
use ra_db:: { CrateId , CrateName , Edition , FileId } ;
33
33
use ra_prof:: profile;
@@ -186,6 +186,22 @@ impl ModuleDef {
186
186
187
187
module. visibility_of ( db, self )
188
188
}
189
+
190
+ pub fn name ( self , db : & dyn HirDatabase ) -> Option < Name > {
191
+ match self {
192
+ ModuleDef :: Adt ( it) => Some ( it. name ( db) ) ,
193
+ ModuleDef :: Trait ( it) => Some ( it. name ( db) ) ,
194
+ ModuleDef :: Function ( it) => Some ( it. name ( db) ) ,
195
+ ModuleDef :: EnumVariant ( it) => Some ( it. name ( db) ) ,
196
+ ModuleDef :: TypeAlias ( it) => Some ( it. name ( db) ) ,
197
+
198
+ ModuleDef :: Module ( it) => it. name ( db) ,
199
+ ModuleDef :: Const ( it) => it. name ( db) ,
200
+ ModuleDef :: Static ( it) => it. name ( db) ,
201
+
202
+ ModuleDef :: BuiltinType ( it) => Some ( it. as_name ( ) ) ,
203
+ }
204
+ }
189
205
}
190
206
191
207
pub use hir_def:: {
@@ -1359,6 +1375,27 @@ impl Type {
1359
1375
Some ( adt. into ( ) )
1360
1376
}
1361
1377
1378
+ pub fn as_dyn_trait ( & self ) -> Option < Trait > {
1379
+ self . ty . value . dyn_trait ( ) . map ( Into :: into)
1380
+ }
1381
+
1382
+ pub fn as_impl_traits ( & self , db : & dyn HirDatabase ) -> Option < Vec < Trait > > {
1383
+ self . ty . value . impl_trait_bounds ( db) . map ( |it| {
1384
+ it. into_iter ( )
1385
+ . filter_map ( |pred| match pred {
1386
+ hir_ty:: GenericPredicate :: Implemented ( trait_ref) => {
1387
+ Some ( Trait :: from ( trait_ref. trait_ ) )
1388
+ }
1389
+ _ => None ,
1390
+ } )
1391
+ . collect ( )
1392
+ } )
1393
+ }
1394
+
1395
+ pub fn as_associated_type_parent_trait ( & self , db : & dyn HirDatabase ) -> Option < Trait > {
1396
+ self . ty . value . associated_type_parent_trait ( db) . map ( Into :: into)
1397
+ }
1398
+
1362
1399
// FIXME: provide required accessors such that it becomes implementable from outside.
1363
1400
pub fn is_equal_for_find_impls ( & self , other : & Type ) -> bool {
1364
1401
match ( & self . ty . value , & other. ty . value ) {
@@ -1380,6 +1417,80 @@ impl Type {
1380
1417
ty : InEnvironment { value : ty, environment : self . ty . environment . clone ( ) } ,
1381
1418
}
1382
1419
}
1420
+
1421
+ pub fn walk ( & self , db : & dyn HirDatabase , mut cb : impl FnMut ( Type ) ) {
1422
+ // TypeWalk::walk for a Ty at first visits parameters and only after that the Ty itself.
1423
+ // We need a different order here.
1424
+
1425
+ fn walk_substs (
1426
+ db : & dyn HirDatabase ,
1427
+ type_ : & Type ,
1428
+ substs : & Substs ,
1429
+ cb : & mut impl FnMut ( Type ) ,
1430
+ ) {
1431
+ for ty in substs. iter ( ) {
1432
+ walk_type ( db, & type_. derived ( ty. clone ( ) ) , cb) ;
1433
+ }
1434
+ }
1435
+
1436
+ fn walk_bounds (
1437
+ db : & dyn HirDatabase ,
1438
+ type_ : & Type ,
1439
+ bounds : & [ GenericPredicate ] ,
1440
+ cb : & mut impl FnMut ( Type ) ,
1441
+ ) {
1442
+ for pred in bounds {
1443
+ match pred {
1444
+ GenericPredicate :: Implemented ( trait_ref) => {
1445
+ cb ( type_. clone ( ) ) ;
1446
+ walk_substs ( db, type_, & trait_ref. substs , cb) ;
1447
+ }
1448
+ _ => ( ) ,
1449
+ }
1450
+ }
1451
+ }
1452
+
1453
+ fn walk_type ( db : & dyn HirDatabase , type_ : & Type , cb : & mut impl FnMut ( Type ) ) {
1454
+ let ty = type_. ty . value . strip_references ( ) ;
1455
+ match ty {
1456
+ Ty :: Apply ( ApplicationTy { ctor, parameters } ) => {
1457
+ match ctor {
1458
+ TypeCtor :: Adt ( _) => {
1459
+ cb ( type_. derived ( ty. clone ( ) ) ) ;
1460
+ }
1461
+ TypeCtor :: AssociatedType ( _) => {
1462
+ if let Some ( _) = ty. associated_type_parent_trait ( db) {
1463
+ cb ( type_. derived ( ty. clone ( ) ) ) ;
1464
+ }
1465
+ }
1466
+ _ => ( ) ,
1467
+ }
1468
+
1469
+ // adt params, tuples, etc...
1470
+ walk_substs ( db, type_, parameters, cb) ;
1471
+ }
1472
+ Ty :: Opaque ( opaque_ty) => {
1473
+ if let Some ( bounds) = ty. impl_trait_bounds ( db) {
1474
+ walk_bounds ( db, & type_. derived ( ty. clone ( ) ) , & bounds, cb) ;
1475
+ }
1476
+
1477
+ walk_substs ( db, type_, & opaque_ty. parameters , cb) ;
1478
+ }
1479
+ Ty :: Placeholder ( _) => {
1480
+ if let Some ( bounds) = ty. impl_trait_bounds ( db) {
1481
+ walk_bounds ( db, & type_. derived ( ty. clone ( ) ) , & bounds, cb) ;
1482
+ }
1483
+ }
1484
+ Ty :: Dyn ( bounds) => {
1485
+ walk_bounds ( db, & type_. derived ( ty. clone ( ) ) , bounds. as_ref ( ) , cb) ;
1486
+ }
1487
+
1488
+ _ => ( ) ,
1489
+ }
1490
+ }
1491
+
1492
+ walk_type ( db, self , & mut cb) ;
1493
+ }
1383
1494
}
1384
1495
1385
1496
impl HirDisplay for Type {
0 commit comments