@@ -6,14 +6,21 @@ use rustc_middle::ty::{
6
6
TypeVisitableExt , fold_regions,
7
7
} ;
8
8
use 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
+ } ;
10
12
use tracing:: { debug, instrument} ;
11
13
12
14
use super :: RegionInferenceContext ;
13
15
use crate :: BorrowCheckRootCtxt ;
14
16
use crate :: session_diagnostics:: LifetimeMismatchOpaqueParam ;
15
17
use crate :: universal_regions:: RegionClassification ;
16
18
19
+ pub ( crate ) enum DeferredOpaqueTypeError < ' tcx > {
20
+ InvalidOpaqueTypeArgs ( InvalidOpaqueTypeArgs < ' tcx > ) ,
21
+ LifetimeMismatchOpaqueParam ( LifetimeMismatchOpaqueParam < ' tcx > ) ,
22
+ }
23
+
17
24
impl < ' tcx > RegionInferenceContext < ' tcx > {
18
25
/// Resolve any opaque types that were encountered while borrow checking
19
26
/// this item. This is then used to get the type in the `type_of` query.
@@ -58,13 +65,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
58
65
///
59
66
/// [rustc-dev-guide chapter]:
60
67
/// 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) ) ]
62
69
pub ( crate ) fn infer_opaque_types (
63
70
& self ,
64
71
root_cx : & mut BorrowCheckRootCtxt < ' tcx > ,
65
72
infcx : & InferCtxt < ' tcx > ,
66
73
opaque_ty_decls : FxIndexMap < OpaqueTypeKey < ' tcx > , OpaqueHiddenType < ' tcx > > ,
67
- ) {
74
+ ) -> Vec < DeferredOpaqueTypeError < ' tcx > > {
75
+ let mut errors = Vec :: new ( ) ;
68
76
let mut decls_modulo_regions: FxIndexMap < OpaqueTypeKey < ' tcx > , ( OpaqueTypeKey < ' tcx > , Span ) > =
69
77
FxIndexMap :: default ( ) ;
70
78
@@ -124,8 +132,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
124
132
} ) ;
125
133
debug ! ( ?concrete_type) ;
126
134
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
+ } ;
129
144
130
145
// Sometimes, when the hidden type is an inference variable, it can happen that
131
146
// the hidden type becomes the opaque type itself. In this case, this was an opaque
@@ -149,25 +164,27 @@ impl<'tcx> RegionInferenceContext<'tcx> {
149
164
// non-region parameters. This is necessary because within the new solver we perform
150
165
// various query operations modulo regions, and thus could unsoundly select some impls
151
166
// 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)
162
175
{
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
+ ) ) ;
169
184
}
170
185
}
186
+
187
+ errors
171
188
}
172
189
173
190
/// Map the regions in the type to named regions. This is similar to what
@@ -260,19 +277,13 @@ impl<'tcx> InferCtxt<'tcx> {
260
277
& self ,
261
278
opaque_type_key : OpaqueTypeKey < ' tcx > ,
262
279
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 (
269
282
self ,
270
283
opaque_type_key,
271
284
instantiated_ty. span ,
272
285
DefiningScopeKind :: MirBorrowck ,
273
- ) {
274
- return Ty :: new_error ( self . tcx , err. report ( self ) ) ;
275
- }
286
+ ) ?;
276
287
277
288
let definition_ty = instantiated_ty
278
289
. remap_generic_params_to_declaration_params (
@@ -282,10 +293,7 @@ impl<'tcx> InferCtxt<'tcx> {
282
293
)
283
294
. ty ;
284
295
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)
290
298
}
291
299
}
0 commit comments