17
17
18
18
use rustc_hir:: def_id:: DefId ;
19
19
use rustc_infer:: infer:: canonical:: { Canonical , CanonicalVarValues } ;
20
- use rustc_infer:: infer:: { DefineOpaqueTypes , InferOk } ;
21
20
use rustc_infer:: traits:: query:: NoSolution ;
22
21
use rustc_middle:: traits:: solve:: {
23
22
CanonicalGoal , CanonicalResponse , Certainty , ExternalConstraints , ExternalConstraintsData ,
@@ -101,11 +100,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
101
100
// That won't actually reflect in the query response, so it seems moot.
102
101
self . evaluate_added_goals_and_make_canonical_response ( Certainty :: AMBIGUOUS )
103
102
} else {
104
- let InferOk { value : ( ) , obligations } = self
105
- . infcx
106
- . at ( & ObligationCause :: dummy ( ) , goal. param_env )
107
- . sub ( DefineOpaqueTypes :: No , goal. predicate . a , goal. predicate . b ) ?;
108
- self . add_goals ( obligations. into_iter ( ) . map ( |pred| pred. into ( ) ) ) ;
103
+ self . sub ( goal. param_env , goal. predicate . a , goal. predicate . b ) ?;
109
104
self . evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
110
105
}
111
106
}
@@ -161,44 +156,41 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
161
156
goal : Goal < ' tcx , ( ty:: Term < ' tcx > , ty:: Term < ' tcx > , ty:: AliasRelationDirection ) > ,
162
157
) -> QueryResult < ' tcx > {
163
158
let tcx = self . tcx ( ) ;
164
-
165
- let evaluate_normalizes_to = |ecx : & mut EvalCtxt < ' _ , ' tcx > , alias, other, direction| {
166
- debug ! ( "evaluate_normalizes_to(alias={:?}, other={:?})" , alias, other) ;
167
- let result = ecx. probe ( |ecx| {
168
- let other = match direction {
169
- // This is purely an optimization.
170
- ty:: AliasRelationDirection :: Equate => other,
171
-
172
- ty:: AliasRelationDirection :: Subtype | ty:: AliasRelationDirection :: Supertype => {
173
- let fresh = ecx. next_term_infer_of_kind ( other) ;
174
- let ( sub, sup) = if direction == ty:: AliasRelationDirection :: Subtype {
175
- ( fresh, other)
176
- } else {
177
- ( other, fresh)
178
- } ;
179
- ecx. add_goals (
180
- ecx. infcx
181
- . at ( & ObligationCause :: dummy ( ) , goal. param_env )
182
- . sub ( DefineOpaqueTypes :: No , sub, sup) ?
183
- . into_obligations ( )
184
- . into_iter ( )
185
- . map ( |o| o. into ( ) ) ,
186
- ) ;
187
- fresh
188
- }
189
- } ;
190
- ecx. add_goal ( goal. with (
191
- tcx,
192
- ty:: Binder :: dummy ( ty:: ProjectionPredicate {
193
- projection_ty : alias,
194
- term : other,
195
- } ) ,
196
- ) ) ;
197
- ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
198
- } ) ;
199
- debug ! ( "evaluate_normalizes_to({alias}, {other}, {direction:?}) -> {result:?}" ) ;
200
- result
201
- } ;
159
+ // We may need to invert the alias relation direction if dealing an alias on the RHS.
160
+ enum Invert {
161
+ No ,
162
+ Yes ,
163
+ }
164
+ let evaluate_normalizes_to =
165
+ |ecx : & mut EvalCtxt < ' _ , ' tcx > , alias, other, direction, invert| {
166
+ debug ! ( "evaluate_normalizes_to(alias={:?}, other={:?})" , alias, other) ;
167
+ let result = ecx. probe ( |ecx| {
168
+ let other = match direction {
169
+ // This is purely an optimization.
170
+ ty:: AliasRelationDirection :: Equate => other,
171
+
172
+ ty:: AliasRelationDirection :: Subtype => {
173
+ let fresh = ecx. next_term_infer_of_kind ( other) ;
174
+ let ( sub, sup) = match invert {
175
+ Invert :: No => ( fresh, other) ,
176
+ Invert :: Yes => ( other, fresh) ,
177
+ } ;
178
+ ecx. sub ( goal. param_env , sub, sup) ?;
179
+ fresh
180
+ }
181
+ } ;
182
+ ecx. add_goal ( goal. with (
183
+ tcx,
184
+ ty:: Binder :: dummy ( ty:: ProjectionPredicate {
185
+ projection_ty : alias,
186
+ term : other,
187
+ } ) ,
188
+ ) ) ;
189
+ ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
190
+ } ) ;
191
+ debug ! ( "evaluate_normalizes_to({alias}, {other}, {direction:?}) -> {result:?}" ) ;
192
+ result
193
+ } ;
202
194
203
195
let ( lhs, rhs, direction) = goal. predicate ;
204
196
@@ -212,46 +204,37 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
212
204
( None , None ) => bug ! ( "`AliasRelate` goal without an alias on either lhs or rhs" ) ,
213
205
214
206
// RHS is not a projection, only way this is true is if LHS normalizes-to RHS
215
- ( Some ( alias_lhs) , None ) => evaluate_normalizes_to ( self , alias_lhs, rhs, direction) ,
207
+ ( Some ( alias_lhs) , None ) => {
208
+ evaluate_normalizes_to ( self , alias_lhs, rhs, direction, Invert :: No )
209
+ }
216
210
217
211
// LHS is not a projection, only way this is true is if RHS normalizes-to LHS
218
212
( None , Some ( alias_rhs) ) => {
219
- evaluate_normalizes_to ( self , alias_rhs, lhs, direction. invert ( ) )
213
+ evaluate_normalizes_to ( self , alias_rhs, lhs, direction, Invert :: Yes )
220
214
}
221
215
222
216
( Some ( alias_lhs) , Some ( alias_rhs) ) => {
223
217
debug ! ( "compute_alias_relate_goal: both sides are aliases" ) ;
224
218
225
219
let candidates = vec ! [
226
220
// LHS normalizes-to RHS
227
- evaluate_normalizes_to( self , alias_lhs, rhs, direction) ,
221
+ evaluate_normalizes_to( self , alias_lhs, rhs, direction, Invert :: No ) ,
228
222
// RHS normalizes-to RHS
229
- evaluate_normalizes_to( self , alias_rhs, lhs, direction. invert ( ) ) ,
223
+ evaluate_normalizes_to( self , alias_rhs, lhs, direction, Invert :: Yes ) ,
230
224
// Relate via substs
231
225
self . probe( |ecx| {
232
226
debug!(
233
227
"compute_alias_relate_goal: alias defids are equal, equating substs"
234
228
) ;
235
229
236
- ecx. add_goals(
237
- match direction {
238
- ty:: AliasRelationDirection :: Equate => ecx
239
- . infcx
240
- . at( & ObligationCause :: dummy( ) , goal. param_env)
241
- . eq( DefineOpaqueTypes :: No , alias_lhs, alias_rhs) ,
242
- ty:: AliasRelationDirection :: Subtype => ecx
243
- . infcx
244
- . at( & ObligationCause :: dummy( ) , goal. param_env)
245
- . sub( DefineOpaqueTypes :: No , alias_lhs, alias_rhs) ,
246
- ty:: AliasRelationDirection :: Supertype => ecx
247
- . infcx
248
- . at( & ObligationCause :: dummy( ) , goal. param_env)
249
- . sup( DefineOpaqueTypes :: No , alias_lhs, alias_rhs) ,
250
- } ?
251
- . into_obligations( )
252
- . into_iter( )
253
- . map( |o| o. into( ) ) ,
254
- ) ;
230
+ match direction {
231
+ ty:: AliasRelationDirection :: Equate => {
232
+ ecx. eq( goal. param_env, alias_lhs, alias_rhs) ?;
233
+ }
234
+ ty:: AliasRelationDirection :: Subtype => {
235
+ ecx. sub( goal. param_env, alias_lhs, alias_rhs) ?;
236
+ }
237
+ }
255
238
256
239
ecx. evaluate_added_goals_and_make_canonical_response( Certainty :: Yes )
257
240
} ) ,
0 commit comments