@@ -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 , TraitRef ,
30
- Ty , 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;
@@ -1379,8 +1379,17 @@ impl Type {
1379
1379
self . ty . value . dyn_trait ( ) . map ( Into :: into)
1380
1380
}
1381
1381
1382
- pub fn as_impl_trait ( & self , db : & dyn HirDatabase ) -> Option < Trait > {
1383
- self . ty . value . impl_trait_ref ( db) . map ( |it| it. trait_ . into ( ) )
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
+ } )
1384
1393
}
1385
1394
1386
1395
pub fn as_associated_type_parent_trait ( & self , db : & dyn HirDatabase ) -> Option < Trait > {
@@ -1410,71 +1419,77 @@ impl Type {
1410
1419
}
1411
1420
1412
1421
pub fn walk ( & self , db : & dyn HirDatabase , mut cb : impl FnMut ( Type ) ) {
1413
- // TypeWalk::walk does not preserve items order!
1414
- fn walk_substs ( db : & dyn HirDatabase , substs : & Substs , cb : & mut 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
+ ) {
1415
1431
for ty in substs. iter ( ) {
1416
- walk_ty ( db, ty , cb) ;
1432
+ walk_type ( db, & type_ . derived ( ty . clone ( ) ) , cb) ;
1417
1433
}
1418
1434
}
1419
1435
1420
- fn walk_trait (
1436
+ fn walk_bounds (
1421
1437
db : & dyn HirDatabase ,
1422
- ty : Ty ,
1423
- trait_ref : & TraitRef ,
1438
+ type_ : & Type ,
1439
+ bounds : & [ GenericPredicate ] ,
1424
1440
cb : & mut impl FnMut ( Type ) ,
1425
1441
) {
1426
- let def_db: & dyn DefDatabase = db. upcast ( ) ;
1427
- let resolver = trait_ref. trait_ . resolver ( def_db) ;
1428
- let krate = trait_ref. trait_ . lookup ( def_db) . container . module ( def_db) . krate ;
1429
- cb ( Type :: new_with_resolver_inner ( db, krate, & resolver, ty) ) ;
1430
- walk_substs ( db, & trait_ref. substs , cb) ;
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
+ }
1431
1451
}
1432
1452
1433
- fn walk_ty ( db : & dyn HirDatabase , ty : & Ty , cb : & mut impl FnMut ( Type ) ) {
1434
- let def_db: & dyn DefDatabase = db. upcast ( ) ;
1435
- let ty = ty. strip_references ( ) ;
1453
+ fn walk_type ( db : & dyn HirDatabase , type_ : & Type , cb : & mut impl FnMut ( Type ) ) {
1454
+ let ty = type_. ty . value . strip_references ( ) ;
1436
1455
match ty {
1437
1456
Ty :: Apply ( ApplicationTy { ctor, parameters } ) => {
1438
1457
match ctor {
1439
- TypeCtor :: Adt ( adt ) => {
1440
- cb ( Type :: from_def ( db , adt . module ( def_db ) . krate , * adt ) ) ;
1458
+ TypeCtor :: Adt ( _ ) => {
1459
+ cb ( type_ . derived ( ty . clone ( ) ) ) ;
1441
1460
}
1442
1461
TypeCtor :: AssociatedType ( _) => {
1443
- if let Some ( trait_id) = ty. associated_type_parent_trait ( db) {
1444
- let resolver = trait_id. resolver ( def_db) ;
1445
- let krate = trait_id. lookup ( def_db) . container . module ( def_db) . krate ;
1446
- cb ( Type :: new_with_resolver_inner ( db, krate, & resolver, ty. clone ( ) ) ) ;
1462
+ if let Some ( _) = ty. associated_type_parent_trait ( db) {
1463
+ cb ( type_. derived ( ty. clone ( ) ) ) ;
1447
1464
}
1448
1465
}
1449
1466
_ => ( ) ,
1450
1467
}
1451
1468
1452
1469
// adt params, tuples, etc...
1453
- walk_substs ( db, parameters, cb) ;
1470
+ walk_substs ( db, type_ , parameters, cb) ;
1454
1471
}
1455
1472
Ty :: Opaque ( opaque_ty) => {
1456
- if let Some ( trait_ref ) = ty. impl_trait_ref ( db) {
1457
- walk_trait ( db, ty. clone ( ) , & trait_ref , cb) ;
1473
+ if let Some ( bounds ) = ty. impl_trait_bounds ( db) {
1474
+ walk_bounds ( db, & type_ . derived ( ty. clone ( ) ) , & bounds , cb) ;
1458
1475
}
1459
1476
1460
- walk_substs ( db, & opaque_ty. parameters , cb) ;
1477
+ walk_substs ( db, type_ , & opaque_ty. parameters , cb) ;
1461
1478
}
1462
1479
Ty :: Placeholder ( _) => {
1463
- if let Some ( trait_ref ) = ty. impl_trait_ref ( db) {
1464
- walk_trait ( db, ty. clone ( ) , & trait_ref , cb) ;
1480
+ if let Some ( bounds ) = ty. impl_trait_bounds ( db) {
1481
+ walk_bounds ( db, & type_ . derived ( ty. clone ( ) ) , & bounds , cb) ;
1465
1482
}
1466
1483
}
1467
- Ty :: Dyn ( _) => {
1468
- if let Some ( trait_ref) = ty. dyn_trait_ref ( ) {
1469
- walk_trait ( db, ty. clone ( ) , trait_ref, cb) ;
1470
- }
1484
+ Ty :: Dyn ( bounds) => {
1485
+ walk_bounds ( db, & type_. derived ( ty. clone ( ) ) , bounds. as_ref ( ) , cb) ;
1471
1486
}
1472
1487
1473
1488
_ => ( ) ,
1474
1489
}
1475
1490
}
1476
1491
1477
- walk_ty ( db, & self . ty . value , & mut cb) ;
1492
+ walk_type ( db, self , & mut cb) ;
1478
1493
}
1479
1494
}
1480
1495
0 commit comments