@@ -884,10 +884,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
884884 // those that do.
885885 self . ensure_super_predicates ( binding. span , trait_ref. def_id ( ) ) ?;
886886
887- let candidates: Vec < ty :: PolyTraitRef > =
887+ let candidates =
888888 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 ) ) ;
891890
892891 let candidate = self . one_bound_for_assoc_type ( candidates,
893892 & trait_ref. to_string ( ) ,
@@ -1191,10 +1190,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
11911190
11921191 // Check that there is exactly one way to find an associated type with the
11931192 // correct name.
1194- let suitable_bounds: Vec < _ > =
1193+ let suitable_bounds =
11951194 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) ) ;
11981196
11991197 self . one_bound_for_assoc_type ( suitable_bounds,
12001198 & ty_param_name. as_str ( ) ,
@@ -1205,54 +1203,57 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
12051203
12061204 // Checks that bounds contains exactly one element and reports appropriate
12071205 // 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 ,
12101208 ty_param_name : & str ,
12111209 assoc_name : & str ,
12121210 span : Span )
12131211 -> Result < ty:: PolyTraitRef < ' tcx > , ErrorReported >
1212+ where I : Iterator < Item =ty:: PolyTraitRef < ' tcx > >
12141213 {
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+ } ;
12321226
1227+ if let Some ( bound2) = bounds. next ( ) {
1228+ let bounds = iter:: once ( bound) . chain ( iter:: once ( bound2) ) . chain ( bounds) ;
12331229 let mut err = struct_span_err ! (
12341230 self . tcx( ) . sess, span, E0221 ,
12351231 "ambiguous associated type `{}` in bounds of `{}`" ,
12361232 assoc_name,
12371233 ty_param_name) ;
12381234 err. span_label ( span, & format ! ( "ambiguous associated type `{}`" , assoc_name) ) ;
12391235
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 {
12421243 err. span_label ( span, & format ! ( "ambiguous `{}` from `{}`" ,
12431244 assoc_name,
1244- span_and_bound . 1 ) ) ;
1245+ bound ) ) ;
12451246 } else {
12461247 span_note ! ( & mut err, span,
12471248 "associated type `{}` could derive from `{}`" ,
12481249 ty_param_name,
1249- span_and_bound . 1 ) ;
1250+ bound ) ;
12501251 }
12511252 }
12521253 err. emit ( ) ;
12531254 }
12541255
1255- Ok ( bounds [ 0 ] . clone ( ) )
1256+ return Ok ( bound ) ;
12561257 }
12571258
12581259 // Create a type from a path to an associated type.
@@ -1293,11 +1294,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
12931294 return ( tcx. types . err , Def :: Err ) ;
12941295 }
12951296
1296- let candidates: Vec < ty :: PolyTraitRef > =
1297+ let candidates =
12971298 traits:: supertraits ( tcx, ty:: Binder ( trait_ref) )
12981299 . filter ( |r| self . trait_defines_associated_type_named ( r. def_id ( ) ,
1299- assoc_name) )
1300- . collect ( ) ;
1300+ assoc_name) ) ;
13011301
13021302 match self . one_bound_for_assoc_type ( candidates,
13031303 "Self" ,
0 commit comments