@@ -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 inspect_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 > {
@@ -100,65 +115,66 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
100115 let mut has_changed = false ;
101116 for obligation in mem:: take ( & mut self . obligations ) {
102117 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- } ;
118+ let result = infcx. evaluate_root_goal ( goal, GenerateProofTree :: IfEnabled ) . 0 ;
119+ self . inspect_evaluated_obligation ( infcx, & obligation, & result) ;
120+ let ( changed, certainty, nested_goals) = match result {
121+ Ok ( result) => result,
122+ Err ( NoSolution ) => {
123+ errors. push ( FulfillmentError {
124+ obligation : obligation. clone ( ) ,
125+ code : match goal. predicate . kind ( ) . skip_binder ( ) {
126+ ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( _) ) => {
127+ FulfillmentErrorCode :: ProjectionError (
128+ // FIXME: This could be a `Sorts` if the term is a type
129+ MismatchedProjectionTypes { err : TypeError :: Mismatch } ,
130+ )
131+ }
132+ ty:: PredicateKind :: NormalizesTo ( ..) => {
133+ FulfillmentErrorCode :: ProjectionError (
134+ MismatchedProjectionTypes { err : TypeError :: Mismatch } ,
135+ )
136+ }
137+ ty:: PredicateKind :: AliasRelate ( _, _, _) => {
138+ FulfillmentErrorCode :: ProjectionError (
139+ MismatchedProjectionTypes { err : TypeError :: Mismatch } ,
140+ )
141+ }
142+ ty:: PredicateKind :: Subtype ( pred) => {
143+ let ( a, b) = infcx. instantiate_binder_with_placeholders (
144+ goal. predicate . kind ( ) . rebind ( ( pred. a , pred. b ) ) ,
145+ ) ;
146+ let expected_found = ExpectedFound :: new ( true , a, b) ;
147+ FulfillmentErrorCode :: SubtypeError (
148+ expected_found,
149+ TypeError :: Sorts ( expected_found) ,
150+ )
151+ }
152+ ty:: PredicateKind :: Coerce ( pred) => {
153+ let ( a, b) = infcx. instantiate_binder_with_placeholders (
154+ goal. predicate . kind ( ) . rebind ( ( pred. a , pred. b ) ) ,
155+ ) ;
156+ let expected_found = ExpectedFound :: new ( false , a, b) ;
157+ FulfillmentErrorCode :: SubtypeError (
158+ expected_found,
159+ TypeError :: Sorts ( expected_found) ,
160+ )
161+ }
162+ ty:: PredicateKind :: Clause ( _)
163+ | ty:: PredicateKind :: ObjectSafe ( _)
164+ | ty:: PredicateKind :: Ambiguous => {
165+ FulfillmentErrorCode :: SelectionError (
166+ SelectionError :: Unimplemented ,
167+ )
168+ }
169+ ty:: PredicateKind :: ConstEquate ( ..) => {
170+ bug ! ( "unexpected goal: {goal:?}" )
171+ }
172+ } ,
173+ root_obligation : obligation,
174+ } ) ;
175+ continue ;
176+ }
177+ } ;
162178 // Push any nested goals that we get from unifying our canonical response
163179 // with our obligation onto the fulfillment context.
164180 self . obligations . extend ( nested_goals. into_iter ( ) . map ( |goal| {
0 commit comments