1717
1818use rustc_hir:: def_id:: DefId ;
1919use rustc_infer:: infer:: canonical:: { Canonical , CanonicalVarValues } ;
20- use rustc_infer:: infer:: { DefineOpaqueTypes , InferOk } ;
2120use rustc_infer:: traits:: query:: NoSolution ;
2221use rustc_middle:: traits:: solve:: {
2322 CanonicalGoal , CanonicalResponse , Certainty , ExternalConstraints , ExternalConstraintsData ,
@@ -101,11 +100,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
101100 // That won't actually reflect in the query response, so it seems moot.
102101 self . evaluate_added_goals_and_make_canonical_response ( Certainty :: AMBIGUOUS )
103102 } 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 ) ?;
109104 self . evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
110105 }
111106 }
@@ -161,44 +156,41 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
161156 goal : Goal < ' tcx , ( ty:: Term < ' tcx > , ty:: Term < ' tcx > , ty:: AliasRelationDirection ) > ,
162157 ) -> QueryResult < ' tcx > {
163158 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+ } ;
202194
203195 let ( lhs, rhs, direction) = goal. predicate ;
204196
@@ -212,46 +204,37 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
212204 ( None , None ) => bug ! ( "`AliasRelate` goal without an alias on either lhs or rhs" ) ,
213205
214206 // 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+ }
216210
217211 // LHS is not a projection, only way this is true is if RHS normalizes-to LHS
218212 ( 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 )
220214 }
221215
222216 ( Some ( alias_lhs) , Some ( alias_rhs) ) => {
223217 debug ! ( "compute_alias_relate_goal: both sides are aliases" ) ;
224218
225219 let candidates = vec ! [
226220 // LHS normalizes-to RHS
227- evaluate_normalizes_to( self , alias_lhs, rhs, direction) ,
221+ evaluate_normalizes_to( self , alias_lhs, rhs, direction, Invert :: No ) ,
228222 // 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 ) ,
230224 // Relate via substs
231225 self . probe( |ecx| {
232226 debug!(
233227 "compute_alias_relate_goal: alias defids are equal, equating substs"
234228 ) ;
235229
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+ }
255238
256239 ecx. evaluate_added_goals_and_make_canonical_response( Certainty :: Yes )
257240 } ) ,
0 commit comments