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