@@ -11,7 +11,7 @@ use rustc_middle::ty;
11
11
use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
12
12
13
13
use super :: eval_ctxt:: GenerateProofTree ;
14
- use super :: { Certainty , InferCtxtEvalExt } ;
14
+ use super :: { Certainty , Goal , InferCtxtEvalExt } ;
15
15
16
16
/// A trait engine using the new trait solver.
17
17
///
@@ -43,6 +43,21 @@ impl<'tcx> FulfillmentCtxt<'tcx> {
43
43
) ;
44
44
FulfillmentCtxt { obligations : Vec :: new ( ) , usable_in_snapshot : infcx. num_open_snapshots ( ) }
45
45
}
46
+
47
+ fn track_evaluated_obligation (
48
+ & self ,
49
+ infcx : & InferCtxt < ' tcx > ,
50
+ obligation : & PredicateObligation < ' tcx > ,
51
+ result : & Result < ( bool , Certainty , Vec < Goal < ' tcx , ty:: Predicate < ' tcx > > > ) , NoSolution > ,
52
+ ) {
53
+ if let Some ( inspector) = infcx. obligation_inspector . get ( ) {
54
+ let result = match result {
55
+ Ok ( ( _, c, _) ) => Ok ( * c) ,
56
+ Err ( NoSolution ) => Err ( NoSolution ) ,
57
+ } ;
58
+ ( inspector) ( infcx, & obligation, result) ;
59
+ }
60
+ }
46
61
}
47
62
48
63
impl < ' tcx > TraitEngine < ' tcx > for FulfillmentCtxt < ' tcx > {
@@ -57,7 +72,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
57
72
}
58
73
59
74
fn collect_remaining_errors ( & mut self , infcx : & InferCtxt < ' tcx > ) -> Vec < FulfillmentError < ' tcx > > {
60
- self . obligations
75
+ let errors = self
76
+ . obligations
61
77
. drain ( ..)
62
78
. map ( |obligation| {
63
79
let code = infcx. probe ( |_| {
@@ -86,7 +102,9 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
86
102
root_obligation : obligation,
87
103
}
88
104
} )
89
- . collect ( )
105
+ . collect ( ) ;
106
+
107
+ errors
90
108
}
91
109
92
110
fn select_where_possible ( & mut self , infcx : & InferCtxt < ' tcx > ) -> Vec < FulfillmentError < ' tcx > > {
@@ -100,65 +118,66 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
100
118
let mut has_changed = false ;
101
119
for obligation in mem:: take ( & mut self . obligations ) {
102
120
let goal = obligation. clone ( ) . into ( ) ;
103
- let ( changed, certainty, nested_goals) =
104
- match infcx. evaluate_root_goal ( goal, GenerateProofTree :: IfEnabled ) . 0 {
105
- Ok ( result) => result,
106
- Err ( NoSolution ) => {
107
- errors. push ( FulfillmentError {
108
- obligation : obligation. clone ( ) ,
109
- code : match goal. predicate . kind ( ) . skip_binder ( ) {
110
- ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( _) ) => {
111
- FulfillmentErrorCode :: ProjectionError (
112
- // FIXME: This could be a `Sorts` if the term is a type
113
- MismatchedProjectionTypes { err : TypeError :: Mismatch } ,
114
- )
115
- }
116
- ty:: PredicateKind :: NormalizesTo ( ..) => {
117
- FulfillmentErrorCode :: ProjectionError (
118
- MismatchedProjectionTypes { err : TypeError :: Mismatch } ,
119
- )
120
- }
121
- ty:: PredicateKind :: AliasRelate ( _, _, _) => {
122
- FulfillmentErrorCode :: ProjectionError (
123
- MismatchedProjectionTypes { err : TypeError :: Mismatch } ,
124
- )
125
- }
126
- ty:: PredicateKind :: Subtype ( pred) => {
127
- let ( a, b) = infcx. instantiate_binder_with_placeholders (
128
- goal. predicate . kind ( ) . rebind ( ( pred. a , pred. b ) ) ,
129
- ) ;
130
- let expected_found = ExpectedFound :: new ( true , a, b) ;
131
- FulfillmentErrorCode :: SubtypeError (
132
- expected_found,
133
- TypeError :: Sorts ( expected_found) ,
134
- )
135
- }
136
- ty:: PredicateKind :: Coerce ( pred) => {
137
- let ( a, b) = infcx. instantiate_binder_with_placeholders (
138
- goal. predicate . kind ( ) . rebind ( ( pred. a , pred. b ) ) ,
139
- ) ;
140
- let expected_found = ExpectedFound :: new ( false , a, b) ;
141
- FulfillmentErrorCode :: SubtypeError (
142
- expected_found,
143
- TypeError :: Sorts ( expected_found) ,
144
- )
145
- }
146
- ty:: PredicateKind :: Clause ( _)
147
- | ty:: PredicateKind :: ObjectSafe ( _)
148
- | ty:: PredicateKind :: Ambiguous => {
149
- FulfillmentErrorCode :: SelectionError (
150
- SelectionError :: Unimplemented ,
151
- )
152
- }
153
- ty:: PredicateKind :: ConstEquate ( ..) => {
154
- bug ! ( "unexpected goal: {goal:?}" )
155
- }
156
- } ,
157
- root_obligation : obligation,
158
- } ) ;
159
- continue ;
160
- }
161
- } ;
121
+ let result = infcx. evaluate_root_goal ( goal, GenerateProofTree :: IfEnabled ) . 0 ;
122
+ self . track_evaluated_obligation ( infcx, & obligation, & result) ;
123
+ let ( changed, certainty, nested_goals) = match result {
124
+ Ok ( result) => result,
125
+ Err ( NoSolution ) => {
126
+ errors. push ( FulfillmentError {
127
+ obligation : obligation. clone ( ) ,
128
+ code : match goal. predicate . kind ( ) . skip_binder ( ) {
129
+ ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( _) ) => {
130
+ FulfillmentErrorCode :: ProjectionError (
131
+ // FIXME: This could be a `Sorts` if the term is a type
132
+ MismatchedProjectionTypes { err : TypeError :: Mismatch } ,
133
+ )
134
+ }
135
+ ty:: PredicateKind :: NormalizesTo ( ..) => {
136
+ FulfillmentErrorCode :: ProjectionError (
137
+ MismatchedProjectionTypes { err : TypeError :: Mismatch } ,
138
+ )
139
+ }
140
+ ty:: PredicateKind :: AliasRelate ( _, _, _) => {
141
+ FulfillmentErrorCode :: ProjectionError (
142
+ MismatchedProjectionTypes { err : TypeError :: Mismatch } ,
143
+ )
144
+ }
145
+ ty:: PredicateKind :: Subtype ( pred) => {
146
+ let ( a, b) = infcx. instantiate_binder_with_placeholders (
147
+ goal. predicate . kind ( ) . rebind ( ( pred. a , pred. b ) ) ,
148
+ ) ;
149
+ let expected_found = ExpectedFound :: new ( true , a, b) ;
150
+ FulfillmentErrorCode :: SubtypeError (
151
+ expected_found,
152
+ TypeError :: Sorts ( expected_found) ,
153
+ )
154
+ }
155
+ ty:: PredicateKind :: Coerce ( pred) => {
156
+ let ( a, b) = infcx. instantiate_binder_with_placeholders (
157
+ goal. predicate . kind ( ) . rebind ( ( pred. a , pred. b ) ) ,
158
+ ) ;
159
+ let expected_found = ExpectedFound :: new ( false , a, b) ;
160
+ FulfillmentErrorCode :: SubtypeError (
161
+ expected_found,
162
+ TypeError :: Sorts ( expected_found) ,
163
+ )
164
+ }
165
+ ty:: PredicateKind :: Clause ( _)
166
+ | ty:: PredicateKind :: ObjectSafe ( _)
167
+ | ty:: PredicateKind :: Ambiguous => {
168
+ FulfillmentErrorCode :: SelectionError (
169
+ SelectionError :: Unimplemented ,
170
+ )
171
+ }
172
+ ty:: PredicateKind :: ConstEquate ( ..) => {
173
+ bug ! ( "unexpected goal: {goal:?}" )
174
+ }
175
+ } ,
176
+ root_obligation : obligation,
177
+ } ) ;
178
+ continue ;
179
+ }
180
+ } ;
162
181
// Push any nested goals that we get from unifying our canonical response
163
182
// with our obligation onto the fulfillment context.
164
183
self . obligations . extend ( nested_goals. into_iter ( ) . map ( |goal| {
0 commit comments