@@ -5,8 +5,7 @@ use rustc_hir::OpaqueTyOrigin;
5
5
use rustc_infer:: infer:: TyCtxtInferExt as _;
6
6
use rustc_infer:: infer:: { DefiningAnchor , InferCtxt } ;
7
7
use rustc_infer:: traits:: { Obligation , ObligationCause , TraitEngine } ;
8
- use rustc_middle:: ty:: fold:: { TypeFolder , TypeSuperFoldable } ;
9
- use rustc_middle:: ty:: subst:: { GenericArg , GenericArgKind , InternalSubsts } ;
8
+ use rustc_middle:: ty:: subst:: { GenericArgKind , InternalSubsts } ;
10
9
use rustc_middle:: ty:: visit:: TypeVisitable ;
11
10
use rustc_middle:: ty:: {
12
11
self , OpaqueHiddenType , OpaqueTypeKey , ToPredicate , Ty , TyCtxt , TypeFoldable ,
@@ -15,8 +14,6 @@ use rustc_span::Span;
15
14
use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt as _;
16
15
use rustc_trait_selection:: traits:: TraitEngineExt as _;
17
16
18
- use crate :: session_diagnostics:: ConstNotUsedTraitAlias ;
19
-
20
17
use super :: RegionInferenceContext ;
21
18
22
19
impl < ' tcx > RegionInferenceContext < ' tcx > {
@@ -228,29 +225,9 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
228
225
return self . tcx . ty_error ( ) ;
229
226
}
230
227
231
- let OpaqueTypeKey { def_id, substs } = opaque_type_key;
232
-
233
- // Use substs to build up a reverse map from regions to their
234
- // identity mappings. This is necessary because of `impl
235
- // Trait` lifetimes are computed by replacing existing
236
- // lifetimes with 'static and remapping only those used in the
237
- // `impl Trait` return type, resulting in the parameters
238
- // shifting.
239
- let id_substs = InternalSubsts :: identity_for_item ( self . tcx , def_id. to_def_id ( ) ) ;
240
- debug ! ( ?id_substs) ;
241
- let map: FxHashMap < GenericArg < ' tcx > , GenericArg < ' tcx > > =
242
- substs. iter ( ) . enumerate ( ) . map ( |( index, subst) | ( subst, id_substs[ index] ) ) . collect ( ) ;
243
- debug ! ( "map = {:#?}" , map) ;
244
-
245
- // Convert the type from the function into a type valid outside
246
- // the function, by replacing invalid regions with 'static,
247
- // after producing an error for each of them.
248
- let definition_ty = instantiated_ty. ty . fold_with ( & mut ReverseMapper :: new (
249
- self . tcx ,
250
- map,
251
- instantiated_ty. span ,
252
- ) ) ;
253
- debug ! ( ?definition_ty) ;
228
+ let definition_ty = instantiated_ty
229
+ . remap_generic_params_to_declaration_params ( opaque_type_key, self . tcx )
230
+ . ty ;
254
231
255
232
if !check_opaque_type_parameter_valid (
256
233
self . tcx ,
@@ -266,6 +243,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
266
243
let OpaqueTyOrigin :: TyAlias = origin else {
267
244
return definition_ty;
268
245
} ;
246
+ let def_id = opaque_type_key. def_id ;
269
247
// This logic duplicates most of `check_opaque_meets_bounds`.
270
248
// FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely.
271
249
let param_env = self . tcx . param_env ( def_id) ;
@@ -281,6 +259,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
281
259
. to_predicate ( infcx. tcx ) ;
282
260
let mut fulfillment_cx = <dyn TraitEngine < ' tcx > >:: new ( infcx. tcx ) ;
283
261
262
+ let id_substs = InternalSubsts :: identity_for_item ( self . tcx , def_id. to_def_id ( ) ) ;
263
+
284
264
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
285
265
// the bounds that the function supplies.
286
266
match infcx. register_hidden_type (
@@ -421,200 +401,3 @@ fn check_opaque_type_parameter_valid(
421
401
}
422
402
true
423
403
}
424
-
425
- struct ReverseMapper < ' tcx > {
426
- tcx : TyCtxt < ' tcx > ,
427
- map : FxHashMap < GenericArg < ' tcx > , GenericArg < ' tcx > > ,
428
- do_not_error : bool ,
429
-
430
- /// Span of function being checked.
431
- span : Span ,
432
- }
433
-
434
- impl < ' tcx > ReverseMapper < ' tcx > {
435
- fn new (
436
- tcx : TyCtxt < ' tcx > ,
437
- map : FxHashMap < GenericArg < ' tcx > , GenericArg < ' tcx > > ,
438
- span : Span ,
439
- ) -> Self {
440
- Self { tcx, map, do_not_error : false , span }
441
- }
442
-
443
- fn fold_kind_no_missing_regions_error ( & mut self , kind : GenericArg < ' tcx > ) -> GenericArg < ' tcx > {
444
- assert ! ( !self . do_not_error) ;
445
- self . do_not_error = true ;
446
- let kind = kind. fold_with ( self ) ;
447
- self . do_not_error = false ;
448
- kind
449
- }
450
-
451
- fn fold_kind_normally ( & mut self , kind : GenericArg < ' tcx > ) -> GenericArg < ' tcx > {
452
- assert ! ( !self . do_not_error) ;
453
- kind. fold_with ( self )
454
- }
455
- }
456
-
457
- impl < ' tcx > TypeFolder < ' tcx > for ReverseMapper < ' tcx > {
458
- fn tcx ( & self ) -> TyCtxt < ' tcx > {
459
- self . tcx
460
- }
461
-
462
- #[ instrument( skip( self ) , level = "debug" ) ]
463
- fn fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
464
- match * r {
465
- // Ignore bound regions and `'static` regions that appear in the
466
- // type, we only need to remap regions that reference lifetimes
467
- // from the function declaration.
468
- // This would ignore `'r` in a type like `for<'r> fn(&'r u32)`.
469
- ty:: ReLateBound ( ..) | ty:: ReStatic => return r,
470
-
471
- // If regions have been erased (by writeback), don't try to unerase
472
- // them.
473
- ty:: ReErased => return r,
474
-
475
- // The regions that we expect from borrow checking.
476
- ty:: ReEarlyBound ( _) | ty:: ReFree ( _) => { }
477
-
478
- ty:: RePlaceholder ( _) | ty:: ReVar ( _) => {
479
- // All of the regions in the type should either have been
480
- // erased by writeback, or mapped back to named regions by
481
- // borrow checking.
482
- bug ! ( "unexpected region kind in opaque type: {:?}" , r) ;
483
- }
484
- }
485
-
486
- match self . map . get ( & r. into ( ) ) . map ( |k| k. unpack ( ) ) {
487
- Some ( GenericArgKind :: Lifetime ( r1) ) => r1,
488
- Some ( u) => panic ! ( "region mapped to unexpected kind: {:?}" , u) ,
489
- None if self . do_not_error => self . tcx . lifetimes . re_static ,
490
- None => {
491
- self . tcx
492
- . sess
493
- . struct_span_err ( self . span , "non-defining opaque type use in defining scope" )
494
- . span_label (
495
- self . span ,
496
- format ! (
497
- "lifetime `{}` is part of concrete type but not used in \
498
- parameter list of the `impl Trait` type alias",
499
- r
500
- ) ,
501
- )
502
- . emit ( ) ;
503
-
504
- self . tcx ( ) . lifetimes . re_static
505
- }
506
- }
507
- }
508
-
509
- fn fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
510
- match * ty. kind ( ) {
511
- ty:: Closure ( def_id, substs) => {
512
- // I am a horrible monster and I pray for death. When
513
- // we encounter a closure here, it is always a closure
514
- // from within the function that we are currently
515
- // type-checking -- one that is now being encapsulated
516
- // in an opaque type. Ideally, we would
517
- // go through the types/lifetimes that it references
518
- // and treat them just like we would any other type,
519
- // which means we would error out if we find any
520
- // reference to a type/region that is not in the
521
- // "reverse map".
522
- //
523
- // **However,** in the case of closures, there is a
524
- // somewhat subtle (read: hacky) consideration. The
525
- // problem is that our closure types currently include
526
- // all the lifetime parameters declared on the
527
- // enclosing function, even if they are unused by the
528
- // closure itself. We can't readily filter them out,
529
- // so here we replace those values with `'empty`. This
530
- // can't really make a difference to the rest of the
531
- // compiler; those regions are ignored for the
532
- // outlives relation, and hence don't affect trait
533
- // selection or auto traits, and they are erased
534
- // during codegen.
535
-
536
- let generics = self . tcx . generics_of ( def_id) ;
537
- let substs = self . tcx . mk_substs ( substs. iter ( ) . enumerate ( ) . map ( |( index, kind) | {
538
- if index < generics. parent_count {
539
- // Accommodate missing regions in the parent kinds...
540
- self . fold_kind_no_missing_regions_error ( kind)
541
- } else {
542
- // ...but not elsewhere.
543
- self . fold_kind_normally ( kind)
544
- }
545
- } ) ) ;
546
-
547
- self . tcx . mk_closure ( def_id, substs)
548
- }
549
-
550
- ty:: Generator ( def_id, substs, movability) => {
551
- let generics = self . tcx . generics_of ( def_id) ;
552
- let substs = self . tcx . mk_substs ( substs. iter ( ) . enumerate ( ) . map ( |( index, kind) | {
553
- if index < generics. parent_count {
554
- // Accommodate missing regions in the parent kinds...
555
- self . fold_kind_no_missing_regions_error ( kind)
556
- } else {
557
- // ...but not elsewhere.
558
- self . fold_kind_normally ( kind)
559
- }
560
- } ) ) ;
561
-
562
- self . tcx . mk_generator ( def_id, substs, movability)
563
- }
564
-
565
- ty:: Param ( param) => {
566
- // Look it up in the substitution list.
567
- match self . map . get ( & ty. into ( ) ) . map ( |k| k. unpack ( ) ) {
568
- // Found it in the substitution list; replace with the parameter from the
569
- // opaque type.
570
- Some ( GenericArgKind :: Type ( t1) ) => t1,
571
- Some ( u) => panic ! ( "type mapped to unexpected kind: {:?}" , u) ,
572
- None => {
573
- debug ! ( ?param, ?self . map) ;
574
- self . tcx
575
- . sess
576
- . struct_span_err (
577
- self . span ,
578
- & format ! (
579
- "type parameter `{}` is part of concrete type but not \
580
- used in parameter list for the `impl Trait` type alias",
581
- ty
582
- ) ,
583
- )
584
- . emit ( ) ;
585
-
586
- self . tcx ( ) . ty_error ( )
587
- }
588
- }
589
- }
590
-
591
- _ => ty. super_fold_with ( self ) ,
592
- }
593
- }
594
-
595
- fn fold_const ( & mut self , ct : ty:: Const < ' tcx > ) -> ty:: Const < ' tcx > {
596
- trace ! ( "checking const {:?}" , ct) ;
597
- // Find a const parameter
598
- match ct. kind ( ) {
599
- ty:: ConstKind :: Param ( ..) => {
600
- // Look it up in the substitution list.
601
- match self . map . get ( & ct. into ( ) ) . map ( |k| k. unpack ( ) ) {
602
- // Found it in the substitution list, replace with the parameter from the
603
- // opaque type.
604
- Some ( GenericArgKind :: Const ( c1) ) => c1,
605
- Some ( u) => panic ! ( "const mapped to unexpected kind: {:?}" , u) ,
606
- None => {
607
- self . tcx . sess . emit_err ( ConstNotUsedTraitAlias {
608
- ct : ct. to_string ( ) ,
609
- span : self . span ,
610
- } ) ;
611
-
612
- self . tcx ( ) . const_error ( ct. ty ( ) )
613
- }
614
- }
615
- }
616
-
617
- _ => ct,
618
- }
619
- }
620
- }
0 commit comments