@@ -26,8 +26,8 @@ use hir_ty::{
2626 autoderef,
2727 display:: { HirDisplayError , HirFormatter } ,
2828 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 ,
3131} ;
3232use ra_db:: { CrateId , CrateName , Edition , FileId } ;
3333use ra_prof:: profile;
@@ -1379,8 +1379,17 @@ impl Type {
13791379 self . ty . value . dyn_trait ( ) . map ( Into :: into)
13801380 }
13811381
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+ } )
13841393 }
13851394
13861395 pub fn as_associated_type_parent_trait ( & self , db : & dyn HirDatabase ) -> Option < Trait > {
@@ -1410,71 +1419,77 @@ impl Type {
14101419 }
14111420
14121421 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+ ) {
14151431 for ty in substs. iter ( ) {
1416- walk_ty ( db, ty , cb) ;
1432+ walk_type ( db, & type_ . derived ( ty . clone ( ) ) , cb) ;
14171433 }
14181434 }
14191435
1420- fn walk_trait (
1436+ fn walk_bounds (
14211437 db : & dyn HirDatabase ,
1422- ty : Ty ,
1423- trait_ref : & TraitRef ,
1438+ type_ : & Type ,
1439+ bounds : & [ GenericPredicate ] ,
14241440 cb : & mut impl FnMut ( Type ) ,
14251441 ) {
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+ }
14311451 }
14321452
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 ( ) ;
14361455 match ty {
14371456 Ty :: Apply ( ApplicationTy { ctor, parameters } ) => {
14381457 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 ( ) ) ) ;
14411460 }
14421461 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 ( ) ) ) ;
14471464 }
14481465 }
14491466 _ => ( ) ,
14501467 }
14511468
14521469 // adt params, tuples, etc...
1453- walk_substs ( db, parameters, cb) ;
1470+ walk_substs ( db, type_ , parameters, cb) ;
14541471 }
14551472 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) ;
14581475 }
14591476
1460- walk_substs ( db, & opaque_ty. parameters , cb) ;
1477+ walk_substs ( db, type_ , & opaque_ty. parameters , cb) ;
14611478 }
14621479 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) ;
14651482 }
14661483 }
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) ;
14711486 }
14721487
14731488 _ => ( ) ,
14741489 }
14751490 }
14761491
1477- walk_ty ( db, & self . ty . value , & mut cb) ;
1492+ walk_type ( db, self , & mut cb) ;
14781493 }
14791494}
14801495
0 commit comments