Skip to content

Commit 34812b8

Browse files
committed
Stop masking overflow and propagate it out more aggressively; also improve error reporting to suggest to user how to fix.
1 parent 3ee85d8 commit 34812b8

File tree

5 files changed

+37
-17
lines changed

5 files changed

+37
-17
lines changed

src/librustc/middle/traits/select.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,10 @@ enum BuiltinBoundConditions<'tcx> {
155155
}
156156

157157
#[deriving(Show)]
158-
enum EvaluationResult {
158+
enum EvaluationResult<'tcx> {
159159
EvaluatedToOk,
160-
EvaluatedToErr,
161160
EvaluatedToAmbig,
161+
EvaluatedToErr(SelectionError<'tcx>),
162162
}
163163

164164
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
@@ -272,7 +272,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
272272
bound: ty::BuiltinBound,
273273
previous_stack: &ObligationStack<'o, 'tcx>,
274274
ty: Ty<'tcx>)
275-
-> EvaluationResult
275+
-> EvaluationResult<'tcx>
276276
{
277277
let obligation =
278278
util::obligation_for_builtin_bound(
@@ -295,7 +295,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
295295
fn evaluate_obligation_recursively<'o>(&mut self,
296296
previous_stack: Option<&ObligationStack<'o, 'tcx>>,
297297
obligation: &Obligation<'tcx>)
298-
-> EvaluationResult
298+
-> EvaluationResult<'tcx>
299299
{
300300
debug!("evaluate_obligation_recursively({})",
301301
obligation.repr(self.tcx()));
@@ -310,7 +310,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
310310

311311
fn evaluate_stack<'o>(&mut self,
312312
stack: &ObligationStack<'o, 'tcx>)
313-
-> EvaluationResult
313+
-> EvaluationResult<'tcx>
314314
{
315315
// In intercrate mode, whenever any of the types are unbound,
316316
// there can always be an impl. Even if there are no impls in
@@ -381,7 +381,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
381381
match self.candidate_from_obligation(stack) {
382382
Ok(Some(c)) => self.winnow_candidate(stack, &c),
383383
Ok(None) => EvaluatedToAmbig,
384-
Err(_) => EvaluatedToErr,
384+
Err(e) => EvaluatedToErr(e),
385385
}
386386
}
387387

@@ -812,27 +812,27 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
812812
fn winnow_candidate<'o>(&mut self,
813813
stack: &ObligationStack<'o, 'tcx>,
814814
candidate: &Candidate<'tcx>)
815-
-> EvaluationResult
815+
-> EvaluationResult<'tcx>
816816
{
817817
debug!("winnow_candidate: candidate={}", candidate.repr(self.tcx()));
818818
self.infcx.probe(|| {
819819
let candidate = (*candidate).clone();
820820
match self.confirm_candidate(stack.obligation, candidate) {
821821
Ok(selection) => self.winnow_selection(Some(stack), selection),
822-
Err(_) => EvaluatedToErr,
822+
Err(error) => EvaluatedToErr(error),
823823
}
824824
})
825825
}
826826

827827
fn winnow_selection<'o>(&mut self,
828828
stack: Option<&ObligationStack<'o, 'tcx>>,
829829
selection: Selection<'tcx>)
830-
-> EvaluationResult
830+
-> EvaluationResult<'tcx>
831831
{
832832
let mut result = EvaluatedToOk;
833833
for obligation in selection.iter_nested() {
834834
match self.evaluate_obligation_recursively(stack, obligation) {
835-
EvaluatedToErr => { return EvaluatedToErr; }
835+
EvaluatedToErr(e) => { return EvaluatedToErr(e); }
836836
EvaluatedToAmbig => { result = EvaluatedToAmbig; }
837837
EvaluatedToOk => { }
838838
}
@@ -1847,11 +1847,18 @@ impl<'o, 'tcx> Repr<'tcx> for ObligationStack<'o, 'tcx> {
18471847
}
18481848
}
18491849

1850-
impl EvaluationResult {
1850+
impl<'tcx> EvaluationResult<'tcx> {
18511851
fn may_apply(&self) -> bool {
18521852
match *self {
1853-
EvaluatedToOk | EvaluatedToAmbig => true,
1854-
EvaluatedToErr => false,
1853+
EvaluatedToOk |
1854+
EvaluatedToAmbig |
1855+
EvaluatedToErr(Overflow) |
1856+
EvaluatedToErr(OutputTypeParameterMismatch(..)) => {
1857+
true
1858+
}
1859+
EvaluatedToErr(Unimplemented) => {
1860+
false
1861+
}
18551862
}
18561863
}
18571864
}

src/librustc_typeck/check/vtable.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,15 @@ pub fn report_selection_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
366366
"overflow evaluating the trait `{}` for the type `{}`",
367367
trait_ref.user_string(fcx.tcx()),
368368
self_ty.user_string(fcx.tcx())).as_slice());
369+
370+
let current_limit = fcx.tcx().sess.recursion_limit.get();
371+
let suggested_limit = current_limit * 2;
372+
fcx.tcx().sess.span_note(
373+
obligation.cause.span,
374+
format!(
375+
"consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
376+
suggested_limit)[]);
377+
369378
note_obligation_cause(fcx, obligation);
370379
}
371380
Unimplemented => {

src/test/compile-fail/recursion_limit.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ fn is_send<T:Send>() { }
4242

4343
fn main() {
4444
is_send::<A>();
45-
//~^ ERROR not implemented
46-
//~^^ ERROR not implemented
45+
//~^ ERROR overflow evaluating
46+
//~^^ NOTE consider adding a `#![recursion_limit="20"]` attribute to your crate
47+
//~^^^ NOTE must be implemented
48+
//~^^^^ ERROR overflow evaluating
49+
//~^^^^^ NOTE consider adding a `#![recursion_limit="20"]` attribute to your crate
50+
//~^^^^^^ NOTE must be implemented
4751
}

src/test/compile-fail/unboxed-closures-type-mismatch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ use std::ops::FnMut;
1414

1515
pub fn main() {
1616
let mut f = |&mut: x: int, y: int| -> int { x + y };
17-
let z = f.call_mut((1u, 2)); //~ ERROR not implemented
17+
let z = f.call_mut((1u, 2)); //~ ERROR type mismatch
1818
println!("{}", z);
1919
}

src/test/compile-fail/unboxed-closures-vtable-mismatch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ fn call_it<F:FnMut<(int,int),int>>(y: int, mut f: F) -> int {
1818

1919
pub fn main() {
2020
let f = |&mut: x: uint, y: int| -> int { (x as int) + y };
21-
let z = call_it(3, f); //~ ERROR not implemented
21+
let z = call_it(3, f); //~ ERROR type mismatch
2222
println!("{}", z);
2323
}
2424

0 commit comments

Comments
 (0)