From 3c4e1f85cb7103751bf99e3d826051ab42700dcc Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 9 Feb 2023 18:14:13 +0000 Subject: [PATCH] Multiple candidates with same response is not ambiguous --- Cargo.lock | 1 + compiler/rustc_trait_selection/Cargo.toml | 1 + compiler/rustc_trait_selection/src/solve/assembly.rs | 8 +++++--- tests/ui/traits/new-solver/provisional-result-done.rs | 2 +- .../traits/new-solver/provisional-result-done.stderr | 11 ----------- 5 files changed, 8 insertions(+), 15 deletions(-) delete mode 100644 tests/ui/traits/new-solver/provisional-result-done.stderr diff --git a/Cargo.lock b/Cargo.lock index ad01ef5e41f16..1ddf8cadd7280 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 3f863038efb37..d3eba43b47e95 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 775974d8e9a60..126ec60b3d68a 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 254ab356ad89c..589d34dd7abb1 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 5bd0613d25911..0000000000000 --- a/tests/ui/traits/new-solver/provisional-result-done.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0283]: type annotations needed: cannot satisfy `Bar: Coinductive` - --> $DIR/provisional-result-done.rs:16:25 - | -LL | impl Coinductive for Bar - | ^^^^^^ - | - = note: cannot satisfy `Bar: Coinductive` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0283`.