@@ -73,36 +73,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
7373 fn collect_remaining_errors ( & mut self , infcx : & InferCtxt < ' tcx > ) -> Vec < FulfillmentError < ' tcx > > {
7474 self . obligations
7575 . 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) )
10677 . collect ( )
10778 }
10879
@@ -125,58 +96,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
12596 let ( changed, certainty) = match result {
12697 Ok ( result) => result,
12798 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) ) ;
180100 continue ;
181101 }
182102 } ;
@@ -206,3 +126,74 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
206126 std:: mem:: take ( & mut self . obligations )
207127 }
208128}
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