@@ -72,14 +72,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
7272
7373 let mut subst_regions = vec ! [ self . universal_regions. fr_static] ;
7474 let universal_substs = infcx. tcx . fold_regions ( substs, |region, _| {
75- if let ty:: RePlaceholder ( ..) = region. kind ( ) {
76- // Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
77- return region;
75+ let ( vid, scc) = match region. kind ( ) {
76+ ty:: ReVar ( vid) => ( vid, self . constraint_sccs . scc ( vid) ) ,
77+ _ => bug ! ( "expected nll var" ) ,
78+ } ;
79+ trace ! ( ?vid, ?scc) ;
80+
81+ // Special handling of higher-ranked regions. These appear in the substs of the
82+ // inner opaque type `impl Sized` in:
83+ // `fn test() -> impl for<'a> Trait<'a, Ty = impl Sized + 'a>`
84+ if self . scc_universes [ scc] != ty:: UniverseIndex :: ROOT {
85+ subst_regions. push ( vid) ;
86+ return self . definitions [ vid]
87+ . external_name ( infcx. tcx )
88+ . expect ( "higher-ranked existential region found in opaque type substs" ) ;
7889 }
79- let vid = self . to_region_vid ( region) ;
80- trace ! ( ?vid) ;
81- let scc = self . constraint_sccs . scc ( vid) ;
82- trace ! ( ?scc) ;
90+
8391 match self . scc_values . universal_regions_outlived_by ( scc) . find_map ( |lb| {
8492 self . eval_equal ( vid, lb) . then_some ( self . definitions [ lb] . external_name ?)
8593 } ) {
@@ -107,9 +115,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
107115 ty:: ReVar ( vid) => subst_regions
108116 . iter ( )
109117 . find ( |ur_vid| self . eval_equal ( vid, * * ur_vid) )
110- . and_then ( |ur_vid| self . definitions [ * ur_vid] . external_name )
118+ . and_then ( |ur_vid| self . definitions [ * ur_vid] . external_name ( infcx . tcx ) )
111119 . unwrap_or ( infcx. tcx . lifetimes . re_root_empty ) ,
112- _ => region ,
120+ _ => bug ! ( "expected nll var" ) ,
113121 } ) ;
114122
115123 debug ! ( ?universal_concrete_type, ?universal_substs) ;
@@ -160,6 +168,25 @@ impl<'tcx> RegionInferenceContext<'tcx> {
160168 {
161169 tcx. fold_regions ( ty, |region, _| match * region {
162170 ty:: ReVar ( vid) => {
171+ let scc = self . constraint_sccs . scc ( vid) ;
172+
173+ // Special handling of higher-ranked regions.
174+ if self . scc_universes [ scc] != ty:: UniverseIndex :: ROOT {
175+ // If the region contains a single placeholder then they're equal.
176+ if let Some ( ( 0 , placeholder) ) =
177+ self . scc_values . placeholders_contained_in ( scc) . enumerate ( ) . last ( )
178+ {
179+ // HACK: we convert named placeholders to free regions for better errors.
180+ // Otherwise, this is incorrect.
181+ if let bound_region @ ty:: BrNamed ( scope, _) = placeholder. name {
182+ return tcx
183+ . mk_region ( ty:: ReFree ( ty:: FreeRegion { scope, bound_region } ) ) ;
184+ }
185+ }
186+ // Fallback: this will produce a cryptic error message.
187+ return region;
188+ }
189+
163190 // Find something that we can name
164191 let upper_bound = self . approx_universal_upper_bound ( vid) ;
165192 let upper_bound = & self . definitions [ upper_bound] ;
@@ -385,7 +412,7 @@ fn check_opaque_type_parameter_valid(
385412 return false ;
386413 }
387414 GenericArgKind :: Lifetime ( lt) => {
388- matches ! ( * lt, ty:: ReEarlyBound ( _) | ty:: ReFree ( _) )
415+ matches ! ( * lt, ty:: ReEarlyBound ( _) | ty:: ReFree ( _) | ty :: RePlaceholder ( _ ) )
389416 }
390417 GenericArgKind :: Const ( ct) => matches ! ( ct. kind( ) , ty:: ConstKind :: Param ( _) ) ,
391418 } ;
@@ -495,9 +522,12 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
495522 ty:: ReErased => return r,
496523
497524 // The regions that we expect from borrow checking.
498- ty:: ReEarlyBound ( _) | ty:: ReFree ( _) | ty:: ReEmpty ( ty:: UniverseIndex :: ROOT ) => { }
525+ ty:: ReEarlyBound ( _)
526+ | ty:: ReFree ( _)
527+ | ty:: RePlaceholder ( _)
528+ | ty:: ReEmpty ( ty:: UniverseIndex :: ROOT ) => { }
499529
500- ty:: ReEmpty ( _) | ty:: RePlaceholder ( _ ) | ty :: ReVar ( _) => {
530+ ty:: ReEmpty ( _) | ty:: ReVar ( _) => {
501531 // All of the regions in the type should either have been
502532 // erased by writeback, or mapped back to named regions by
503533 // borrow checking.
0 commit comments