@@ -8,7 +8,7 @@ use hir_def::{
88 } ,
99 lang_item:: LangItem ,
1010 type_ref:: { TypeBound , TypeRef } ,
11- AdtId , GenericDefId , ItemContainerId , ItemTreeLoc , Lookup ,
11+ AdtId , GenericDefId ,
1212} ;
1313use hir_ty:: {
1414 display:: {
@@ -34,26 +34,41 @@ impl HirDisplay for Function {
3434 let container = self . as_assoc_item ( db) . map ( |it| it. container ( db) ) ;
3535 let mut module = self . module ( db) ;
3636
37- match container {
37+ // Write container (trait or impl)
38+ let container_params = match container {
3839 Some ( AssocItemContainer :: Trait ( trait_) ) => {
39- if f. show_container_bounds ( ) && !f. db . generic_params ( trait_. id . into ( ) ) . is_empty ( ) {
40+ let params = f. db . generic_params ( trait_. id . into ( ) ) ;
41+ if f. show_container_bounds ( ) && !params. is_empty ( ) {
4042 write_trait_header ( & trait_, f) ?;
41- f. write_str ( "\n " ) ?;
43+ f. write_char ( '\n' ) ?;
44+ has_disaplayable_predicates ( & params) . then_some ( params)
45+ } else {
46+ None
4247 }
4348 }
4449 Some ( AssocItemContainer :: Impl ( impl_) ) => {
45- if f. show_container_bounds ( ) && !f. db . generic_params ( impl_. id . into ( ) ) . is_empty ( ) {
50+ let params = f. db . generic_params ( impl_. id . into ( ) ) ;
51+ if f. show_container_bounds ( ) && !params. is_empty ( ) {
4652 write_impl_header ( & impl_, f) ?;
47- f. write_str ( "\n " ) ?;
53+ f. write_char ( '\n' ) ?;
54+ has_disaplayable_predicates ( & params) . then_some ( params)
55+ } else {
56+ None
4857 }
49-
50- // Block-local impls are "hoisted" to the nearest (non-block) module.
51- module = module. nearest_non_block_module ( db) ;
5258 }
53- None => { }
59+ None => None ,
60+ } ;
61+
62+ // Write signature of the function
63+
64+ // Block-local impls are "hoisted" to the nearest (non-block) module.
65+ if let Some ( AssocItemContainer :: Impl ( _) ) = container {
66+ module = module. nearest_non_block_module ( db) ;
5467 }
5568 let module_id = module. id ;
69+
5670 write_visibility ( module_id, self . visibility ( db) , f) ?;
71+
5772 if data. has_default_kw ( ) {
5873 f. write_str ( "default " ) ?;
5974 }
@@ -134,8 +149,19 @@ impl HirDisplay for Function {
134149 }
135150 }
136151
137- write_where_clause ( GenericDefId :: FunctionId ( self . id ) , f) ?;
138-
152+ // Write where clauses
153+ let has_written_where = write_where_clause ( GenericDefId :: FunctionId ( self . id ) , f) ?;
154+ if let Some ( container_params) = container_params {
155+ if !has_written_where {
156+ f. write_str ( "\n where" ) ?;
157+ }
158+ let container_name = match container. unwrap ( ) {
159+ AssocItemContainer :: Trait ( _) => "trait" ,
160+ AssocItemContainer :: Impl ( _) => "impl" ,
161+ } ;
162+ write ! ( f, "\n // Bounds from {container_name}:" , ) ?;
163+ write_where_predicates ( & container_params, f) ?;
164+ }
139165 Ok ( ( ) )
140166 }
141167}
@@ -575,48 +601,26 @@ fn write_where_clause(
575601 f : & mut HirFormatter < ' _ > ,
576602) -> Result < bool , HirDisplayError > {
577603 let params = f. db . generic_params ( def) ;
578-
579- let container = match def {
580- GenericDefId :: FunctionId ( id) if f. show_container_bounds ( ) => {
581- match id. lookup ( f. db . upcast ( ) ) . container ( ) {
582- ItemContainerId :: ImplId ( it) => Some ( ( "impl" , it. into ( ) ) ) ,
583- ItemContainerId :: TraitId ( it) => Some ( ( "trait" , it. into ( ) ) ) ,
584- _ => None ,
585- }
586- . map ( |( name, def) | ( name, f. db . generic_params ( def) ) )
587- }
588- _ => None ,
589- } ;
590-
591- let no_displayable_pred = |params : & Interned < GenericParams > | {
592- params. where_predicates . iter ( ) . all ( |pred| {
593- matches ! (
594- pred,
595- WherePredicate :: TypeBound { target: WherePredicateTypeTarget :: TypeOrConstParam ( id) , .. }
596- if params. type_or_consts[ * id] . name( ) . is_none( )
597- )
598- } )
599- } ;
600-
601- let container_bounds_no_displayable =
602- container. as_ref ( ) . map_or ( true , |( _, p) | no_displayable_pred ( p) ) ;
603- if no_displayable_pred ( & params) && container_bounds_no_displayable {
604+ if !has_disaplayable_predicates ( & params) {
604605 return Ok ( false ) ;
605606 }
606607
607608 f. write_str ( "\n where" ) ?;
608609 write_where_predicates ( & params, f) ?;
609610
610- if let Some ( ( name, container_params) ) = container {
611- if !container_bounds_no_displayable {
612- write ! ( f, "\n // Bounds from {}:" , name) ?;
613- write_where_predicates ( & container_params, f) ?;
614- }
615- }
616-
617611 Ok ( true )
618612}
619613
614+ fn has_disaplayable_predicates ( params : & Interned < GenericParams > ) -> bool {
615+ params. where_predicates . iter ( ) . any ( |pred| {
616+ !matches ! (
617+ pred,
618+ WherePredicate :: TypeBound { target: WherePredicateTypeTarget :: TypeOrConstParam ( id) , .. }
619+ if params. type_or_consts[ * id] . name( ) . is_none( )
620+ )
621+ } )
622+ }
623+
620624fn write_where_predicates (
621625 params : & Interned < GenericParams > ,
622626 f : & mut HirFormatter < ' _ > ,
0 commit comments