about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-02-08 03:03:15 +0000
committerMichael Goulet <michael@errs.io>2023-02-09 17:22:37 +0000
commit8987e68247ed6df47624f9eeb35430fc92d54f15 (patch)
treef03b99bd5dc1cf4d7799d2c651c1ec6feed7f1ea
parent8c67ecd1245daef98a2667bd1672fe47ff16927a (diff)
downloadrust-8987e68247ed6df47624f9eeb35430fc92d54f15.tar.gz
rust-8987e68247ed6df47624f9eeb35430fc92d54f15.zip
Implement a dummy drop-in-favor-of for the new solver
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals.rs23
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs29
-rw-r--r--tests/ui/traits/new-solver/provisional-result-done.rs4
-rw-r--r--tests/ui/traits/new-solver/provisional-result-done.stderr15
-rw-r--r--tests/ui/traits/new-solver/temporary-ambiguity.rs22
5 files changed, 65 insertions, 28 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index e3ec71d1b4f..bdf1550fab9 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -3,7 +3,7 @@ use crate::traits::{specialization_graph, translate_substs};
 use super::assembly::{self, Candidate, CandidateSource};
 use super::infcx_ext::InferCtxtExt;
 use super::trait_goals::structural_traits;
-use super::{Certainty, EvalCtxt, Goal, QueryResult};
+use super::{Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
@@ -182,11 +182,17 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 // If there are *STILL* multiple candidates, give up
                 // and report ambiguity.
                 i += 1;
-                if i > 1 {
-                    debug!("multiple matches, ambig");
-                    // FIXME: return overflow if all candidates overflow, otherwise return ambiguity.
-                    unimplemented!();
-                }
+            }
+
+            if candidates.len() > 1 {
+                let certainty = if candidates.iter().all(|x| {
+                    matches!(x.result.value.certainty, Certainty::Maybe(MaybeCause::Overflow))
+                }) {
+                    Certainty::Maybe(MaybeCause::Overflow)
+                } else {
+                    Certainty::AMBIGUOUS
+                };
+                return self.make_canonical_response(certainty);
             }
         }
 
@@ -203,7 +209,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             (CandidateSource::Impl(_), _)
             | (CandidateSource::ParamEnv(_), _)
             | (CandidateSource::BuiltinImpl, _)
-            | (CandidateSource::AliasBound, _) => unimplemented!(),
+            | (CandidateSource::AliasBound, _) => false,
         }
     }
 }
@@ -452,7 +458,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
                         [ty::GenericArg::from(goal.predicate.self_ty())],
                     ));
 
-                    let is_sized_certainty = ecx.evaluate_goal(goal.with(tcx, sized_predicate))?.1;
+                    let (_, is_sized_certainty) =
+                        ecx.evaluate_goal(goal.with(tcx, sized_predicate))?;
                     return ecx.eq_term_and_make_canonical_response(
                         goal,
                         is_sized_certainty,
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index 06a72e95d49..6e1e993b2de 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -4,7 +4,7 @@ use std::iter;
 
 use super::assembly::{self, Candidate, CandidateSource};
 use super::infcx_ext::InferCtxtExt;
-use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, QueryResult};
+use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::InferCtxt;
 use rustc_infer::traits::query::NoSolution;
@@ -511,11 +511,17 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 // If there are *STILL* multiple candidates, give up
                 // and report ambiguity.
                 i += 1;
-                if i > 1 {
-                    debug!("multiple matches, ambig");
-                    // FIXME: return overflow if all candidates overflow, otherwise return ambiguity.
-                    unimplemented!();
-                }
+            }
+
+            if candidates.len() > 1 {
+                let certainty = if candidates.iter().all(|x| {
+                    matches!(x.result.value.certainty, Certainty::Maybe(MaybeCause::Overflow))
+                }) {
+                    Certainty::Maybe(MaybeCause::Overflow)
+                } else {
+                    Certainty::AMBIGUOUS
+                };
+                return self.make_canonical_response(certainty);
             }
         }
 
@@ -532,17 +538,18 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             (CandidateSource::Impl(_), _)
             | (CandidateSource::ParamEnv(_), _)
             | (CandidateSource::AliasBound, _)
-            | (CandidateSource::BuiltinImpl, _) => unimplemented!(),
+            | (CandidateSource::BuiltinImpl, _) => false,
         }
     }
 
-    fn discard_reservation_impl(&self, candidate: Candidate<'tcx>) -> Candidate<'tcx> {
+    fn discard_reservation_impl(&self, mut candidate: Candidate<'tcx>) -> Candidate<'tcx> {
         if let CandidateSource::Impl(def_id) = candidate.source {
             if let ty::ImplPolarity::Reservation = self.tcx().impl_polarity(def_id) {
                 debug!("Selected reservation impl");
-                // FIXME: reduce candidate to ambiguous
-                // FIXME: replace `var_values` with identity, yeet external constraints.
-                unimplemented!()
+                // We assemble all candidates inside of a probe so by
+                // making a new canonical response here our result will
+                // have no constraints.
+                candidate.result = self.make_canonical_response(Certainty::AMBIGUOUS).unwrap();
             }
         }
 
diff --git a/tests/ui/traits/new-solver/provisional-result-done.rs b/tests/ui/traits/new-solver/provisional-result-done.rs
index a3d97927bad..254ab356ad8 100644
--- a/tests/ui/traits/new-solver/provisional-result-done.rs
+++ b/tests/ui/traits/new-solver/provisional-result-done.rs
@@ -1,9 +1,5 @@
 // known-bug: unknown
 // compile-flags: -Ztrait-solver=next
-// failure-status: 101
-// normalize-stderr-test "note: .*\n\n" -> ""
-// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
-// rustc-env:RUST_BACKTRACE=0
 
 // 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
index ffc92b81f08..5bd0613d259 100644
--- a/tests/ui/traits/new-solver/provisional-result-done.stderr
+++ b/tests/ui/traits/new-solver/provisional-result-done.stderr
@@ -1,6 +1,11 @@
-error: the compiler unexpectedly panicked. this is a bug.
+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`
 
-query stack during panic:
-#0 [check_well_formed] checking that `<impl at $DIR/provisional-result-done.rs:20:1: 20:31>` is well-formed
-#1 [check_mod_type_wf] checking that types are well-formed in top-level module
-end of query stack
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/traits/new-solver/temporary-ambiguity.rs b/tests/ui/traits/new-solver/temporary-ambiguity.rs
new file mode 100644
index 00000000000..18ee0545700
--- /dev/null
+++ b/tests/ui/traits/new-solver/temporary-ambiguity.rs
@@ -0,0 +1,22 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+// Checks that we don't explode when we assemble >1 candidate for a goal.
+
+struct Wrapper<T>(T);
+
+trait Foo {}
+
+impl Foo for Wrapper<i32> {}
+
+impl Foo for Wrapper<()> {}
+
+fn needs_foo(_: impl Foo) {}
+
+fn main() {
+    let mut x = Default::default();
+    let w = Wrapper(x);
+    needs_foo(w);
+    x = 1;
+    drop(x);
+}