Skip to content

Commit 8434b43

Browse files
Report the right fulfillment errors
1 parent 2a17174 commit 8434b43

File tree

1 file changed

+57
-10
lines changed
  • compiler/rustc_trait_selection/src/solve

1 file changed

+57
-10
lines changed

compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
use std::mem;
22

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,
107
};
8+
use rustc_middle::ty;
9+
use rustc_middle::ty::error::{ExpectedFound, TypeError};
10+
11+
use super::{Certainty, InferCtxtEvalExt};
1112

1213
/// A trait engine using the new trait solver.
1314
///
@@ -70,9 +71,55 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
7071
Err(NoSolution) => {
7172
errors.push(FulfillmentError {
7273
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+
},
76123
root_obligation: obligation,
77124
});
78125
continue;

0 commit comments

Comments
 (0)