about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2019-01-21 16:55:32 +0100
committerSimon Sapin <simon.sapin@exyr.org>2019-01-21 18:41:53 +0100
commite195ce654a570606a85ead6cefb36042a206205a (patch)
tree80a517b4e0e47f41708b7162d8dae32cc4159aa2
parent9be4c76910e0df7decb33c5d400260f1d8c217a1 (diff)
downloadrust-e195ce654a570606a85ead6cefb36042a206205a.tar.gz
rust-e195ce654a570606a85ead6cefb36042a206205a.zip
Fix some non-determinism in help messages for E0277 errors.
The diagnostic for this error prints `the following implementations
were found` followed by the first N relevant impls, sorted.

This commit makes the sort happen before slicing,
so that the set of impls being printed is deterministic
when the input is not.
-rw-r--r--src/librustc/traits/error_reporting.rs10
-rw-r--r--src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr2
-rw-r--r--src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr4
-rw-r--r--src/test/ui/try-block/try-block-bad-type.stderr2
4 files changed, 11 insertions, 7 deletions
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 367a7eacdfc..1c92e2da588 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -471,7 +471,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     }
 
     fn report_similar_impl_candidates(&self,
-                                      mut impl_candidates: Vec<ty::TraitRef<'tcx>>,
+                                      impl_candidates: Vec<ty::TraitRef<'tcx>>,
                                       err: &mut DiagnosticBuilder<'_>)
     {
         if impl_candidates.is_empty() {
@@ -497,14 +497,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         });
 
         // Sort impl candidates so that ordering is consistent for UI tests.
-        let normalized_impl_candidates = &mut impl_candidates[0..end]
+        let mut normalized_impl_candidates = impl_candidates
             .iter()
             .map(normalize)
             .collect::<Vec<String>>();
+
+        // Sort before taking the `..end` range,
+        // because the ordering of `impl_candidates` may not be deterministic:
+        // https://github.com/rust-lang/rust/pull/57475#issuecomment-455519507
         normalized_impl_candidates.sort();
 
         err.help(&format!("the following implementations were found:{}{}",
-                          normalized_impl_candidates.join(""),
+                          normalized_impl_candidates[..end].join(""),
                           if len > 5 {
                               format!("\nand {} others", len - 4)
                           } else {
diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
index 140f98b4038..d6d5ce4d1a7 100644
--- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
+++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
@@ -8,7 +8,7 @@ LL |     f1.foo(1usize);
              <Bar as Foo<i16>>
              <Bar as Foo<i32>>
              <Bar as Foo<i8>>
-             <Bar as Foo<u8>>
+             <Bar as Foo<u16>>
            and 2 others
 
 error: aborting due to previous error
diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
index 23466980f92..3411958be62 100644
--- a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
+++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
@@ -40,10 +40,10 @@ LL |     Foo::<i32>::bar(&true); //~ ERROR is not satisfied
    |     ^^^^^^^^^^^^^^^ the trait `Foo<i32>` is not implemented for `bool`
    |
    = help: the following implementations were found:
+             <bool as Foo<bool>>
+             <bool as Foo<i8>>
              <bool as Foo<u16>>
              <bool as Foo<u32>>
-             <bool as Foo<u64>>
-             <bool as Foo<u8>>
            and 2 others
 note: required by `Foo::bar`
   --> $DIR/issue-39802-show-5-trait-impls.rs:2:5
diff --git a/src/test/ui/try-block/try-block-bad-type.stderr b/src/test/ui/try-block/try-block-bad-type.stderr
index c2f9e9b52be..df8e646280c 100644
--- a/src/test/ui/try-block/try-block-bad-type.stderr
+++ b/src/test/ui/try-block/try-block-bad-type.stderr
@@ -5,10 +5,10 @@ LL |         Err("")?; //~ ERROR the trait bound `i32: std::convert::From<&str>`
    |         ^^^^^^^^ the trait `std::convert::From<&str>` is not implemented for `i32`
    |
    = help: the following implementations were found:
+             <i32 as std::convert::From<bool>>
              <i32 as std::convert::From<core::num::NonZeroI32>>
              <i32 as std::convert::From<i16>>
              <i32 as std::convert::From<i8>>
-             <i32 as std::convert::From<u8>>
            and 2 others
    = note: required by `std::convert::From::from`