diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-01-11 21:08:09 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-01-11 21:08:09 +0100 |
| commit | 865d83e87ab489f2915802e70a5c4a3f2424ff67 (patch) | |
| tree | 8a9881668006bda5f9df7045fe0873ef06fda32d | |
| parent | 90f9c681d44b91ed41425284dd748604268cdc4e (diff) | |
| parent | 104ec48c649987685e385b7f64a19921403ece63 (diff) | |
| download | rust-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.rs | 36 |
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), } } |
