summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_trait_selection/Cargo.toml1
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly.rs8
-rw-r--r--tests/ui/traits/new-solver/provisional-result-done.rs2
-rw-r--r--tests/ui/traits/new-solver/provisional-result-done.stderr11
5 files changed, 8 insertions, 15 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ad01ef5e41f..1ddf8cadd72 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4773,6 +4773,7 @@ checksum = "8ba09476327c4b70ccefb6180f046ef588c26a24cf5d269a9feba316eb4f029f"
 name = "rustc_trait_selection"
 version = "0.0.0"
 dependencies = [
+ "itertools",
  "rustc_ast",
  "rustc_attr",
  "rustc_data_structures",
diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml
index 3f863038efb..d3eba43b47e 100644
--- a/compiler/rustc_trait_selection/Cargo.toml
+++ b/compiler/rustc_trait_selection/Cargo.toml
@@ -24,3 +24,4 @@ rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
+itertools = "0.10.1"
diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs
index 775974d8e9a..126ec60b3d6 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly.rs
@@ -4,6 +4,7 @@ use super::infcx_ext::InferCtxtExt;
 #[cfg(doc)]
 use super::trait_goals::structural_traits::*;
 use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
+use itertools::Itertools;
 use rustc_hir::def_id::DefId;
 use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::util::elaborate_predicates;
@@ -489,9 +490,9 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 i += 1;
             }
 
-            // If there are *STILL* multiple candidates, give up
-            // and report ambiguity.
-            if candidates.len() > 1 {
+            // If there are *STILL* multiple candidates that have *different* response
+            // results, give up and report ambiguity.
+            if candidates.len() > 1 && !candidates.iter().map(|cand| cand.result).all_equal() {
                 let certainty = if candidates.iter().all(|x| {
                     matches!(x.result.value.certainty, Certainty::Maybe(MaybeCause::Overflow))
                 }) {
@@ -503,6 +504,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             }
         }
 
+        // FIXME: What if there are >1 candidates left with the same response, and one is a reservation impl?
         Ok(self.discard_reservation_impl(candidates.pop().unwrap()).result)
     }
 
diff --git a/tests/ui/traits/new-solver/provisional-result-done.rs b/tests/ui/traits/new-solver/provisional-result-done.rs
index 254ab356ad8..589d34dd7ab 100644
--- a/tests/ui/traits/new-solver/provisional-result-done.rs
+++ b/tests/ui/traits/new-solver/provisional-result-done.rs
@@ -1,5 +1,5 @@
-// known-bug: unknown
 // compile-flags: -Ztrait-solver=next
+// check-pass
 
 // This tests checks that we update results in the provisional cache when
 // we pop a goal from the stack.
diff --git a/tests/ui/traits/new-solver/provisional-result-done.stderr b/tests/ui/traits/new-solver/provisional-result-done.stderr
deleted file mode 100644
index 5bd0613d259..00000000000
--- a/tests/ui/traits/new-solver/provisional-result-done.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0283]: type annotations needed: cannot satisfy `Bar<T>: Coinductive`
-  --> $DIR/provisional-result-done.rs:16:25
-   |
-LL | impl<T> Coinductive for Bar<T>
-   |                         ^^^^^^
-   |
-   = note: cannot satisfy `Bar<T>: Coinductive`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0283`.