@@ -2,12 +2,10 @@ use rustc_data_structures::fx::FxHashMap;
22use rustc_data_structures:: vec_map:: VecMap ;
33use rustc_hir:: def_id:: LocalDefId ;
44use rustc_hir:: OpaqueTyOrigin ;
5- use rustc_infer:: infer:: error_reporting:: unexpected_hidden_region_diagnostic;
65use rustc_infer:: infer:: TyCtxtInferExt as _;
76use rustc_infer:: infer:: { DefiningAnchor , InferCtxt } ;
87use 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 } ;
119use rustc_middle:: ty:: visit:: TypeVisitable ;
1210use rustc_middle:: ty:: {
1311 self , OpaqueHiddenType , OpaqueTypeKey , ToPredicate , Ty , TyCtxt , TypeFoldable ,
@@ -16,8 +14,6 @@ use rustc_span::Span;
1614use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt as _;
1715use rustc_trait_selection:: traits:: TraitEngineExt as _;
1816
19- use crate :: session_diagnostics:: ConstNotUsedTraitAlias ;
20-
2117use super :: RegionInferenceContext ;
2218
2319impl < ' tcx > RegionInferenceContext < ' tcx > {
@@ -229,31 +225,9 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
229225 return self . tcx . ty_error ( ) ;
230226 }
231227
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 ;
257231
258232 if !check_opaque_type_parameter_valid (
259233 self . tcx ,
@@ -269,6 +243,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
269243 let OpaqueTyOrigin :: TyAlias = origin else {
270244 return definition_ty;
271245 } ;
246+ let def_id = opaque_type_key. def_id ;
272247 // This logic duplicates most of `check_opaque_meets_bounds`.
273248 // FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely.
274249 let param_env = self . tcx . param_env ( def_id) ;
@@ -284,6 +259,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
284259 . to_predicate ( infcx. tcx ) ;
285260 let mut fulfillment_cx = <dyn TraitEngine < ' tcx > >:: new ( infcx. tcx ) ;
286261
262+ let id_substs = InternalSubsts :: identity_for_item ( self . tcx , def_id. to_def_id ( ) ) ;
263+
287264 // Require that the hidden type actually fulfills all the bounds of the opaque type, even without
288265 // the bounds that the function supplies.
289266 match infcx. register_hidden_type (
@@ -424,221 +401,3 @@ fn check_opaque_type_parameter_valid(
424401 }
425402 true
426403}
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