11use crate :: infer:: { InferCtxt , InferOk } ;
2- use crate :: traits:: { self , PredicateObligation } ;
2+ use crate :: traits;
33use hir:: def_id:: { DefId , LocalDefId } ;
44use hir:: OpaqueTyOrigin ;
55use rustc_data_structures:: sync:: Lrc ;
@@ -42,25 +42,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
4242 & self ,
4343 a : Ty < ' tcx > ,
4444 b : Ty < ' tcx > ,
45+ a_is_expected : bool ,
4546 cause : & ObligationCause < ' tcx > ,
4647 param_env : ty:: ParamEnv < ' tcx > ,
4748 ) -> InferResult < ' tcx , ( ) > {
4849 if a. references_error ( ) || b. references_error ( ) {
4950 return Ok ( InferOk { value : ( ) , obligations : vec ! [ ] } ) ;
5051 }
51- if self . defining_use_anchor . is_some ( ) {
52- let process = |a : Ty < ' tcx > , b : Ty < ' tcx > | match * a. kind ( ) {
53- ty:: Opaque ( def_id, substs) => {
54- if let ty:: Opaque ( did2, _) = * b. kind ( ) {
55- // We could accept this, but there are various ways to handle this situation, and we don't
56- // want to make a decision on it right now. Likely this case is so super rare anyway, that
57- // no one encounters it in practice.
58- // It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
59- // where it is of no concern, so we only check for TAITs.
60- if let Some ( OpaqueTyOrigin :: TyAlias ) =
61- self . opaque_type_origin ( did2, cause. span )
62- {
63- self . tcx
52+ let ( a, b) = if a_is_expected { ( a, b) } else { ( b, a) } ;
53+ let process = |a : Ty < ' tcx > , b : Ty < ' tcx > | match * a. kind ( ) {
54+ ty:: Opaque ( def_id, substs) => {
55+ if let ty:: Opaque ( did2, _) = * b. kind ( ) {
56+ // We could accept this, but there are various ways to handle this situation, and we don't
57+ // want to make a decision on it right now. Likely this case is so super rare anyway, that
58+ // no one encounters it in practice.
59+ // It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
60+ // where it is of no concern, so we only check for TAITs.
61+ if let Some ( OpaqueTyOrigin :: TyAlias ) = self . opaque_type_origin ( did2, cause. span )
62+ {
63+ self . tcx
6464 . sess
6565 . struct_span_err (
6666 cause. span ,
@@ -76,13 +76,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
7676 "opaque type being used as hidden type" ,
7777 )
7878 . emit ( ) ;
79- }
8079 }
81- Some ( self . register_hidden_type (
82- OpaqueTypeKey { def_id, substs } ,
83- cause. clone ( ) ,
84- param_env,
85- b,
80+ }
81+ Some ( self . register_hidden_type (
82+ OpaqueTypeKey { def_id, substs } ,
83+ cause. clone ( ) ,
84+ param_env,
85+ b,
86+ if self . defining_use_anchor . is_some ( ) {
8687 // Check that this is `impl Trait` type is
8788 // declared by `parent_def_id` -- i.e., one whose
8889 // value we are inferring. At present, this is
@@ -117,47 +118,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
117118 // let x = || foo(); // returns the Opaque assoc with `foo`
118119 // }
119120 // ```
120- self . opaque_type_origin ( def_id, cause. span ) ?,
121- ) )
122- }
123- _ => None ,
124- } ;
125- if let Some ( res) = process ( a, b) {
126- res
127- } else if let Some ( res) = process ( b, a) {
128- res
129- } else {
130- // Rerun equality check, but this time error out due to
131- // different types.
132- match self . at ( cause, param_env) . define_opaque_types ( false ) . eq ( a, b) {
133- Ok ( _) => span_bug ! (
134- cause. span,
135- "opaque types are never equal to anything but themselves: {:#?}" ,
136- ( a. kind( ) , b. kind( ) )
137- ) ,
138- Err ( e) => Err ( e) ,
139- }
121+ self . opaque_type_origin ( def_id, cause. span ) ?
122+ } else {
123+ self . opaque_ty_origin_unchecked ( def_id, cause. span )
124+ } ,
125+ ) )
140126 }
127+ _ => None ,
128+ } ;
129+ if let Some ( res) = process ( a, b) {
130+ res
131+ } else if let Some ( res) = process ( b, a) {
132+ res
141133 } else {
142- let ( opaque_type , hidden_ty ) = match ( a . kind ( ) , b . kind ( ) ) {
143- ( ty :: Opaque ( .. ) , _ ) => ( a , b ) ,
144- ( _ , ty :: Opaque ( .. ) ) => ( b , a ) ,
145- types => span_bug ! (
134+ // Rerun equality check, but this time error out due to
135+ // different types.
136+ match self . at ( cause , param_env ) . define_opaque_types ( false ) . eq ( a , b ) {
137+ Ok ( _ ) => span_bug ! (
146138 cause. span,
147- "opaque type obligations only work for opaque types : {:#?}" ,
148- types
139+ "opaque types are never equal to anything but themselves : {:#?}" ,
140+ ( a . kind ( ) , b . kind ( ) )
149141 ) ,
150- } ;
151- let key = opaque_type. expect_opaque_type ( ) ;
152- let origin = self . opaque_ty_origin_unchecked ( key. def_id , cause. span ) ;
153- let prev = self . inner . borrow_mut ( ) . opaque_types ( ) . register (
154- key,
155- OpaqueHiddenType { ty : hidden_ty, span : cause. span } ,
156- origin,
157- ) ;
158- match prev {
159- Some ( prev) => self . at ( cause, param_env) . eq ( prev, hidden_ty) ,
160- None => Ok ( InferOk { value : ( ) , obligations : vec ! [ ] } ) ,
142+ Err ( e) => Err ( e) ,
161143 }
162144 }
163145 }
@@ -363,22 +345,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
363345 } ) ;
364346 }
365347
366- pub fn opaque_ty_obligation (
367- & self ,
368- a : Ty < ' tcx > ,
369- b : Ty < ' tcx > ,
370- a_is_expected : bool ,
371- param_env : ty:: ParamEnv < ' tcx > ,
372- cause : ObligationCause < ' tcx > ,
373- ) -> PredicateObligation < ' tcx > {
374- let ( a, b) = if a_is_expected { ( a, b) } else { ( b, a) } ;
375- PredicateObligation :: new (
376- cause,
377- param_env,
378- self . tcx . mk_predicate ( ty:: Binder :: dummy ( ty:: PredicateKind :: OpaqueType ( a, b) ) ) ,
379- )
380- }
381-
382348 #[ instrument( skip( self ) , level = "trace" ) ]
383349 pub fn opaque_type_origin ( & self , opaque_def_id : DefId , span : Span ) -> Option < OpaqueTyOrigin > {
384350 let def_id = opaque_def_id. as_local ( ) ?;
0 commit comments