about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-01-11 21:08:09 +0100
committerGitHub <noreply@github.com>2023-01-11 21:08:09 +0100
commit865d83e87ab489f2915802e70a5c4a3f2424ff67 (patch)
tree8a9881668006bda5f9df7045fe0873ef06fda32d
parent90f9c681d44b91ed41425284dd748604268cdc4e (diff)
parent104ec48c649987685e385b7f64a19921403ece63 (diff)
downloadrust-865d83e87ab489f2915802e70a5c4a3f2424ff67.tar.gz
rust-865d83e87ab489f2915802e70a5c4a3f2424ff67.zip
Rollup merge of #106705 - compiler-errors:new-solver-err-properly, r=lcnr
Report fulfillment errors in new trait solver

Causes fewer ICEs when testing the new solver :smile:
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs36
1 files changed, 25 insertions, 11 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 80115d78d88..c014d682a9a 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -3,7 +3,10 @@ use std::mem;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_infer::{
     infer::InferCtxt,
-    traits::{query::NoSolution, FulfillmentError, PredicateObligation, TraitEngine},
+    traits::{
+        query::NoSolution, FulfillmentError, FulfillmentErrorCode, PredicateObligation,
+        SelectionError, TraitEngine,
+    },
 };
 use rustc_middle::ty;
 
@@ -45,32 +48,43 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
             return errors;
         }
 
-        if self.obligations.is_empty() {
-            Vec::new()
-        } else {
-            unimplemented!("ambiguous obligations")
-        }
+        self.obligations
+            .drain(..)
+            .map(|obligation| FulfillmentError {
+                obligation: obligation.clone(),
+                code: FulfillmentErrorCode::CodeSelectionError(SelectionError::Unimplemented),
+                root_obligation: obligation,
+            })
+            .collect()
     }
 
     fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
-        let errors = Vec::new();
+        let mut errors = Vec::new();
         for i in 0.. {
             if !infcx.tcx.recursion_limit().value_within_limit(i) {
                 unimplemented!("overflow")
             }
 
             let mut has_changed = false;
-            for o in mem::take(&mut self.obligations) {
+            for obligation in mem::take(&mut self.obligations) {
                 let mut cx = EvalCtxt::new(infcx.tcx);
-                let (changed, certainty) = match cx.evaluate_goal(infcx, o.clone().into()) {
+                let (changed, certainty) = match cx.evaluate_goal(infcx, obligation.clone().into())
+                {
                     Ok(result) => result,
-                    Err(NoSolution) => unimplemented!("error"),
+                    Err(NoSolution) => {
+                        errors.push(FulfillmentError {
+                            obligation: obligation.clone(),
+                            code: FulfillmentErrorCode::CodeAmbiguity,
+                            root_obligation: obligation,
+                        });
+                        continue;
+                    }
                 };
 
                 has_changed |= changed;
                 match certainty {
                     Certainty::Yes => {}
-                    Certainty::Maybe(_) => self.obligations.push(o),
+                    Certainty::Maybe(_) => self.obligations.push(obligation),
                 }
             }