|
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