@@ -1809,6 +1809,25 @@ impl HirDisplay for Path {
18091809 }
18101810 }
18111811
1812+ // Convert trait's `Self` bound back to the surface syntax. Note there is no associated
1813+ // trait, so there can only be one path segment that `has_self_type`. The `Self` type
1814+ // itself can contain further qualified path through, which will be handled by recursive
1815+ // `hir_fmt`s.
1816+ //
1817+ // `trait_mod::Trait<Self = type_mod::Type, Args>::Assoc`
1818+ // =>
1819+ // `<type_mod::Type as trait_mod::Trait<Args>>::Assoc`
1820+ let trait_self_ty = self . segments ( ) . iter ( ) . find_map ( |seg| {
1821+ let generic_args = seg. args_and_bindings ?;
1822+ generic_args. has_self_type . then ( || & generic_args. args [ 0 ] )
1823+ } ) ;
1824+ if let Some ( ty) = trait_self_ty {
1825+ write ! ( f, "<" ) ?;
1826+ ty. hir_fmt ( f) ?;
1827+ write ! ( f, " as " ) ?;
1828+ // Now format the path of the trait...
1829+ }
1830+
18121831 for ( seg_idx, segment) in self . segments ( ) . iter ( ) . enumerate ( ) {
18131832 if !matches ! ( self . kind( ) , PathKind :: Plain ) || seg_idx > 0 {
18141833 write ! ( f, "::" ) ?;
@@ -1840,15 +1859,12 @@ impl HirDisplay for Path {
18401859 return Ok ( ( ) ) ;
18411860 }
18421861
1843- write ! ( f, "<" ) ?;
18441862 let mut first = true ;
1845- for arg in generic_args. args . iter ( ) {
1863+ // Skip the `Self` bound if exists. It's handled outside the loop.
1864+ for arg in & generic_args. args [ generic_args. has_self_type as usize ..] {
18461865 if first {
18471866 first = false ;
1848- if generic_args. has_self_type {
1849- // FIXME: Convert to `<Ty as Trait>` form.
1850- write ! ( f, "Self = " ) ?;
1851- }
1867+ write ! ( f, "<" ) ?;
18521868 } else {
18531869 write ! ( f, ", " ) ?;
18541870 }
@@ -1857,6 +1873,7 @@ impl HirDisplay for Path {
18571873 for binding in generic_args. bindings . iter ( ) {
18581874 if first {
18591875 first = false ;
1876+ write ! ( f, "<" ) ?;
18601877 } else {
18611878 write ! ( f, ", " ) ?;
18621879 }
@@ -1872,9 +1889,20 @@ impl HirDisplay for Path {
18721889 }
18731890 }
18741891 }
1875- write ! ( f, ">" ) ?;
1892+
1893+ // There may be no generic arguments to print, in case of a trait having only a
1894+ // single `Self` bound which is converted to `<Ty as Trait>::Assoc`.
1895+ if !first {
1896+ write ! ( f, ">" ) ?;
1897+ }
1898+
1899+ // Current position: `<Ty as Trait<Args>|`
1900+ if generic_args. has_self_type {
1901+ write ! ( f, ">" ) ?;
1902+ }
18761903 }
18771904 }
1905+
18781906 Ok ( ( ) )
18791907 }
18801908}
0 commit comments