Skip to content

Commit d21861d

Browse files
Refactor one_bound_for_assoc_type to take an Iterator instead of Vec.
1 parent 3abaf43 commit d21861d

File tree

1 file changed

+33
-33
lines changed

1 file changed

+33
-33
lines changed

src/librustc_typeck/astconv.rs

+33-33
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)