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