|
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