diff options
| author | Michael Goulet <michael@errs.io> | 2023-01-11 03:54:46 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-01-11 18:05:50 +0000 |
| commit | 104ec48c649987685e385b7f64a19921403ece63 (patch) | |
| tree | 075080a32f5107c8a536f7cdc42dfedc5b9c56a6 /compiler | |
| parent | b22c152958eade17a71d899b29a2d39bcc77aa48 (diff) | |
| download | rust-104ec48c649987685e385b7f64a19921403ece63.tar.gz rust-104ec48c649987685e385b7f64a19921403ece63.zip | |
Report fulfillment errors in new trait solver
Diffstat (limited to 'compiler')
| -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), } } |
