@@ -61,7 +61,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
61
61
pub ( crate ) fn infer_opaque_types (
62
62
& self ,
63
63
infcx : & InferCtxt < ' tcx > ,
64
- opaque_ty_decls : FxIndexMap < OpaqueTypeKey < ' tcx > , ( OpaqueHiddenType < ' tcx > , OpaqueTyOrigin ) > ,
64
+ opaque_ty_decls : FxIndexMap < OpaqueTypeKey < ' tcx > , OpaqueHiddenType < ' tcx > > ,
65
65
) -> FxIndexMap < LocalDefId , OpaqueHiddenType < ' tcx > > {
66
66
let mut result: FxIndexMap < LocalDefId , OpaqueHiddenType < ' tcx > > = FxIndexMap :: default ( ) ;
67
67
@@ -72,7 +72,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
72
72
. collect ( ) ;
73
73
debug ! ( ?member_constraints) ;
74
74
75
- for ( opaque_type_key, ( concrete_type, origin ) ) in opaque_ty_decls {
75
+ for ( opaque_type_key, concrete_type) in opaque_ty_decls {
76
76
let substs = opaque_type_key. substs ;
77
77
debug ! ( ?concrete_type, ?substs) ;
78
78
@@ -143,7 +143,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
143
143
let ty = infcx. infer_opaque_definition_from_instantiation (
144
144
opaque_type_key,
145
145
universal_concrete_type,
146
- origin,
147
146
) ;
148
147
// Sometimes two opaque types are the same only after we remap the generic parameters
149
148
// back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
@@ -215,7 +214,6 @@ pub trait InferCtxtExt<'tcx> {
215
214
& self ,
216
215
opaque_type_key : OpaqueTypeKey < ' tcx > ,
217
216
instantiated_ty : OpaqueHiddenType < ' tcx > ,
218
- origin : OpaqueTyOrigin ,
219
217
) -> Ty < ' tcx > ;
220
218
}
221
219
@@ -248,109 +246,115 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
248
246
& self ,
249
247
opaque_type_key : OpaqueTypeKey < ' tcx > ,
250
248
instantiated_ty : OpaqueHiddenType < ' tcx > ,
251
- origin : OpaqueTyOrigin ,
252
249
) -> Ty < ' tcx > {
253
250
if let Some ( e) = self . tainted_by_errors ( ) {
254
251
return self . tcx . ty_error ( e) ;
255
252
}
256
253
254
+ if let Err ( guar) =
255
+ check_opaque_type_parameter_valid ( self . tcx , opaque_type_key, instantiated_ty. span )
256
+ {
257
+ return self . tcx . ty_error ( guar) ;
258
+ }
259
+
257
260
let definition_ty = instantiated_ty
258
261
. remap_generic_params_to_declaration_params ( opaque_type_key, self . tcx , false )
259
262
. ty ;
260
263
261
- if let Err ( guar) = check_opaque_type_parameter_valid (
264
+ // `definition_ty` does not live in of the current inference context,
265
+ // so lets make sure that we don't accidentally misuse our current `infcx`.
266
+ match check_opaque_type_well_formed (
262
267
self . tcx ,
263
- opaque_type_key ,
264
- origin ,
268
+ self . next_trait_solver ( ) ,
269
+ opaque_type_key . def_id ,
265
270
instantiated_ty. span ,
271
+ definition_ty,
266
272
) {
267
- return self . tcx . ty_error ( guar) ;
273
+ Ok ( hidden_ty) => hidden_ty,
274
+ Err ( guar) => self . tcx . ty_error ( guar) ,
268
275
}
276
+ }
277
+ }
269
278
270
- // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
271
- // on stable and we'd break that.
272
- let OpaqueTyOrigin :: TyAlias { .. } = origin else {
273
- return definition_ty;
274
- } ;
275
- let def_id = opaque_type_key. def_id ;
276
- // This logic duplicates most of `check_opaque_meets_bounds`.
277
- // FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely.
278
- let param_env = self . tcx . param_env ( def_id) ;
279
- // HACK This bubble is required for this tests to pass:
280
- // nested-return-type2-tait2.rs
281
- // nested-return-type2-tait3.rs
282
- // FIXME(-Ztrait-solver=next): We probably should use `DefiningAnchor::Error`
283
- // and prepopulate this `InferCtxt` with known opaque values, rather than
284
- // using the `Bind` anchor here. For now it's fine.
285
- let infcx = self
286
- . tcx
287
- . infer_ctxt ( )
288
- . with_opaque_type_inference ( if self . next_trait_solver ( ) {
289
- DefiningAnchor :: Bind ( def_id)
290
- } else {
291
- DefiningAnchor :: Bubble
292
- } )
293
- . build ( ) ;
294
- let ocx = ObligationCtxt :: new ( & infcx) ;
295
- // Require the hidden type to be well-formed with only the generics of the opaque type.
296
- // Defining use functions may have more bounds than the opaque type, which is ok, as long as the
297
- // hidden type is well formed even without those bounds.
298
- let predicate = ty:: Binder :: dummy ( ty:: PredicateKind :: WellFormed ( definition_ty. into ( ) ) ) ;
299
-
300
- let id_substs = InternalSubsts :: identity_for_item ( self . tcx , def_id) ;
279
+ /// This logic duplicates most of `check_opaque_meets_bounds`.
280
+ /// FIXME(oli-obk): Also do region checks here and then consider removing
281
+ /// `check_opaque_meets_bounds` entirely.
282
+ fn check_opaque_type_well_formed < ' tcx > (
283
+ tcx : TyCtxt < ' tcx > ,
284
+ next_trait_solver : bool ,
285
+ def_id : LocalDefId ,
286
+ definition_span : Span ,
287
+ definition_ty : Ty < ' tcx > ,
288
+ ) -> Result < Ty < ' tcx > , ErrorGuaranteed > {
289
+ // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
290
+ // on stable and we'd break that.
291
+ let opaque_ty_hir = tcx. hir ( ) . expect_item ( def_id) ;
292
+ let OpaqueTyOrigin :: TyAlias { .. } = opaque_ty_hir. expect_opaque_ty ( ) . origin else {
293
+ return Ok ( definition_ty) ;
294
+ } ;
295
+ let param_env = tcx. param_env ( def_id) ;
296
+ // HACK This bubble is required for this tests to pass:
297
+ // nested-return-type2-tait2.rs
298
+ // nested-return-type2-tait3.rs
299
+ // FIXME(-Ztrait-solver=next): We probably should use `DefiningAnchor::Error`
300
+ // and prepopulate this `InferCtxt` with known opaque values, rather than
301
+ // using the `Bind` anchor here. For now it's fine.
302
+ let infcx = tcx
303
+ . infer_ctxt ( )
304
+ . with_next_trait_solver ( next_trait_solver)
305
+ . with_opaque_type_inference ( if next_trait_solver {
306
+ DefiningAnchor :: Bind ( def_id)
307
+ } else {
308
+ DefiningAnchor :: Bubble
309
+ } )
310
+ . build ( ) ;
311
+ let ocx = ObligationCtxt :: new ( & infcx) ;
312
+ let identity_substs = InternalSubsts :: identity_for_item ( tcx, def_id) ;
301
313
302
- // Require that the hidden type actually fulfills all the bounds of the opaque type, even without
303
- // the bounds that the function supplies.
304
- let opaque_ty = self . tcx . mk_opaque ( def_id. to_def_id ( ) , id_substs) ;
305
- if let Err ( err) = ocx. eq (
306
- & ObligationCause :: misc ( instantiated_ty. span , def_id) ,
307
- param_env,
308
- opaque_ty,
309
- definition_ty,
310
- ) {
314
+ // Require that the hidden type actually fulfills all the bounds of the opaque type, even without
315
+ // the bounds that the function supplies.
316
+ let opaque_ty = tcx. mk_opaque ( def_id. to_def_id ( ) , identity_substs) ;
317
+ ocx. eq ( & ObligationCause :: misc ( definition_span, def_id) , param_env, opaque_ty, definition_ty)
318
+ . map_err ( |err| {
311
319
infcx
312
320
. err_ctxt ( )
313
321
. report_mismatched_types (
314
- & ObligationCause :: misc ( instantiated_ty . span , def_id) ,
322
+ & ObligationCause :: misc ( definition_span , def_id) ,
315
323
opaque_ty,
316
324
definition_ty,
317
325
err,
318
326
)
319
- . emit ( ) ;
320
- }
327
+ . emit ( )
328
+ } ) ? ;
321
329
322
- ocx. register_obligation ( Obligation :: misc (
323
- infcx. tcx ,
324
- instantiated_ty. span ,
325
- def_id,
326
- param_env,
327
- predicate,
328
- ) ) ;
330
+ // Require the hidden type to be well-formed with only the generics of the opaque type.
331
+ // Defining use functions may have more bounds than the opaque type, which is ok, as long as the
332
+ // hidden type is well formed even without those bounds.
333
+ let predicate = ty:: Binder :: dummy ( ty:: PredicateKind :: WellFormed ( definition_ty. into ( ) ) ) ;
334
+ ocx. register_obligation ( Obligation :: misc ( tcx, definition_span, def_id, param_env, predicate) ) ;
329
335
330
- // Check that all obligations are satisfied by the implementation's
331
- // version.
332
- let errors = ocx. select_all_or_error ( ) ;
336
+ // Check that all obligations are satisfied by the implementation's
337
+ // version.
338
+ let errors = ocx. select_all_or_error ( ) ;
333
339
334
- // This is still required for many(half of the tests in ui/type-alias-impl-trait)
335
- // tests to pass
336
- let _ = infcx. take_opaque_types ( ) ;
340
+ // This is still required for many(half of the tests in ui/type-alias-impl-trait)
341
+ // tests to pass
342
+ let _ = infcx. take_opaque_types ( ) ;
337
343
338
- if errors. is_empty ( ) {
339
- definition_ty
340
- } else {
341
- let reported = infcx. err_ctxt ( ) . report_fulfillment_errors ( & errors) ;
342
- self . tcx . ty_error ( reported)
343
- }
344
+ if errors. is_empty ( ) {
345
+ Ok ( definition_ty)
346
+ } else {
347
+ Err ( infcx. err_ctxt ( ) . report_fulfillment_errors ( & errors) )
344
348
}
345
349
}
346
350
347
351
fn check_opaque_type_parameter_valid (
348
352
tcx : TyCtxt < ' _ > ,
349
353
opaque_type_key : OpaqueTypeKey < ' _ > ,
350
- origin : OpaqueTyOrigin ,
351
354
span : Span ,
352
355
) -> Result < ( ) , ErrorGuaranteed > {
353
- match origin {
356
+ let opaque_ty_hir = tcx. hir ( ) . expect_item ( opaque_type_key. def_id ) ;
357
+ match opaque_ty_hir. expect_opaque_ty ( ) . origin {
354
358
// No need to check return position impl trait (RPIT)
355
359
// because for type and const parameters they are correct
356
360
// by construction: we convert
0 commit comments