about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJared Roesch <roeschinc@gmail.com>2015-07-21 14:52:21 -0700
committerJared Roesch <jroesch@MacBook.home>2015-07-25 19:57:59 -0700
commit9da04b2bd1fdcd147f6d0ebcdbb5108f63bf7576 (patch)
tree57efb2020cd1fe30a33aeaed4642b272db0bbda3 /src
parentd732f7323b07cd62bf2a9f7e4785407d6f82ee63 (diff)
downloadrust-9da04b2bd1fdcd147f6d0ebcdbb5108f63bf7576.tar.gz
rust-9da04b2bd1fdcd147f6d0ebcdbb5108f63bf7576.zip
Make default error reporting deterministic
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/check/mod.rs19
-rw-r--r--src/librustc_typeck/collect.rs1
-rw-r--r--src/test/compile-fail/default_ty_param_conflict.rs7
-rw-r--r--src/test/compile-fail/default_ty_param_conflict_cross_crate.rs18
4 files changed, 35 insertions, 10 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index fd4cf6f28df..95e916f1a0d 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1800,6 +1800,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // We wrap this in a transaction for error reporting, if we detect a conflict
             // we will rollback the inference context to its prior state so we can probe
             // for conflicts and correctly report them.
+
+
             let _ = self.infcx().commit_if_ok(|_: &infer::CombinedSnapshot| {
                 for ty in &unbound_tyvars {
                     if self.infcx().type_var_diverges(ty) {
@@ -1849,10 +1851,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 def_id: local_def(0) // what do I put here?
                             });
 
+                    // This is to ensure that we elimnate any non-determinism from the error
+                    // reporting by fixing an order, it doesn't matter what order we choose
+                    // just that it is consistent.
+                    let (first_default, second_default) =
+                        if default.def_id < conflicting_default.def_id {
+                            (default, conflicting_default)
+                        } else {
+                            (conflicting_default, default)
+                        };
+
+
                     self.infcx().report_conflicting_default_types(
-                        conflicting_default.origin_span,
-                        conflicting_default,
-                        default)
+                        first_default.origin_span,
+                        first_default,
+                        second_default)
                 }
             }
         }
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index d31a29ecc0e..236a1e690e8 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1930,7 +1930,6 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
         index: index,
         name: param.ident.name,
         def_id: local_def(param.id),
-        // what do I return? should this be an option as well
         default_def_id: local_def(parent),
         default: default,
         object_lifetime_default: object_lifetime_default,
diff --git a/src/test/compile-fail/default_ty_param_conflict.rs b/src/test/compile-fail/default_ty_param_conflict.rs
index 900945da113..42de545f9d0 100644
--- a/src/test/compile-fail/default_ty_param_conflict.rs
+++ b/src/test/compile-fail/default_ty_param_conflict.rs
@@ -12,12 +12,19 @@ use std::fmt::Debug;
 
 // Example from the RFC
 fn foo<F:Default=usize>() -> F { F::default() }
+//~^ NOTE: a default was defined here...
+
 fn bar<B:Debug=isize>(b: B) { println!("{:?}", b); }
+//~^ NOTE: a second default was defined here...
 
 fn main() {
     // Here, F is instantiated with $0=uint
     let x = foo();
+    //~^ ERROR: mismatched types
+    //~| NOTE: conflicting type parameter defaults `usize` and `isize`
+    //~| NOTE: ...that was applied to an unconstrained type variable here
 
     // Here, B is instantiated with $1=uint, and constraint $0 <: $1 is added.
     bar(x);
+    //~^ NOTE: ...that also applies to the same type variable here
 }
diff --git a/src/test/compile-fail/default_ty_param_conflict_cross_crate.rs b/src/test/compile-fail/default_ty_param_conflict_cross_crate.rs
index bc79d3713e5..804a864e074 100644
--- a/src/test/compile-fail/default_ty_param_conflict_cross_crate.rs
+++ b/src/test/compile-fail/default_ty_param_conflict_cross_crate.rs
@@ -7,14 +7,20 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
+//
+//aux-build:default_ty_param_cross_crate_crate.rs
+extern crate default_param_test;
 
-use std::fmt::Debug;
-use std::collections::HashMap;
+use default_param_test::{Foo, bleh};
 
-fn foo<R=()>(x: HashMap<i32, i32, R>) ->  HashMap<i32, i32, R> { x }
-fn bar<R=char>(x: HashMap<i32, i32, R>) {}
+fn meh<X, B=bool>(x: Foo<X, B>) {}
+//~^ NOTE: a default was defined here...
 
 fn main() {
-    let x: HashMap<i32, i32, _> = foo(panic!());
-    bar(x);
+    let foo = bleh();
+    //~^ NOTE: ...that also applies to the same type variable here
+
+    meh(foo);
+    //~^ ERROR: mismatched types:
+    //~| NOTE: conflicting type parameter defaults `bool` and `char`
 }