1
Fork 0

Report fulfillment errors in new trait solver

This commit is contained in:
Michael Goulet 2023-01-11 03:54:46 +00:00
parent b22c152958
commit 104ec48c64

View file

@ -3,7 +3,10 @@ use std::mem;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_infer::{ use rustc_infer::{
infer::InferCtxt, infer::InferCtxt,
traits::{query::NoSolution, FulfillmentError, PredicateObligation, TraitEngine}, traits::{
query::NoSolution, FulfillmentError, FulfillmentErrorCode, PredicateObligation,
SelectionError, TraitEngine,
},
}; };
use rustc_middle::ty; use rustc_middle::ty;
@ -45,32 +48,43 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
return errors; return errors;
} }
if self.obligations.is_empty() { self.obligations
Vec::new() .drain(..)
} else { .map(|obligation| FulfillmentError {
unimplemented!("ambiguous obligations") obligation: obligation.clone(),
} code: FulfillmentErrorCode::CodeSelectionError(SelectionError::Unimplemented),
root_obligation: obligation,
})
.collect()
} }
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> { 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.. { for i in 0.. {
if !infcx.tcx.recursion_limit().value_within_limit(i) { if !infcx.tcx.recursion_limit().value_within_limit(i) {
unimplemented!("overflow") unimplemented!("overflow")
} }
let mut has_changed = false; 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 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, 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; has_changed |= changed;
match certainty { match certainty {
Certainty::Yes => {} Certainty::Yes => {}
Certainty::Maybe(_) => self.obligations.push(o), Certainty::Maybe(_) => self.obligations.push(obligation),
} }
} }