@@ -5,8 +5,7 @@ use rustc_hir::OpaqueTyOrigin;
55use rustc_infer:: infer:: TyCtxtInferExt as _;
66use rustc_infer:: infer:: { DefiningAnchor , InferCtxt } ;
77use 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 } ;
109use rustc_middle:: ty:: visit:: TypeVisitable ;
1110use rustc_middle:: ty:: {
1211 self , OpaqueHiddenType , OpaqueTypeKey , ToPredicate , Ty , TyCtxt , TypeFoldable ,
@@ -15,8 +14,6 @@ use rustc_span::Span;
1514use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt as _;
1615use rustc_trait_selection:: traits:: TraitEngineExt as _;
1716
18- use crate :: session_diagnostics:: ConstNotUsedTraitAlias ;
19-
2017use super :: RegionInferenceContext ;
2118
2219impl < ' tcx > RegionInferenceContext < ' tcx > {
@@ -228,29 +225,9 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
228225 return self . tcx . ty_error ( ) ;
229226 }
230227
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 ;
254231
255232 if !check_opaque_type_parameter_valid (
256233 self . tcx ,
@@ -266,6 +243,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
266243 let OpaqueTyOrigin :: TyAlias = origin else {
267244 return definition_ty;
268245 } ;
246+ let def_id = opaque_type_key. def_id ;
269247 // This logic duplicates most of `check_opaque_meets_bounds`.
270248 // FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely.
271249 let param_env = self . tcx . param_env ( def_id) ;
@@ -281,6 +259,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
281259 . to_predicate ( infcx. tcx ) ;
282260 let mut fulfillment_cx = <dyn TraitEngine < ' tcx > >:: new ( infcx. tcx ) ;
283261
262+ let id_substs = InternalSubsts :: identity_for_item ( self . tcx , def_id. to_def_id ( ) ) ;
263+
284264 // Require that the hidden type actually fulfills all the bounds of the opaque type, even without
285265 // the bounds that the function supplies.
286266 match infcx. register_hidden_type (
@@ -421,200 +401,3 @@ fn check_opaque_type_parameter_valid(
421401 }
422402 true
423403}
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