@@ -73,36 +73,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
73
73
fn collect_remaining_errors ( & mut self , infcx : & InferCtxt < ' tcx > ) -> Vec < FulfillmentError < ' tcx > > {
74
74
self . obligations
75
75
. drain ( ..)
76
- . map ( |obligation| {
77
- let code = infcx. probe ( |_| {
78
- match infcx
79
- . evaluate_root_goal ( obligation. clone ( ) . into ( ) , GenerateProofTree :: IfEnabled )
80
- . 0
81
- {
82
- Ok ( ( _, Certainty :: Maybe ( MaybeCause :: Ambiguity ) ) ) => {
83
- FulfillmentErrorCode :: Ambiguity { overflow : None }
84
- }
85
- Ok ( (
86
- _,
87
- Certainty :: Maybe ( MaybeCause :: Overflow { suggest_increasing_limit } ) ,
88
- ) ) => FulfillmentErrorCode :: Ambiguity {
89
- overflow : Some ( suggest_increasing_limit) ,
90
- } ,
91
- Ok ( ( _, Certainty :: Yes ) ) => {
92
- bug ! ( "did not expect successful goal when collecting ambiguity errors" )
93
- }
94
- Err ( _) => {
95
- bug ! ( "did not expect selection error when collecting ambiguity errors" )
96
- }
97
- }
98
- } ) ;
99
-
100
- FulfillmentError {
101
- obligation : obligation. clone ( ) ,
102
- code,
103
- root_obligation : obligation,
104
- }
105
- } )
76
+ . map ( |obligation| fulfillment_error_for_stalled ( infcx, obligation) )
106
77
. collect ( )
107
78
}
108
79
@@ -125,58 +96,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
125
96
let ( changed, certainty) = match result {
126
97
Ok ( result) => result,
127
98
Err ( NoSolution ) => {
128
- errors. push ( FulfillmentError {
129
- obligation : obligation. clone ( ) ,
130
- code : match goal. predicate . kind ( ) . skip_binder ( ) {
131
- ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( _) ) => {
132
- FulfillmentErrorCode :: ProjectionError (
133
- // FIXME: This could be a `Sorts` if the term is a type
134
- MismatchedProjectionTypes { err : TypeError :: Mismatch } ,
135
- )
136
- }
137
- ty:: PredicateKind :: NormalizesTo ( ..) => {
138
- FulfillmentErrorCode :: ProjectionError (
139
- MismatchedProjectionTypes { err : TypeError :: Mismatch } ,
140
- )
141
- }
142
- ty:: PredicateKind :: AliasRelate ( _, _, _) => {
143
- FulfillmentErrorCode :: ProjectionError (
144
- MismatchedProjectionTypes { err : TypeError :: Mismatch } ,
145
- )
146
- }
147
- ty:: PredicateKind :: Subtype ( pred) => {
148
- let ( a, b) = infcx. enter_forall_and_leak_universe (
149
- goal. predicate . kind ( ) . rebind ( ( pred. a , pred. b ) ) ,
150
- ) ;
151
- let expected_found = ExpectedFound :: new ( true , a, b) ;
152
- FulfillmentErrorCode :: SubtypeError (
153
- expected_found,
154
- TypeError :: Sorts ( expected_found) ,
155
- )
156
- }
157
- ty:: PredicateKind :: Coerce ( pred) => {
158
- let ( a, b) = infcx. enter_forall_and_leak_universe (
159
- goal. predicate . kind ( ) . rebind ( ( pred. a , pred. b ) ) ,
160
- ) ;
161
- let expected_found = ExpectedFound :: new ( false , a, b) ;
162
- FulfillmentErrorCode :: SubtypeError (
163
- expected_found,
164
- TypeError :: Sorts ( expected_found) ,
165
- )
166
- }
167
- ty:: PredicateKind :: Clause ( _)
168
- | ty:: PredicateKind :: ObjectSafe ( _)
169
- | ty:: PredicateKind :: Ambiguous => {
170
- FulfillmentErrorCode :: SelectionError (
171
- SelectionError :: Unimplemented ,
172
- )
173
- }
174
- ty:: PredicateKind :: ConstEquate ( ..) => {
175
- bug ! ( "unexpected goal: {goal:?}" )
176
- }
177
- } ,
178
- root_obligation : obligation,
179
- } ) ;
99
+ errors. push ( fulfillment_error_for_no_solution ( infcx, obligation) ) ;
180
100
continue ;
181
101
}
182
102
} ;
@@ -206,3 +126,74 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
206
126
std:: mem:: take ( & mut self . obligations )
207
127
}
208
128
}
129
+
130
+ fn fulfillment_error_for_no_solution < ' tcx > (
131
+ infcx : & InferCtxt < ' tcx > ,
132
+ obligation : PredicateObligation < ' tcx > ,
133
+ ) -> FulfillmentError < ' tcx > {
134
+ let code = match obligation. predicate . kind ( ) . skip_binder ( ) {
135
+ ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( _) ) => {
136
+ FulfillmentErrorCode :: ProjectionError (
137
+ // FIXME: This could be a `Sorts` if the term is a type
138
+ MismatchedProjectionTypes { err : TypeError :: Mismatch } ,
139
+ )
140
+ }
141
+ ty:: PredicateKind :: NormalizesTo ( ..) => {
142
+ FulfillmentErrorCode :: ProjectionError ( MismatchedProjectionTypes {
143
+ err : TypeError :: Mismatch ,
144
+ } )
145
+ }
146
+ ty:: PredicateKind :: AliasRelate ( _, _, _) => {
147
+ FulfillmentErrorCode :: ProjectionError ( MismatchedProjectionTypes {
148
+ err : TypeError :: Mismatch ,
149
+ } )
150
+ }
151
+ ty:: PredicateKind :: Subtype ( pred) => {
152
+ let ( a, b) = infcx. enter_forall_and_leak_universe (
153
+ obligation. predicate . kind ( ) . rebind ( ( pred. a , pred. b ) ) ,
154
+ ) ;
155
+ let expected_found = ExpectedFound :: new ( true , a, b) ;
156
+ FulfillmentErrorCode :: SubtypeError ( expected_found, TypeError :: Sorts ( expected_found) )
157
+ }
158
+ ty:: PredicateKind :: Coerce ( pred) => {
159
+ let ( a, b) = infcx. enter_forall_and_leak_universe (
160
+ obligation. predicate . kind ( ) . rebind ( ( pred. a , pred. b ) ) ,
161
+ ) ;
162
+ let expected_found = ExpectedFound :: new ( false , a, b) ;
163
+ FulfillmentErrorCode :: SubtypeError ( expected_found, TypeError :: Sorts ( expected_found) )
164
+ }
165
+ ty:: PredicateKind :: Clause ( _)
166
+ | ty:: PredicateKind :: ObjectSafe ( _)
167
+ | ty:: PredicateKind :: Ambiguous => {
168
+ FulfillmentErrorCode :: SelectionError ( SelectionError :: Unimplemented )
169
+ }
170
+ ty:: PredicateKind :: ConstEquate ( ..) => {
171
+ bug ! ( "unexpected goal: {obligation:?}" )
172
+ }
173
+ } ;
174
+ FulfillmentError { root_obligation : obligation. clone ( ) , code, obligation }
175
+ }
176
+
177
+ fn fulfillment_error_for_stalled < ' tcx > (
178
+ infcx : & InferCtxt < ' tcx > ,
179
+ obligation : PredicateObligation < ' tcx > ,
180
+ ) -> FulfillmentError < ' tcx > {
181
+ let code = infcx. probe ( |_| {
182
+ match infcx. evaluate_root_goal ( obligation. clone ( ) . into ( ) , GenerateProofTree :: Never ) . 0 {
183
+ Ok ( ( _, Certainty :: Maybe ( MaybeCause :: Ambiguity ) ) ) => {
184
+ FulfillmentErrorCode :: Ambiguity { overflow : None }
185
+ }
186
+ Ok ( ( _, Certainty :: Maybe ( MaybeCause :: Overflow { suggest_increasing_limit } ) ) ) => {
187
+ FulfillmentErrorCode :: Ambiguity { overflow : Some ( suggest_increasing_limit) }
188
+ }
189
+ Ok ( ( _, Certainty :: Yes ) ) => {
190
+ bug ! ( "did not expect successful goal when collecting ambiguity errors" )
191
+ }
192
+ Err ( _) => {
193
+ bug ! ( "did not expect selection error when collecting ambiguity errors" )
194
+ }
195
+ }
196
+ } ) ;
197
+
198
+ FulfillmentError { obligation : obligation. clone ( ) , code, root_obligation : obligation }
199
+ }
0 commit comments