@@ -74,37 +74,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
7474 fn collect_remaining_errors ( & mut self , infcx : & InferCtxt < ' tcx > ) -> Vec < FulfillmentError < ' tcx > > {
7575 self . obligations
7676 . 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) )
10878 . collect ( )
10979 }
11080
@@ -127,58 +97,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
12797 let ( changed, certainty, nested_goals) = match result {
12898 Ok ( result) => result,
12999 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) ) ;
182101 continue ;
183102 }
184103 } ;
@@ -218,3 +137,74 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
218137 std:: mem:: take ( & mut self . obligations )
219138 }
220139}
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