@@ -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