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 😄
This commit is contained in:
Matthias Krüger 2023-01-11 21:08:09 +01:00 committed by GitHub
commit 865d83e87a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -3,7 +3,10 @@
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 @@ fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentErr
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),
}
}