@@ -12,7 +12,6 @@ use rustc_middle::ty::subst::SubstsRef;
12
12
use rustc_middle:: ty:: { self , Binder , Const , TypeVisitableExt } ;
13
13
use std:: marker:: PhantomData ;
14
14
15
- use super :: const_evaluatable;
16
15
use super :: project:: { self , ProjectAndUnifyResult } ;
17
16
use super :: select:: SelectionContext ;
18
17
use super :: wf;
@@ -22,6 +21,7 @@ use super::CodeSelectionError;
22
21
use super :: EvaluationResult ;
23
22
use super :: PredicateObligation ;
24
23
use super :: Unimplemented ;
24
+ use super :: { const_evaluatable, TraitQueryMode } ;
25
25
use super :: { FulfillmentError , FulfillmentErrorCode } ;
26
26
27
27
use crate :: traits:: project:: PolyProjectionObligation ;
@@ -64,6 +64,8 @@ pub struct FulfillmentContext<'tcx> {
64
64
// a snapshot (they don't *straddle* a snapshot, so there
65
65
// is no trouble there).
66
66
usable_in_snapshot : bool ,
67
+
68
+ query_mode : TraitQueryMode ,
67
69
}
68
70
69
71
#[ derive( Clone , Debug ) ]
@@ -80,38 +82,30 @@ pub struct PendingPredicateObligation<'tcx> {
80
82
#[ cfg( all( target_arch = "x86_64" , target_pointer_width = "64" ) ) ]
81
83
static_assert_size ! ( PendingPredicateObligation <' _>, 72 ) ;
82
84
83
- impl < ' a , ' tcx > FulfillmentContext < ' tcx > {
85
+ impl < ' tcx > FulfillmentContext < ' tcx > {
84
86
/// Creates a new fulfillment context.
85
87
pub ( super ) fn new ( ) -> FulfillmentContext < ' tcx > {
86
- FulfillmentContext { predicates : ObligationForest :: new ( ) , usable_in_snapshot : false }
88
+ FulfillmentContext {
89
+ predicates : ObligationForest :: new ( ) ,
90
+ usable_in_snapshot : false ,
91
+ query_mode : TraitQueryMode :: Standard ,
92
+ }
87
93
}
88
94
89
95
pub ( super ) fn new_in_snapshot ( ) -> FulfillmentContext < ' tcx > {
90
- FulfillmentContext { predicates : ObligationForest :: new ( ) , usable_in_snapshot : true }
96
+ FulfillmentContext {
97
+ predicates : ObligationForest :: new ( ) ,
98
+ usable_in_snapshot : true ,
99
+ query_mode : TraitQueryMode :: Standard ,
100
+ }
91
101
}
92
102
93
- /// Attempts to select obligations using `selcx`.
94
- fn select ( & mut self , selcx : SelectionContext < ' a , ' tcx > ) -> Vec < FulfillmentError < ' tcx > > {
95
- let span = debug_span ! ( "select" , obligation_forest_size = ?self . predicates. len( ) ) ;
96
- let _enter = span. enter ( ) ;
97
-
98
- // Process pending obligations.
99
- let outcome: Outcome < _ , _ > =
100
- self . predicates . process_obligations ( & mut FulfillProcessor { selcx } ) ;
101
-
102
- // FIXME: if we kept the original cache key, we could mark projection
103
- // obligations as complete for the projection cache here.
104
-
105
- let errors: Vec < FulfillmentError < ' tcx > > =
106
- outcome. errors . into_iter ( ) . map ( to_fulfillment_error) . collect ( ) ;
107
-
108
- debug ! (
109
- "select({} predicates remaining, {} errors) done" ,
110
- self . predicates. len( ) ,
111
- errors. len( )
112
- ) ;
113
-
114
- errors
103
+ pub ( super ) fn with_query_mode_canonical ( ) -> FulfillmentContext < ' tcx > {
104
+ FulfillmentContext {
105
+ predicates : ObligationForest :: new ( ) ,
106
+ usable_in_snapshot : false ,
107
+ query_mode : TraitQueryMode :: Canonical ,
108
+ }
115
109
}
116
110
}
117
111
@@ -138,8 +132,27 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
138
132
}
139
133
140
134
fn select_where_possible ( & mut self , infcx : & InferCtxt < ' tcx > ) -> Vec < FulfillmentError < ' tcx > > {
141
- let selcx = SelectionContext :: new ( infcx) ;
142
- self . select ( selcx)
135
+ let span = debug_span ! ( "select" , obligation_forest_size = ?self . predicates. len( ) ) ;
136
+ let selcx = SelectionContext :: with_query_mode ( infcx, self . query_mode ) ;
137
+ let _enter = span. enter ( ) ;
138
+
139
+ // Process pending obligations.
140
+ let outcome: Outcome < _ , _ > =
141
+ self . predicates . process_obligations ( & mut FulfillProcessor { selcx } ) ;
142
+
143
+ // FIXME: if we kept the original cache key, we could mark projection
144
+ // obligations as complete for the projection cache here.
145
+
146
+ let errors: Vec < FulfillmentError < ' tcx > > =
147
+ outcome. errors . into_iter ( ) . map ( to_fulfillment_error) . collect ( ) ;
148
+
149
+ debug ! (
150
+ "select({} predicates remaining, {} errors) done" ,
151
+ self . predicates. len( ) ,
152
+ errors. len( )
153
+ ) ;
154
+
155
+ errors
143
156
}
144
157
145
158
fn drain_unstalled_obligations (
0 commit comments