| 
1 | 1 | use std::mem;  | 
2 | 2 | 
 
  | 
3 |  | -use super::{Certainty, InferCtxtEvalExt};  | 
4 |  | -use rustc_infer::{  | 
5 |  | -    infer::InferCtxt,  | 
6 |  | -    traits::{  | 
7 |  | -        query::NoSolution, FulfillmentError, FulfillmentErrorCode, PredicateObligation,  | 
8 |  | -        SelectionError, TraitEngine,  | 
9 |  | -    },  | 
 | 3 | +use rustc_infer::infer::InferCtxt;  | 
 | 4 | +use rustc_infer::traits::{  | 
 | 5 | +    query::NoSolution, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes,  | 
 | 6 | +    PredicateObligation, SelectionError, TraitEngine,  | 
10 | 7 | };  | 
 | 8 | +use rustc_middle::ty;  | 
 | 9 | +use rustc_middle::ty::error::{ExpectedFound, TypeError};  | 
 | 10 | + | 
 | 11 | +use super::{Certainty, InferCtxtEvalExt};  | 
11 | 12 | 
 
  | 
12 | 13 | /// A trait engine using the new trait solver.  | 
13 | 14 | ///  | 
@@ -70,9 +71,55 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {  | 
70 | 71 |                     Err(NoSolution) => {  | 
71 | 72 |                         errors.push(FulfillmentError {  | 
72 | 73 |                             obligation: obligation.clone(),  | 
73 |  | -                            code: FulfillmentErrorCode::CodeSelectionError(  | 
74 |  | -                                SelectionError::Unimplemented,  | 
75 |  | -                            ),  | 
 | 74 | +                            code: match goal.predicate.kind().skip_binder() {  | 
 | 75 | +                                ty::PredicateKind::Clause(ty::Clause::Projection(_)) => {  | 
 | 76 | +                                    FulfillmentErrorCode::CodeProjectionError(  | 
 | 77 | +                                        // FIXME: This could be a `Sorts` if the term is a type  | 
 | 78 | +                                        MismatchedProjectionTypes { err: TypeError::Mismatch },  | 
 | 79 | +                                    )  | 
 | 80 | +                                }  | 
 | 81 | +                                ty::PredicateKind::Subtype(pred) => {  | 
 | 82 | +                                    let (a, b) = infcx.replace_bound_vars_with_placeholders(  | 
 | 83 | +                                        goal.predicate.kind().rebind((pred.a, pred.b)),  | 
 | 84 | +                                    );  | 
 | 85 | +                                    let expected_found = ExpectedFound::new(true, a, b);  | 
 | 86 | +                                    FulfillmentErrorCode::CodeSubtypeError(  | 
 | 87 | +                                        expected_found,  | 
 | 88 | +                                        TypeError::Sorts(expected_found),  | 
 | 89 | +                                    )  | 
 | 90 | +                                }  | 
 | 91 | +                                ty::PredicateKind::Coerce(pred) => {  | 
 | 92 | +                                    let (a, b) = infcx.replace_bound_vars_with_placeholders(  | 
 | 93 | +                                        goal.predicate.kind().rebind((pred.a, pred.b)),  | 
 | 94 | +                                    );  | 
 | 95 | +                                    let expected_found = ExpectedFound::new(false, a, b);  | 
 | 96 | +                                    FulfillmentErrorCode::CodeSubtypeError(  | 
 | 97 | +                                        expected_found,  | 
 | 98 | +                                        TypeError::Sorts(expected_found),  | 
 | 99 | +                                    )  | 
 | 100 | +                                }  | 
 | 101 | +                                ty::PredicateKind::ConstEquate(a, b) => {  | 
 | 102 | +                                    let (a, b) = infcx.replace_bound_vars_with_placeholders(  | 
 | 103 | +                                        goal.predicate.kind().rebind((a, b)),  | 
 | 104 | +                                    );  | 
 | 105 | +                                    let expected_found = ExpectedFound::new(true, a, b);  | 
 | 106 | +                                    FulfillmentErrorCode::CodeConstEquateError(  | 
 | 107 | +                                        expected_found,  | 
 | 108 | +                                        TypeError::ConstMismatch(expected_found),  | 
 | 109 | +                                    )  | 
 | 110 | +                                }  | 
 | 111 | +                                ty::PredicateKind::Clause(_)  | 
 | 112 | +                                | ty::PredicateKind::WellFormed(_)  | 
 | 113 | +                                | ty::PredicateKind::ObjectSafe(_)  | 
 | 114 | +                                | ty::PredicateKind::ClosureKind(_, _, _)  | 
 | 115 | +                                | ty::PredicateKind::ConstEvaluatable(_)  | 
 | 116 | +                                | ty::PredicateKind::TypeWellFormedFromEnv(_)  | 
 | 117 | +                                | ty::PredicateKind::Ambiguous => {  | 
 | 118 | +                                    FulfillmentErrorCode::CodeSelectionError(  | 
 | 119 | +                                        SelectionError::Unimplemented,  | 
 | 120 | +                                    )  | 
 | 121 | +                                }  | 
 | 122 | +                            },  | 
76 | 123 |                             root_obligation: obligation,  | 
77 | 124 |                         });  | 
78 | 125 |                         continue;  | 
 | 
0 commit comments