From 104ec48c649987685e385b7f64a19921403ece63 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 11 Jan 2023 03:54:46 +0000 Subject: [PATCH] Report fulfillment errors in new trait solver --- .../src/solve/fulfill.rs | 36 +++++++++++++------ 1 file 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 80115d78d88d1..c014d682a9aaa 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> { - 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), } }