about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-01-24 23:57:26 +0000
committerMichael Goulet <michael@errs.io>2023-01-26 03:14:26 +0000
commit8434b43a7f9886a0b0e5f36b115d6c26dde4953d (patch)
treea26268a5804e38fa261c6cc4d74a149bb3c8557e
parent2a17174ee639f8e0a3cee307d5685d38beb474ba (diff)
downloadrust-8434b43a7f9886a0b0e5f36b115d6c26dde4953d.tar.gz
rust-8434b43a7f9886a0b0e5f36b115d6c26dde4953d.zip
Report the right fulfillment errors
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs67
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;