@@ -153,20 +153,22 @@ impl<'tcx> InferCtxt<'tcx> {
153153
154154 /// Used by the new solver as that one takes the opaque types at the end of a probe
155155 /// to deal with multiple candidates without having to recompute them.
156- pub fn clone_opaque_types_for_query_response ( & self ) -> Vec < ( Ty < ' tcx > , Ty < ' tcx > ) > {
156+ pub fn clone_opaque_types_for_query_response (
157+ & self ,
158+ ) -> Vec < ( ty:: OpaqueTypeKey < ' tcx > , Ty < ' tcx > ) > {
157159 self . inner
158160 . borrow ( )
159161 . opaque_type_storage
160162 . opaque_types
161163 . iter ( )
162- . map ( |( k, v) | ( self . tcx . mk_opaque ( k . def_id . to_def_id ( ) , k . substs ) , v. hidden_type . ty ) )
164+ . map ( |( k, v) | ( * k , v. hidden_type . ty ) )
163165 . collect ( )
164166 }
165167
166- fn take_opaque_types_for_query_response ( & self ) -> Vec < ( Ty < ' tcx > , Ty < ' tcx > ) > {
168+ fn take_opaque_types_for_query_response ( & self ) -> Vec < ( ty :: OpaqueTypeKey < ' tcx > , Ty < ' tcx > ) > {
167169 std:: mem:: take ( & mut self . inner . borrow_mut ( ) . opaque_type_storage . opaque_types )
168170 . into_iter ( )
169- . map ( |( k, v) | ( self . tcx . mk_opaque ( k . def_id . to_def_id ( ) , k . substs ) , v. hidden_type . ty ) )
171+ . map ( |( k, v) | ( k , v. hidden_type . ty ) )
170172 . collect ( )
171173 }
172174
@@ -507,8 +509,22 @@ impl<'tcx> InferCtxt<'tcx> {
507509 let a = substitute_value ( self . tcx , & result_subst, a) ;
508510 let b = substitute_value ( self . tcx , & result_subst, b) ;
509511 debug ! ( ?a, ?b, "constrain opaque type" ) ;
510- obligations
511- . extend ( self . at ( cause, param_env) . eq ( DefineOpaqueTypes :: Yes , a, b) ?. obligations ) ;
512+ // We use equate here instead of, for example, just registering the
513+ // opaque type's hidden value directly, because we may be instantiating
514+ // a query response that was canonicalized in an InferCtxt that had
515+ // a different defining anchor. In that case, we may have inferred
516+ // `NonLocalOpaque := LocalOpaque` but can only instantiate it in
517+ // the other direction as `LocalOpaque := NonLocalOpaque`. Using eq
518+ // here allows us to try both directions (in `InferCtxt::handle_opaque_type`).
519+ obligations. extend (
520+ self . at ( cause, param_env)
521+ . eq (
522+ DefineOpaqueTypes :: Yes ,
523+ self . tcx . mk_opaque ( a. def_id . to_def_id ( ) , a. substs ) ,
524+ b,
525+ ) ?
526+ . obligations ,
527+ ) ;
512528 }
513529
514530 Ok ( InferOk { value : result_subst, obligations } )
0 commit comments