@@ -11,7 +11,7 @@ use rustc_middle::ty;
1111use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
1212
1313use super :: eval_ctxt:: GenerateProofTree ;
14- use super :: { Certainty , InferCtxtEvalExt } ;
14+ use super :: { Certainty , Goal , InferCtxtEvalExt } ;
1515
1616/// A trait engine using the new trait solver.
1717///
@@ -43,6 +43,21 @@ impl<'tcx> FulfillmentCtxt<'tcx> {
4343 ) ;
4444 FulfillmentCtxt { obligations : Vec :: new ( ) , usable_in_snapshot : infcx. num_open_snapshots ( ) }
4545 }
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+ }
4661}
4762
4863impl < ' tcx > TraitEngine < ' tcx > for FulfillmentCtxt < ' tcx > {
@@ -57,7 +72,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
5772 }
5873
5974 fn collect_remaining_errors ( & mut self , infcx : & InferCtxt < ' tcx > ) -> Vec < FulfillmentError < ' tcx > > {
60- self . obligations
75+ let errors = self
76+ . obligations
6177 . drain ( ..)
6278 . map ( |obligation| {
6379 let code = infcx. probe ( |_| {
@@ -86,7 +102,9 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
86102 root_obligation : obligation,
87103 }
88104 } )
89- . collect ( )
105+ . collect ( ) ;
106+
107+ errors
90108 }
91109
92110 fn select_where_possible ( & mut self , infcx : & InferCtxt < ' tcx > ) -> Vec < FulfillmentError < ' tcx > > {
@@ -100,65 +118,66 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
100118 let mut has_changed = false ;
101119 for obligation in mem:: take ( & mut self . obligations ) {
102120 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+ } ;
162181 // Push any nested goals that we get from unifying our canonical response
163182 // with our obligation onto the fulfillment context.
164183 self . obligations . extend ( nested_goals. into_iter ( ) . map ( |goal| {
0 commit comments