diff options
| author | Michael Goulet <michael@errs.io> | 2023-01-24 23:57:26 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-01-26 03:14:26 +0000 |
| commit | 8434b43a7f9886a0b0e5f36b115d6c26dde4953d (patch) | |
| tree | a26268a5804e38fa261c6cc4d74a149bb3c8557e | |
| parent | 2a17174ee639f8e0a3cee307d5685d38beb474ba (diff) | |
| download | rust-8434b43a7f9886a0b0e5f36b115d6c26dde4953d.tar.gz rust-8434b43a7f9886a0b0e5f36b115d6c26dde4953d.zip | |
Report the right fulfillment errors
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/fulfill.rs | 67 |
1 files changed, 57 insertions, 10 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index d59fa71406c..278024b2276 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -1,13 +1,14 @@ use std::mem; -use super::{Certainty, InferCtxtEvalExt}; -use rustc_infer::{ - infer::InferCtxt, - traits::{ - query::NoSolution, FulfillmentError, FulfillmentErrorCode, PredicateObligation, - SelectionError, TraitEngine, - }, +use rustc_infer::infer::InferCtxt; +use rustc_infer::traits::{ + query::NoSolution, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, + PredicateObligation, SelectionError, TraitEngine, }; +use rustc_middle::ty; +use rustc_middle::ty::error::{ExpectedFound, TypeError}; + +use super::{Certainty, InferCtxtEvalExt}; /// A trait engine using the new trait solver. /// @@ -70,9 +71,55 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { Err(NoSolution) => { errors.push(FulfillmentError { obligation: obligation.clone(), - code: FulfillmentErrorCode::CodeSelectionError( - SelectionError::Unimplemented, - ), + code: match goal.predicate.kind().skip_binder() { + ty::PredicateKind::Clause(ty::Clause::Projection(_)) => { + FulfillmentErrorCode::CodeProjectionError( + // FIXME: This could be a `Sorts` if the term is a type + MismatchedProjectionTypes { err: TypeError::Mismatch }, + ) + } + ty::PredicateKind::Subtype(pred) => { + let (a, b) = infcx.replace_bound_vars_with_placeholders( + goal.predicate.kind().rebind((pred.a, pred.b)), + ); + let expected_found = ExpectedFound::new(true, a, b); + FulfillmentErrorCode::CodeSubtypeError( + expected_found, + TypeError::Sorts(expected_found), + ) + } + ty::PredicateKind::Coerce(pred) => { + let (a, b) = infcx.replace_bound_vars_with_placeholders( + goal.predicate.kind().rebind((pred.a, pred.b)), + ); + let expected_found = ExpectedFound::new(false, a, b); + FulfillmentErrorCode::CodeSubtypeError( + expected_found, + TypeError::Sorts(expected_found), + ) + } + ty::PredicateKind::ConstEquate(a, b) => { + let (a, b) = infcx.replace_bound_vars_with_placeholders( + goal.predicate.kind().rebind((a, b)), + ); + let expected_found = ExpectedFound::new(true, a, b); + FulfillmentErrorCode::CodeConstEquateError( + expected_found, + TypeError::ConstMismatch(expected_found), + ) + } + ty::PredicateKind::Clause(_) + | ty::PredicateKind::WellFormed(_) + | ty::PredicateKind::ObjectSafe(_) + | ty::PredicateKind::ClosureKind(_, _, _) + | ty::PredicateKind::ConstEvaluatable(_) + | ty::PredicateKind::TypeWellFormedFromEnv(_) + | ty::PredicateKind::Ambiguous => { + FulfillmentErrorCode::CodeSelectionError( + SelectionError::Unimplemented, + ) + } + }, root_obligation: obligation, }); continue; |
