@@ -884,10 +884,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
884
884
// those that do.
885
885
self . ensure_super_predicates ( binding. span , trait_ref. def_id ( ) ) ?;
886
886
887
- let candidates: Vec < ty :: PolyTraitRef > =
887
+ let candidates =
888
888
traits:: supertraits ( tcx, trait_ref. clone ( ) )
889
- . filter ( |r| self . trait_defines_associated_type_named ( r. def_id ( ) , binding. item_name ) )
890
- . collect ( ) ;
889
+ . filter ( |r| self . trait_defines_associated_type_named ( r. def_id ( ) , binding. item_name ) ) ;
891
890
892
891
let candidate = self . one_bound_for_assoc_type ( candidates,
893
892
& trait_ref. to_string ( ) ,
@@ -1191,10 +1190,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
1191
1190
1192
1191
// Check that there is exactly one way to find an associated type with the
1193
1192
// correct name.
1194
- let suitable_bounds: Vec < _ > =
1193
+ let suitable_bounds =
1195
1194
traits:: transitive_bounds ( tcx, & bounds)
1196
- . filter ( |b| self . trait_defines_associated_type_named ( b. def_id ( ) , assoc_name) )
1197
- . collect ( ) ;
1195
+ . filter ( |b| self . trait_defines_associated_type_named ( b. def_id ( ) , assoc_name) ) ;
1198
1196
1199
1197
self . one_bound_for_assoc_type ( suitable_bounds,
1200
1198
& ty_param_name. as_str ( ) ,
@@ -1205,54 +1203,57 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
1205
1203
1206
1204
// Checks that bounds contains exactly one element and reports appropriate
1207
1205
// errors otherwise.
1208
- fn one_bound_for_assoc_type ( & self ,
1209
- bounds : Vec < ty :: PolyTraitRef < ' tcx > > ,
1206
+ fn one_bound_for_assoc_type < I > ( & self ,
1207
+ mut bounds : I ,
1210
1208
ty_param_name : & str ,
1211
1209
assoc_name : & str ,
1212
1210
span : Span )
1213
1211
-> Result < ty:: PolyTraitRef < ' tcx > , ErrorReported >
1212
+ where I : Iterator < Item =ty:: PolyTraitRef < ' tcx > >
1214
1213
{
1215
- if bounds. is_empty ( ) {
1216
- struct_span_err ! ( self . tcx( ) . sess, span, E0220 ,
1217
- "associated type `{}` not found for `{}`" ,
1218
- assoc_name,
1219
- ty_param_name)
1220
- . span_label ( span, & format ! ( "associated type `{}` not found" , assoc_name) )
1221
- . emit ( ) ;
1222
- return Err ( ErrorReported ) ;
1223
- }
1224
-
1225
- if bounds. len ( ) > 1 {
1226
- let spans = bounds. iter ( ) . map ( |b| {
1227
- self . tcx ( ) . associated_items ( b. def_id ( ) ) . find ( |item| {
1228
- item. kind == ty:: AssociatedKind :: Type && item. name == assoc_name
1229
- } )
1230
- . and_then ( |item| self . tcx ( ) . map . span_if_local ( item. def_id ) )
1231
- } ) ;
1214
+ let bound = match bounds. next ( ) {
1215
+ Some ( bound) => bound,
1216
+ None => {
1217
+ struct_span_err ! ( self . tcx( ) . sess, span, E0220 ,
1218
+ "associated type `{}` not found for `{}`" ,
1219
+ assoc_name,
1220
+ ty_param_name)
1221
+ . span_label ( span, & format ! ( "associated type `{}` not found" , assoc_name) )
1222
+ . emit ( ) ;
1223
+ return Err ( ErrorReported ) ;
1224
+ }
1225
+ } ;
1232
1226
1227
+ if let Some ( bound2) = bounds. next ( ) {
1228
+ let bounds = iter:: once ( bound) . chain ( iter:: once ( bound2) ) . chain ( bounds) ;
1233
1229
let mut err = struct_span_err ! (
1234
1230
self . tcx( ) . sess, span, E0221 ,
1235
1231
"ambiguous associated type `{}` in bounds of `{}`" ,
1236
1232
assoc_name,
1237
1233
ty_param_name) ;
1238
1234
err. span_label ( span, & format ! ( "ambiguous associated type `{}`" , assoc_name) ) ;
1239
1235
1240
- for span_and_bound in spans. zip ( & bounds) {
1241
- if let Some ( span) = span_and_bound. 0 {
1236
+ for bound in bounds {
1237
+ let bound_span = self . tcx ( ) . associated_items ( bound. def_id ( ) ) . find ( |item| {
1238
+ item. kind == ty:: AssociatedKind :: Type && item. name == assoc_name
1239
+ } )
1240
+ . and_then ( |item| self . tcx ( ) . map . span_if_local ( item. def_id ) ) ;
1241
+
1242
+ if let Some ( span) = bound_span {
1242
1243
err. span_label ( span, & format ! ( "ambiguous `{}` from `{}`" ,
1243
1244
assoc_name,
1244
- span_and_bound . 1 ) ) ;
1245
+ bound ) ) ;
1245
1246
} else {
1246
1247
span_note ! ( & mut err, span,
1247
1248
"associated type `{}` could derive from `{}`" ,
1248
1249
ty_param_name,
1249
- span_and_bound . 1 ) ;
1250
+ bound ) ;
1250
1251
}
1251
1252
}
1252
1253
err. emit ( ) ;
1253
1254
}
1254
1255
1255
- Ok ( bounds [ 0 ] . clone ( ) )
1256
+ return Ok ( bound ) ;
1256
1257
}
1257
1258
1258
1259
// Create a type from a path to an associated type.
@@ -1293,11 +1294,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
1293
1294
return ( tcx. types . err , Def :: Err ) ;
1294
1295
}
1295
1296
1296
- let candidates: Vec < ty :: PolyTraitRef > =
1297
+ let candidates =
1297
1298
traits:: supertraits ( tcx, ty:: Binder ( trait_ref) )
1298
1299
. filter ( |r| self . trait_defines_associated_type_named ( r. def_id ( ) ,
1299
- assoc_name) )
1300
- . collect ( ) ;
1300
+ assoc_name) ) ;
1301
1301
1302
1302
match self . one_bound_for_assoc_type ( candidates,
1303
1303
"Self" ,
0 commit comments