diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2014-12-02 14:04:10 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2014-12-08 15:51:38 -0500 |
| commit | 34812b891db7a699cebddb584e6c6ae44f82ed2e (patch) | |
| tree | 50b63db5056827d614e0bc5ca485f812bd886fe3 | |
| parent | 3ee85d828ebb2502d186ff63f0215340bf79d5ad (diff) | |
| download | rust-34812b891db7a699cebddb584e6c6ae44f82ed2e.tar.gz rust-34812b891db7a699cebddb584e6c6ae44f82ed2e.zip | |
Stop masking overflow and propagate it out more aggressively; also improve error reporting to suggest to user how to fix.
| -rw-r--r-- | src/librustc/middle/traits/select.rs | 33 | ||||
| -rw-r--r-- | src/librustc_typeck/check/vtable.rs | 9 | ||||
| -rw-r--r-- | src/test/compile-fail/recursion_limit.rs | 8 | ||||
| -rw-r--r-- | src/test/compile-fail/unboxed-closures-type-mismatch.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/unboxed-closures-vtable-mismatch.rs | 2 |
5 files changed, 37 insertions, 17 deletions
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 16860e43f08..0e106227f9e 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -155,10 +155,10 @@ enum BuiltinBoundConditions<'tcx> { } #[deriving(Show)] -enum EvaluationResult { +enum EvaluationResult<'tcx> { EvaluatedToOk, - EvaluatedToErr, EvaluatedToAmbig, + EvaluatedToErr(SelectionError<'tcx>), } impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { @@ -272,7 +272,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { bound: ty::BuiltinBound, previous_stack: &ObligationStack<'o, 'tcx>, ty: Ty<'tcx>) - -> EvaluationResult + -> EvaluationResult<'tcx> { let obligation = util::obligation_for_builtin_bound( @@ -295,7 +295,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn evaluate_obligation_recursively<'o>(&mut self, previous_stack: Option<&ObligationStack<'o, 'tcx>>, obligation: &Obligation<'tcx>) - -> EvaluationResult + -> EvaluationResult<'tcx> { debug!("evaluate_obligation_recursively({})", obligation.repr(self.tcx())); @@ -310,7 +310,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn evaluate_stack<'o>(&mut self, stack: &ObligationStack<'o, 'tcx>) - -> EvaluationResult + -> EvaluationResult<'tcx> { // In intercrate mode, whenever any of the types are unbound, // there can always be an impl. Even if there are no impls in @@ -381,7 +381,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match self.candidate_from_obligation(stack) { Ok(Some(c)) => self.winnow_candidate(stack, &c), Ok(None) => EvaluatedToAmbig, - Err(_) => EvaluatedToErr, + Err(e) => EvaluatedToErr(e), } } @@ -812,14 +812,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn winnow_candidate<'o>(&mut self, stack: &ObligationStack<'o, 'tcx>, candidate: &Candidate<'tcx>) - -> EvaluationResult + -> EvaluationResult<'tcx> { debug!("winnow_candidate: candidate={}", candidate.repr(self.tcx())); self.infcx.probe(|| { let candidate = (*candidate).clone(); match self.confirm_candidate(stack.obligation, candidate) { Ok(selection) => self.winnow_selection(Some(stack), selection), - Err(_) => EvaluatedToErr, + Err(error) => EvaluatedToErr(error), } }) } @@ -827,12 +827,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn winnow_selection<'o>(&mut self, stack: Option<&ObligationStack<'o, 'tcx>>, selection: Selection<'tcx>) - -> EvaluationResult + -> EvaluationResult<'tcx> { let mut result = EvaluatedToOk; for obligation in selection.iter_nested() { match self.evaluate_obligation_recursively(stack, obligation) { - EvaluatedToErr => { return EvaluatedToErr; } + EvaluatedToErr(e) => { return EvaluatedToErr(e); } EvaluatedToAmbig => { result = EvaluatedToAmbig; } EvaluatedToOk => { } } @@ -1847,11 +1847,18 @@ impl<'o, 'tcx> Repr<'tcx> for ObligationStack<'o, 'tcx> { } } -impl EvaluationResult { +impl<'tcx> EvaluationResult<'tcx> { fn may_apply(&self) -> bool { match *self { - EvaluatedToOk | EvaluatedToAmbig => true, - EvaluatedToErr => false, + EvaluatedToOk | + EvaluatedToAmbig | + EvaluatedToErr(Overflow) | + EvaluatedToErr(OutputTypeParameterMismatch(..)) => { + true + } + EvaluatedToErr(Unimplemented) => { + false + } } } } diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs index b9f7eb3f271..80363055a4b 100644 --- a/src/librustc_typeck/check/vtable.rs +++ b/src/librustc_typeck/check/vtable.rs @@ -366,6 +366,15 @@ pub fn report_selection_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, "overflow evaluating the trait `{}` for the type `{}`", trait_ref.user_string(fcx.tcx()), self_ty.user_string(fcx.tcx())).as_slice()); + + let current_limit = fcx.tcx().sess.recursion_limit.get(); + let suggested_limit = current_limit * 2; + fcx.tcx().sess.span_note( + obligation.cause.span, + format!( + "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate", + suggested_limit)[]); + note_obligation_cause(fcx, obligation); } Unimplemented => { diff --git a/src/test/compile-fail/recursion_limit.rs b/src/test/compile-fail/recursion_limit.rs index 35713f7cfa2..17afb168a98 100644 --- a/src/test/compile-fail/recursion_limit.rs +++ b/src/test/compile-fail/recursion_limit.rs @@ -42,6 +42,10 @@ fn is_send<T:Send>() { } fn main() { is_send::<A>(); - //~^ ERROR not implemented - //~^^ ERROR not implemented + //~^ ERROR overflow evaluating + //~^^ NOTE consider adding a `#![recursion_limit="20"]` attribute to your crate + //~^^^ NOTE must be implemented + //~^^^^ ERROR overflow evaluating + //~^^^^^ NOTE consider adding a `#![recursion_limit="20"]` attribute to your crate + //~^^^^^^ NOTE must be implemented } diff --git a/src/test/compile-fail/unboxed-closures-type-mismatch.rs b/src/test/compile-fail/unboxed-closures-type-mismatch.rs index c60a99ca0df..b3528f7abe7 100644 --- a/src/test/compile-fail/unboxed-closures-type-mismatch.rs +++ b/src/test/compile-fail/unboxed-closures-type-mismatch.rs @@ -14,6 +14,6 @@ use std::ops::FnMut; pub fn main() { let mut f = |&mut: x: int, y: int| -> int { x + y }; - let z = f.call_mut((1u, 2)); //~ ERROR not implemented + let z = f.call_mut((1u, 2)); //~ ERROR type mismatch println!("{}", z); } diff --git a/src/test/compile-fail/unboxed-closures-vtable-mismatch.rs b/src/test/compile-fail/unboxed-closures-vtable-mismatch.rs index 5a22490b6d6..a96bde7cca4 100644 --- a/src/test/compile-fail/unboxed-closures-vtable-mismatch.rs +++ b/src/test/compile-fail/unboxed-closures-vtable-mismatch.rs @@ -18,7 +18,7 @@ fn call_it<F:FnMut<(int,int),int>>(y: int, mut f: F) -> int { pub fn main() { let f = |&mut: x: uint, y: int| -> int { (x as int) + y }; - let z = call_it(3, f); //~ ERROR not implemented + let z = call_it(3, f); //~ ERROR type mismatch println!("{}", z); } |
