@@ -6,14 +6,21 @@ use rustc_middle::ty::{
66    TypeVisitableExt ,  fold_regions, 
77} ; 
88use  rustc_span:: Span ; 
9- use  rustc_trait_selection:: opaque_types:: check_opaque_type_parameter_valid; 
9+ use  rustc_trait_selection:: opaque_types:: { 
10+     InvalidOpaqueTypeArgs ,  check_opaque_type_parameter_valid, 
11+ } ; 
1012use  tracing:: { debug,  instrument} ; 
1113
1214use  super :: RegionInferenceContext ; 
1315use  crate :: BorrowCheckRootCtxt ; 
1416use  crate :: session_diagnostics:: LifetimeMismatchOpaqueParam ; 
1517use  crate :: universal_regions:: RegionClassification ; 
1618
19+ pub ( crate )  enum  DeferredOpaqueTypeError < ' tcx >  { 
20+     InvalidOpaqueTypeArgs ( InvalidOpaqueTypeArgs < ' tcx > ) , 
21+     LifetimeMismatchOpaqueParam ( LifetimeMismatchOpaqueParam < ' tcx > ) , 
22+ } 
23+ 
1724impl < ' tcx >  RegionInferenceContext < ' tcx >  { 
1825    /// Resolve any opaque types that were encountered while borrow checking 
1926     /// this item. This is then used to get the type in the `type_of` query. 
@@ -58,13 +65,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
5865     /// 
5966     /// [rustc-dev-guide chapter]: 
6067     /// https://rustc-dev-guide.rust-lang.org/opaque-types-region-infer-restrictions.html 
61-      #[ instrument( level = "debug" ,  skip( self ,  root_cx,  infcx) ,  ret ) ]  
68+      #[ instrument( level = "debug" ,  skip( self ,  root_cx,  infcx) ) ]  
6269    pub ( crate )  fn  infer_opaque_types ( 
6370        & self , 
6471        root_cx :  & mut  BorrowCheckRootCtxt < ' tcx > , 
6572        infcx :  & InferCtxt < ' tcx > , 
6673        opaque_ty_decls :  FxIndexMap < OpaqueTypeKey < ' tcx > ,  OpaqueHiddenType < ' tcx > > , 
67-     )  { 
74+     )  -> Vec < DeferredOpaqueTypeError < ' tcx > >  { 
75+         let  mut  errors = Vec :: new ( ) ; 
6876        let  mut  decls_modulo_regions:  FxIndexMap < OpaqueTypeKey < ' tcx > ,  ( OpaqueTypeKey < ' tcx > ,  Span ) >  =
6977            FxIndexMap :: default ( ) ; 
7078
@@ -124,8 +132,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
124132            } ) ; 
125133            debug ! ( ?concrete_type) ; 
126134
127-             let  ty =
128-                 infcx. infer_opaque_definition_from_instantiation ( opaque_type_key,  concrete_type) ; 
135+             let  ty = match  infcx
136+                 . infer_opaque_definition_from_instantiation ( opaque_type_key,  concrete_type) 
137+             { 
138+                 Ok ( ty)  => ty, 
139+                 Err ( err)  => { 
140+                     errors. push ( DeferredOpaqueTypeError :: InvalidOpaqueTypeArgs ( err) ) ; 
141+                     continue ; 
142+                 } 
143+             } ; 
129144
130145            // Sometimes, when the hidden type is an inference variable, it can happen that 
131146            // the hidden type becomes the opaque type itself. In this case, this was an opaque 
@@ -149,25 +164,27 @@ impl<'tcx> RegionInferenceContext<'tcx> {
149164            // non-region parameters. This is necessary because within the new solver we perform 
150165            // various query operations modulo regions, and thus could unsoundly select some impls 
151166            // that don't hold. 
152-             if  !ty. references_error ( ) 
153-                 && let  Some ( ( prev_decl_key,  prev_span) )  = decls_modulo_regions. insert ( 
154-                     infcx. tcx . erase_regions ( opaque_type_key) , 
155-                     ( opaque_type_key,  concrete_type. span ) , 
156-                 ) 
157-                 && let  Some ( ( arg1,  arg2) )  = std:: iter:: zip ( 
158-                     prev_decl_key. iter_captured_args ( infcx. tcx ) . map ( |( _,  arg) | arg) , 
159-                     opaque_type_key. iter_captured_args ( infcx. tcx ) . map ( |( _,  arg) | arg) , 
160-                 ) 
161-                 . find ( |( arg1,  arg2) | arg1 != arg2) 
167+             if  let  Some ( ( prev_decl_key,  prev_span) )  = decls_modulo_regions. insert ( 
168+                 infcx. tcx . erase_regions ( opaque_type_key) , 
169+                 ( opaque_type_key,  concrete_type. span ) , 
170+             )  && let  Some ( ( arg1,  arg2) )  = std:: iter:: zip ( 
171+                 prev_decl_key. iter_captured_args ( infcx. tcx ) . map ( |( _,  arg) | arg) , 
172+                 opaque_type_key. iter_captured_args ( infcx. tcx ) . map ( |( _,  arg) | arg) , 
173+             ) 
174+             . find ( |( arg1,  arg2) | arg1 != arg2) 
162175            { 
163-                 infcx. dcx ( ) . emit_err ( LifetimeMismatchOpaqueParam  { 
164-                     arg :  arg1, 
165-                     prev :  arg2, 
166-                     span :  prev_span, 
167-                     prev_span :  concrete_type. span , 
168-                 } ) ; 
176+                 errors. push ( DeferredOpaqueTypeError :: LifetimeMismatchOpaqueParam ( 
177+                     LifetimeMismatchOpaqueParam  { 
178+                         arg :  arg1, 
179+                         prev :  arg2, 
180+                         span :  prev_span, 
181+                         prev_span :  concrete_type. span , 
182+                     } , 
183+                 ) ) ; 
169184            } 
170185        } 
186+ 
187+         errors
171188    } 
172189
173190    /// Map the regions in the type to named regions. This is similar to what 
@@ -260,19 +277,13 @@ impl<'tcx> InferCtxt<'tcx> {
260277        & self , 
261278        opaque_type_key :  OpaqueTypeKey < ' tcx > , 
262279        instantiated_ty :  OpaqueHiddenType < ' tcx > , 
263-     )  -> Ty < ' tcx >  { 
264-         if  let  Some ( e)  = self . tainted_by_errors ( )  { 
265-             return  Ty :: new_error ( self . tcx ,  e) ; 
266-         } 
267- 
268-         if  let  Err ( err)  = check_opaque_type_parameter_valid ( 
280+     )  -> Result < Ty < ' tcx > ,  InvalidOpaqueTypeArgs < ' tcx > >  { 
281+         check_opaque_type_parameter_valid ( 
269282            self , 
270283            opaque_type_key, 
271284            instantiated_ty. span , 
272285            DefiningScopeKind :: MirBorrowck , 
273-         )  { 
274-             return  Ty :: new_error ( self . tcx ,  err. report ( self ) ) ; 
275-         } 
286+         ) ?; 
276287
277288        let  definition_ty = instantiated_ty
278289            . remap_generic_params_to_declaration_params ( 
@@ -282,10 +293,7 @@ impl<'tcx> InferCtxt<'tcx> {
282293            ) 
283294            . ty ; 
284295
285-         if  let  Err ( e)  = definition_ty. error_reported ( )  { 
286-             return  Ty :: new_error ( self . tcx ,  e) ; 
287-         } 
288- 
289-         definition_ty
296+         definition_ty. error_reported ( ) ?; 
297+         Ok ( definition_ty) 
290298    } 
291299} 
0 commit comments