@@ -8,7 +8,7 @@ use hir_def::{
88 } ,
99 lang_item:: LangItem ,
1010 type_ref:: { TypeBound , TypeRef } ,
11- AdtId , GenericDefId ,
11+ AdtId , GenericDefId , ItemContainerId , ItemTreeLoc , Lookup ,
1212} ;
1313use hir_ty:: {
1414 display:: {
@@ -22,7 +22,7 @@ use itertools::Itertools;
2222
2323use crate :: {
2424 Adt , AsAssocItem , AssocItem , AssocItemContainer , Const , ConstParam , Enum , ExternCrateDecl ,
25- Field , Function , GenericParam , HasCrate , HasVisibility , LifetimeParam , Macro , Module ,
25+ Field , Function , GenericParam , HasCrate , HasVisibility , Impl , LifetimeParam , Macro , Module ,
2626 SelfParam , Static , Struct , Trait , TraitAlias , TupleField , TyBuilder , Type , TypeAlias ,
2727 TypeOrConstParam , TypeParam , Union , Variant ,
2828} ;
@@ -35,11 +35,18 @@ impl HirDisplay for Function {
3535 let mut module = self . module ( db) ;
3636
3737 match container {
38- Some ( AssocItemContainer :: Impl ( _) ) => {
38+ Some ( AssocItemContainer :: Trait ( trait_) ) => {
39+ write_trait_header ( & trait_, f) ?;
40+ f. write_str ( "\n " ) ?;
41+ }
42+ Some ( AssocItemContainer :: Impl ( impl_) ) => {
43+ write_impl_header ( & impl_, f) ?;
44+ f. write_str ( "\n " ) ?;
45+
3946 // Block-local impls are "hoisted" to the nearest (non-block) module.
4047 module = module. nearest_non_block_module ( db) ;
4148 }
42- _ => { }
49+ None => { }
4350 }
4451 let module_id = module. id ;
4552 write_visibility ( module_id, self . visibility ( db) , f) ?;
@@ -129,6 +136,24 @@ impl HirDisplay for Function {
129136 }
130137}
131138
139+ fn write_impl_header ( impl_ : & Impl , f : & mut HirFormatter < ' _ > ) -> Result < ( ) , HirDisplayError > {
140+ let db = f. db ;
141+
142+ f. write_str ( "impl" ) ?;
143+ let def_id = GenericDefId :: ImplId ( impl_. id ) ;
144+ write_generic_params ( def_id, f) ?;
145+
146+ if let Some ( trait_) = impl_. trait_ ( db) {
147+ let trait_data = db. trait_data ( trait_. id ) ;
148+ write ! ( f, " {} for" , trait_data. name. display( db. upcast( ) ) ) ?;
149+ }
150+
151+ f. write_char ( ' ' ) ?;
152+ impl_. self_ty ( db) . hir_fmt ( f) ?;
153+
154+ Ok ( ( ) )
155+ }
156+
132157impl HirDisplay for SelfParam {
133158 fn hir_fmt ( & self , f : & mut HirFormatter < ' _ > ) -> Result < ( ) , HirDisplayError > {
134159 let data = f. db . function_data ( self . func ) ;
@@ -562,6 +587,16 @@ fn write_where_clause(
562587) -> Result < bool , HirDisplayError > {
563588 let params = f. db . generic_params ( def) ;
564589
590+ let container = match def {
591+ GenericDefId :: FunctionId ( id) => match id. lookup ( f. db . upcast ( ) ) . container ( ) {
592+ ItemContainerId :: ImplId ( it) => Some ( ( "impl" , it. into ( ) ) ) ,
593+ ItemContainerId :: TraitId ( it) => Some ( ( "trait" , it. into ( ) ) ) ,
594+ _ => None ,
595+ }
596+ . map ( |( name, def) | ( name, f. db . generic_params ( def) ) ) ,
597+ _ => None ,
598+ } ;
599+
565600 let no_displayable_pred = |params : & Interned < GenericParams > | {
566601 params. where_predicates . iter ( ) . all ( |pred| {
567602 matches ! (
@@ -572,13 +607,20 @@ fn write_where_clause(
572607 } )
573608 } ;
574609
575- if no_displayable_pred ( & params) {
610+ if no_displayable_pred ( & params)
611+ && container. as_ref ( ) . map_or ( true , |( _, p) | no_displayable_pred ( p) )
612+ {
576613 return Ok ( false ) ;
577614 }
578615
579616 f. write_str ( "\n where" ) ?;
580617 write_where_predicates ( & params, f) ?;
581618
619+ if let Some ( ( name, container_params) ) = container {
620+ write ! ( f, "\n // Bounds from {}:" , name) ?;
621+ write_where_predicates ( & container_params, f) ?;
622+ }
623+
582624 Ok ( true )
583625}
584626
0 commit comments