Skip to content

Commit 832b707

Browse files
committed
clean the note-reporting code in report_selection_error
1 parent b23648f commit 832b707

File tree

1 file changed

+62
-39
lines changed

1 file changed

+62
-39
lines changed

src/librustc/traits/error_reporting.rs

+62-39
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,53 @@ fn on_unimplemented_note<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
174174
report
175175
}
176176

177+
fn find_similar_impl_candidates<'a, 'tcx>(
178+
infcx: &InferCtxt<'a, 'tcx>,
179+
trait_ref: ty::PolyTraitRef<'tcx>)
180+
-> Vec<ty::TraitRef<'tcx>>
181+
{
182+
let simp = fast_reject::simplify_type(infcx.tcx,
183+
trait_ref.skip_binder().self_ty(),
184+
true);
185+
let mut impl_candidates = Vec::new();
186+
let trait_def = infcx.tcx.lookup_trait_def(trait_ref.def_id());
187+
188+
match simp {
189+
Some(simp) => trait_def.for_each_impl(infcx.tcx, |def_id| {
190+
let imp = infcx.tcx.impl_trait_ref(def_id).unwrap();
191+
let imp_simp = fast_reject::simplify_type(infcx.tcx,
192+
imp.self_ty(),
193+
true);
194+
if let Some(imp_simp) = imp_simp {
195+
if simp != imp_simp {
196+
return;
197+
}
198+
}
199+
impl_candidates.push(imp);
200+
}),
201+
None => trait_def.for_each_impl(infcx.tcx, |def_id| {
202+
impl_candidates.push(
203+
infcx.tcx.impl_trait_ref(def_id).unwrap());
204+
})
205+
};
206+
impl_candidates
207+
}
208+
209+
fn report_similar_impl_candidates(span: Span,
210+
err: &mut DiagnosticBuilder,
211+
impl_candidates: &[ty::TraitRef])
212+
{
213+
err.fileline_help(span, &format!("the following implementations were found:"));
214+
215+
let end = cmp::min(4, impl_candidates.len());
216+
for candidate in &impl_candidates[0..end] {
217+
err.fileline_help(span, &format!(" {:?}", candidate));
218+
}
219+
if impl_candidates.len() > 4 {
220+
err.fileline_help(span, &format!("and {} others", impl_candidates.len()-4));
221+
}
222+
}
223+
177224
/// Reports that an overflow has occurred and halts compilation. We
178225
/// halt compilation unconditionally because it is important that
179226
/// overflows never be masked -- they basically represent computations
@@ -364,59 +411,35 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
364411
"the trait bound `{}` is not satisfied",
365412
trait_ref.to_predicate());
366413

367-
// Try to report a good error message.
414+
// Try to report a help message
368415

369416
if !trait_ref.has_infer_types() &&
370417
predicate_can_apply(infcx, trait_ref)
371418
{
419+
// If a where-clause may be useful, remind the
420+
// user that they can add it.
421+
//
422+
// don't display an on-unimplemented note, as
423+
// these notes will often be of the form
424+
// "the type `T` can't be frobnicated"
425+
// which is somewhat confusing.
372426
err.fileline_help(obligation.cause.span, &format!(
373427
"consider adding a `where {}` bound",
374428
trait_ref.to_predicate()
375429
));
376430
} else if let Some(s) = on_unimplemented_note(infcx, trait_ref,
377431
obligation.cause.span) {
432+
// Otherwise, if there is an on-unimplemented note,
433+
// display it.
378434
err.fileline_note(obligation.cause.span, &s);
379435
} else {
380-
let simp = fast_reject::simplify_type(infcx.tcx,
381-
trait_ref.self_ty(),
382-
true);
383-
let mut impl_candidates = Vec::new();
384-
let trait_def = infcx.tcx.lookup_trait_def(trait_ref.def_id());
385-
386-
match simp {
387-
Some(simp) => trait_def.for_each_impl(infcx.tcx, |def_id| {
388-
let imp = infcx.tcx.impl_trait_ref(def_id).unwrap();
389-
let imp_simp = fast_reject::simplify_type(infcx.tcx,
390-
imp.self_ty(),
391-
true);
392-
if let Some(imp_simp) = imp_simp {
393-
if simp != imp_simp {
394-
return;
395-
}
396-
}
397-
impl_candidates.push(imp);
398-
}),
399-
None => trait_def.for_each_impl(infcx.tcx, |def_id| {
400-
impl_candidates.push(
401-
infcx.tcx.impl_trait_ref(def_id).unwrap());
402-
})
403-
};
436+
// If we can't show anything useful, try to find
437+
// similar impls.
404438

439+
let impl_candidates = find_similar_impl_candidates(infcx, trait_ref);
405440
if impl_candidates.len() > 0 {
406-
err.fileline_help(
407-
obligation.cause.span,
408-
&format!("the following implementations were found:"));
409-
410-
let end = cmp::min(4, impl_candidates.len());
411-
for candidate in &impl_candidates[0..end] {
412-
err.fileline_help(obligation.cause.span,
413-
&format!(" {:?}", candidate));
414-
}
415-
if impl_candidates.len() > 4 {
416-
err.fileline_help(obligation.cause.span,
417-
&format!("and {} others",
418-
impl_candidates.len()-4));
419-
}
441+
report_similar_impl_candidates(obligation.cause.span,
442+
&mut err, &impl_candidates);
420443
}
421444
}
422445
note_obligation_cause(infcx, &mut err, obligation);

0 commit comments

Comments
 (0)