Skip to content

Commit 957500b

Browse files
Ariel Ben-Yehudaarielb1
Ariel Ben-Yehuda
authored andcommitted
rewrite obligation forest. cycles still handled incorrectly.
1 parent dee865a commit 957500b

File tree

13 files changed

+617
-748
lines changed

13 files changed

+617
-748
lines changed

src/librustc/traits/error_reporting.rs

Lines changed: 2 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -511,115 +511,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
511511
/// that we can give a more helpful error message (and, in particular,
512512
/// we do not suggest increasing the overflow limit, which is not
513513
/// going to help).
514-
pub fn report_overflow_error_cycle(&self, cycle: &Vec<PredicateObligation<'tcx>>) -> ! {
515-
assert!(cycle.len() > 1);
516-
517-
debug!("report_overflow_error_cycle(cycle length = {})", cycle.len());
518-
519-
let cycle = self.resolve_type_vars_if_possible(cycle);
514+
pub fn report_overflow_error_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! {
515+
let cycle = self.resolve_type_vars_if_possible(&cycle.to_owned());
520516

521517
debug!("report_overflow_error_cycle: cycle={:?}", cycle);
522518

523-
assert_eq!(&cycle[0].predicate, &cycle.last().unwrap().predicate);
524-
525-
self.try_report_overflow_error_type_of_infinite_size(&cycle);
526519
self.report_overflow_error(&cycle[0], false);
527520
}
528521

529-
/// If a cycle results from evaluated whether something is Sized, that
530-
/// is a particular special case that always results from a struct or
531-
/// enum definition that lacks indirection (e.g., `struct Foo { x: Foo
532-
/// }`). We wish to report a targeted error for this case.
533-
pub fn try_report_overflow_error_type_of_infinite_size(&self,
534-
cycle: &[PredicateObligation<'tcx>])
535-
{
536-
let sized_trait = match self.tcx.lang_items.sized_trait() {
537-
Some(v) => v,
538-
None => return,
539-
};
540-
let top_is_sized = {
541-
match cycle[0].predicate {
542-
ty::Predicate::Trait(ref data) => data.def_id() == sized_trait,
543-
_ => false,
544-
}
545-
};
546-
if !top_is_sized {
547-
return;
548-
}
549-
550-
// The only way to have a type of infinite size is to have,
551-
// somewhere, a struct/enum type involved. Identify all such types
552-
// and report the cycle to the user.
553-
554-
let struct_enum_tys: Vec<_> =
555-
cycle.iter()
556-
.flat_map(|obligation| match obligation.predicate {
557-
ty::Predicate::Trait(ref data) => {
558-
assert_eq!(data.def_id(), sized_trait);
559-
let self_ty = data.skip_binder().trait_ref.self_ty(); // (*)
560-
// (*) ok to skip binder because this is just
561-
// error reporting and regions don't really
562-
// matter
563-
match self_ty.sty {
564-
ty::TyEnum(..) | ty::TyStruct(..) => Some(self_ty),
565-
_ => None,
566-
}
567-
}
568-
_ => {
569-
span_bug!(obligation.cause.span,
570-
"Sized cycle involving non-trait-ref: {:?}",
571-
obligation.predicate);
572-
}
573-
})
574-
.collect();
575-
576-
assert!(!struct_enum_tys.is_empty());
577-
578-
// This is a bit tricky. We want to pick a "main type" in the
579-
// listing that is local to the current crate, so we can give a
580-
// good span to the user. But it might not be the first one in our
581-
// cycle list. So find the first one that is local and then
582-
// rotate.
583-
let (main_index, main_def_id) =
584-
struct_enum_tys.iter()
585-
.enumerate()
586-
.filter_map(|(index, ty)| match ty.sty {
587-
ty::TyEnum(adt_def, _) | ty::TyStruct(adt_def, _)
588-
if adt_def.did.is_local() =>
589-
Some((index, adt_def.did)),
590-
_ =>
591-
None,
592-
})
593-
.next()
594-
.unwrap(); // should always be SOME local type involved!
595-
596-
// Rotate so that the "main" type is at index 0.
597-
let struct_enum_tys: Vec<_> =
598-
struct_enum_tys.iter()
599-
.cloned()
600-
.skip(main_index)
601-
.chain(struct_enum_tys.iter().cloned().take(main_index))
602-
.collect();
603-
604-
let tcx = self.tcx;
605-
let mut err = tcx.recursive_type_with_infinite_size_error(main_def_id);
606-
let len = struct_enum_tys.len();
607-
if len > 2 {
608-
err.note(&format!("type `{}` is embedded within `{}`...",
609-
struct_enum_tys[0],
610-
struct_enum_tys[1]));
611-
for &next_ty in &struct_enum_tys[1..len-1] {
612-
err.note(&format!("...which in turn is embedded within `{}`...", next_ty));
613-
}
614-
err.note(&format!("...which in turn is embedded within `{}`, \
615-
completing the cycle.",
616-
struct_enum_tys[len-1]));
617-
}
618-
err.emit();
619-
self.tcx.sess.abort_if_errors();
620-
bug!();
621-
}
622-
623522
pub fn report_selection_error(&self,
624523
obligation: &PredicateObligation<'tcx>,
625524
error: &SelectionError<'tcx>,

0 commit comments

Comments
 (0)