@@ -456,65 +456,46 @@ set_option linter.unusedVariables false
456456 }
457457
458458 /// Render generics, adding a space after each parameter
459- fn generics (
460- & self ,
461- Generics {
462- params,
463- constraints,
464- } : & Generics ,
465- ) -> DocBuilder < A > {
459+ fn generics ( & self , generics : & Generics ) -> DocBuilder < A > {
466460 docs ! [
467- zip_right!( params, line!( ) ) ,
461+ zip_right!( & generics . params, line!( ) ) ,
468462 zip_right!(
469- constraints
470- . iter( )
471- . map( |generic_constraint|
472- match generic_constraint {
473- GenericConstraint :: Type ( impl_ident) => {
474- let projections = constraints
475- . iter( )
476- . filter_map( |c|
477- if let GenericConstraint :: Projection ( p) = c {
478- if let ImplExprKind :: LocalBound { id } = & * p. impl_. kind && * id == impl_ident. name {
479- Some ( docs![ p] )
480- } else {
481- Some ( ( || emit_error!( issue 1710 , "Unsupported variant of associated type projection" ) ) ( ) )
482- }
483- } else {
484- None
485- }
486- )
487- . collect:: <Vec <_>>( ) ;
488- docs![
489- docs![
490- impl_ident. goal. trait_,
491- ".AssociatedTypes" ,
492- concat!(
493- impl_ident. goal. args. iter( ) . map( |arg| docs![ line!( ) , arg] )
494- )
495- ]
496- . brackets( )
497- . group( )
498- . nest( INDENT ) ,
463+ generics. type_constraints( ) . map( |impl_ident| {
464+ let projections = generics. projection_constraints( )
465+ . map( |p|
466+ if let ImplExprKind :: LocalBound { id } = & * p. impl_. kind && * id == impl_ident. name {
467+ docs![ p]
468+ } else {
469+ emit_error!( issue 1710 , "Unsupported variant of associated type projection" )
470+ }
471+ )
472+ . collect:: <Vec <_>>( ) ;
473+ docs![
474+ docs![
475+ impl_ident. goal. trait_,
476+ ".AssociatedTypes" ,
477+ concat!(
478+ impl_ident. goal. args. iter( ) . map( |arg| docs![ line!( ) , arg] )
479+ )
480+ ]
481+ . brackets( )
482+ . group( )
483+ . nest( INDENT ) ,
484+ line!( ) ,
485+ docs![
486+ impl_ident. goal. trait_,
487+ concat!(
488+ impl_ident. goal. args. iter( ) . map( |arg| docs![ line!( ) , arg] )
489+ ) ,
499490 line!( ) ,
500- docs![
501- impl_ident. goal. trait_,
502- concat!(
503- impl_ident. goal. args. iter( ) . map( |arg| docs![ line!( ) , arg] )
504- ) ,
505- line!( ) ,
506- self . associated_type_projections( impl_ident, projections)
507- ]
508- . brackets( )
509- . nest( INDENT )
510- . group( )
491+ self . associated_type_projections( impl_ident, projections)
511492 ]
512- . group ( ) }
513- // Projections are rendered via `self.associated_type_projections` above.
514- GenericConstraint :: Projection ( _ ) => docs! [ None ] ,
515- GenericConstraint :: Lifetime ( _ ) =>
516- unreachable_by_invariant! ( Drop_references ) ,
517- } ) ,
493+ . brackets ( )
494+ . nest ( INDENT )
495+ . group ( )
496+ ]
497+ . group ( )
498+ } ) ,
518499 line!( )
519500 ) ,
520501 ]
@@ -1097,17 +1078,10 @@ set_option linter.unusedVariables false
10971078 generics,
10981079 items,
10991080 } => {
1100- let generic_types = generics
1101- . constraints
1102- . iter ( )
1103- . map ( |constraint| match constraint {
1104- GenericConstraint :: Type ( tc_constraint) => Some ( tc_constraint) ,
1105- GenericConstraint :: Lifetime ( _) => {
1106- unreachable_by_invariant ! ( Drop_references )
1107- }
1108- GenericConstraint :: Projection ( _) => None ,
1109- } )
1110- . collect :: < Vec < _ > > ( ) ;
1081+ let generic_types = generics. type_constraints ( ) . collect :: < Vec < _ > > ( ) ;
1082+ if generic_types. len ( ) < generics. constraints . len ( ) {
1083+ emit_error ! ( issue 1710 , "Unsupported equality constraints on associated types" )
1084+ }
11111085 docs ! [
11121086 // A trait is encoded as two Lean type classes: one holding the associated types,
11131087 // and one holding all other fields.
@@ -1121,75 +1095,66 @@ set_option linter.unusedVariables false
11211095 ] ) ,
11221096 softline!( ) ,
11231097 "where"
1124- ] . group( ) ,
1098+ ]
1099+ . group( ) ,
11251100 zip_left!(
11261101 hardline!( ) ,
1127- generic_types. iter( ) . map( |maybe_impl_ident|
1128- maybe_impl_ident. map_or_else(
1129- || emit_error!( issue 1710 , "Unsupported equality constraints on associated types" ) ,
1130- |impl_ident| docs![
1131- self . fresh_constraint_name( & self . render_last( name) , impl_ident) ,
1132- " :" ,
1133- line!( ) ,
1134- & impl_ident. goal. trait_,
1135- ".AssociatedTypes" ,
1136- line!( ) ,
1137- intersperse!( & impl_ident. goal. args, line!( ) )
1138- ]
1139- . group( )
1140- . brackets( )
1141- )
1142- )
1102+ generic_types. iter( ) . map( |impl_ident| docs![
1103+ self . fresh_constraint_name( & self . render_last( name) , impl_ident) ,
1104+ " :" ,
1105+ line!( ) ,
1106+ & impl_ident. goal. trait_,
1107+ ".AssociatedTypes" ,
1108+ line!( ) ,
1109+ intersperse!( & impl_ident. goal. args, line!( ) )
1110+ ]
1111+ . group( )
1112+ . brackets( ) )
11431113 ) ,
11441114 zip_left!(
11451115 hardline!( ) ,
1146- items. iter ( ) . filter ( |item| {
1147- matches! ( item . kind , TraitItemKind :: Type ( _ ) )
1148- } )
1116+ items
1117+ . iter ( )
1118+ . filter ( |item| { matches! ( item . kind , TraitItemKind :: Type ( _ ) ) } )
11491119 ) ,
11501120 ]
11511121 . nest( INDENT ) ,
11521122 // We add the `[instance]` attribute to the contained constraints to make
11531123 // them available for type inference:
11541124 zip_left!(
11551125 docs![ hardline!( ) , hardline!( ) ] ,
1156- generic_types. iter( ) . map( |maybe_impl_ident|
1157- maybe_impl_ident. map_or_else(
1158- || emit_error!( issue 1710 , "Unsupported equality constraints on associated types" ) ,
1159- |impl_ident| docs![
1160- "attribute [instance]" ,
1161- line!( ) ,
1162- name,
1163- ".AssociatedTypes." ,
1164- self . fresh_constraint_name( & self . render_last( name) , impl_ident) ,
1165- ]
1166- . group( )
1167- . nest( INDENT )
1168- )
1169- )
1126+ generic_types. iter( ) . map( |impl_ident| docs![
1127+ "attribute [instance]" ,
1128+ line!( ) ,
1129+ name,
1130+ ".AssociatedTypes." ,
1131+ self . fresh_constraint_name( & self . render_last( name) , impl_ident) ,
1132+ ]
1133+ . group( )
1134+ . nest( INDENT ) )
11701135 ) ,
11711136 // When referencing associated types, we would like to refer to them as
11721137 // `TraitName.TypeName` instead of `TraitName.AssociatedTypes.TypeName`:
11731138 zip_left!(
11741139 docs![ hardline!( ) , hardline!( ) ] ,
1175- items. iter ( )
1176- . filter ( |item| {
1177- matches!( item. kind, TraitItemKind :: Type ( _) )
1178- } )
1179- . map ( |item| {
1180- docs! [
1181- "abbrev " ,
1182- name ,
1183- "." ,
1184- self . render_last ( & item . ident ) ,
1185- " :=" ,
1186- line! ( ) ,
1187- name , ".AssociatedTypes" ,
1188- "." ,
1189- self . render_last( & item. ident) ,
1190- ]
1191- . nest( INDENT )
1192- } )
1140+ items
1141+ . iter ( )
1142+ . filter ( |item| { matches!( item. kind, TraitItemKind :: Type ( _) ) } )
1143+ . map ( |item| {
1144+ docs! [
1145+ "abbrev " ,
1146+ name ,
1147+ "." ,
1148+ self . render_last ( & item . ident ) ,
1149+ " :=" ,
1150+ line! ( ) ,
1151+ name ,
1152+ ".AssociatedTypes" ,
1153+ "." ,
1154+ self . render_last( & item. ident) ,
1155+ ]
1156+ . nest( INDENT )
1157+ } )
11931158 ) ,
11941159 hardline!( ) ,
11951160 hardline!( ) ,
@@ -1210,7 +1175,8 @@ set_option linter.unusedVariables false
12101175 "outParam" ,
12111176 softline!( ) ,
12121177 docs![
1213- name, ".AssociatedTypes" ,
1178+ name,
1179+ ".AssociatedTypes" ,
12141180 softline!( ) ,
12151181 intersperse!( & generics. params, softline!( ) ) ,
12161182 ]
@@ -1225,25 +1191,22 @@ set_option linter.unusedVariables false
12251191 "where"
12261192 ]
12271193 . group( ) ,
1228- // Lean's `extends` does not work for us because one cannot implement
1194+ // Lean's `extends` does not work for us because one cannot implement
12291195 // different functions of the same name on the super- and on the
12301196 // subclass. So we treat supertraits like any other constraint:
12311197 zip_left!(
12321198 hardline!( ) ,
1233- generic_types. iter( ) . map( |maybe_impl_ident|
1234- maybe_impl_ident. map_or_else(
1235- || emit_error!( issue 1710 , "Unsupported equality constraints on associated types" ) ,
1236- |impl_ident| docs![
1237- self . fresh_constraint_name( & self . render_last( name) , impl_ident) ,
1238- " :" ,
1239- line!( ) ,
1240- impl_ident. goal. trait_,
1241- concat!( impl_ident. goal. args. iter( ) . map( |arg| docs![ line!( ) , arg] ) )
1242- ]
1243- . group( )
1244- . brackets( )
1199+ generic_types. iter( ) . map( |impl_ident| docs![
1200+ self . fresh_constraint_name( & self . render_last( name) , impl_ident) ,
1201+ " :" ,
1202+ line!( ) ,
1203+ impl_ident. goal. trait_,
1204+ concat!(
1205+ impl_ident. goal. args. iter( ) . map( |arg| docs![ line!( ) , arg] )
12451206 )
1246- )
1207+ ]
1208+ . group( )
1209+ . brackets( ) )
12471210 ) ,
12481211 zip_left!(
12491212 hardline!( ) ,
@@ -1261,21 +1224,15 @@ set_option linter.unusedVariables false
12611224 // them available for type inference:
12621225 zip_left!(
12631226 docs![ hardline!( ) , hardline!( ) ] ,
1264- generic_types. iter( ) . map( |maybe_impl_ident|
1265- maybe_impl_ident. map_or_else(
1266- || emit_error!( issue 1710 , "Unsupported equality constraints on associated types" ) ,
1267- |impl_ident|
1268- docs![
1269- "attribute [instance]" ,
1270- line!( ) ,
1271- name,
1272- "." ,
1273- self . fresh_constraint_name( & self . render_last( name) , impl_ident) ,
1274- ]
1275- . group( )
1276- . nest( INDENT )
1277- )
1278- )
1227+ generic_types. iter( ) . map( |impl_ident| docs![
1228+ "attribute [instance]" ,
1229+ line!( ) ,
1230+ name,
1231+ "." ,
1232+ self . fresh_constraint_name( & self . render_last( name) , impl_ident) ,
1233+ ]
1234+ . group( )
1235+ . nest( INDENT ) )
12791236 ) ,
12801237 ]
12811238 }
0 commit comments