@@ -72,14 +72,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
72
72
73
73
let mut subst_regions = vec ! [ self . universal_regions. fr_static] ;
74
74
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" ) ;
78
89
}
79
- let vid = self . to_region_vid ( region) ;
80
- trace ! ( ?vid) ;
81
- let scc = self . constraint_sccs . scc ( vid) ;
82
- trace ! ( ?scc) ;
90
+
83
91
match self . scc_values . universal_regions_outlived_by ( scc) . find_map ( |lb| {
84
92
self . eval_equal ( vid, lb) . then_some ( self . definitions [ lb] . external_name ?)
85
93
} ) {
@@ -107,9 +115,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
107
115
ty:: ReVar ( vid) => subst_regions
108
116
. iter ( )
109
117
. 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 ) )
111
119
. unwrap_or ( infcx. tcx . lifetimes . re_root_empty ) ,
112
- _ => region ,
120
+ _ => bug ! ( "expected nll var" ) ,
113
121
} ) ;
114
122
115
123
debug ! ( ?universal_concrete_type, ?universal_substs) ;
@@ -160,6 +168,25 @@ impl<'tcx> RegionInferenceContext<'tcx> {
160
168
{
161
169
tcx. fold_regions ( ty, |region, _| match * region {
162
170
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
+
163
190
// Find something that we can name
164
191
let upper_bound = self . approx_universal_upper_bound ( vid) ;
165
192
let upper_bound = & self . definitions [ upper_bound] ;
@@ -385,7 +412,7 @@ fn check_opaque_type_parameter_valid(
385
412
return false ;
386
413
}
387
414
GenericArgKind :: Lifetime ( lt) => {
388
- matches ! ( * lt, ty:: ReEarlyBound ( _) | ty:: ReFree ( _) )
415
+ matches ! ( * lt, ty:: ReEarlyBound ( _) | ty:: ReFree ( _) | ty :: RePlaceholder ( _ ) )
389
416
}
390
417
GenericArgKind :: Const ( ct) => matches ! ( ct. kind( ) , ty:: ConstKind :: Param ( _) ) ,
391
418
} ;
@@ -495,9 +522,12 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
495
522
ty:: ReErased => return r,
496
523
497
524
// 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 ) => { }
499
529
500
- ty:: ReEmpty ( _) | ty:: RePlaceholder ( _ ) | ty :: ReVar ( _) => {
530
+ ty:: ReEmpty ( _) | ty:: ReVar ( _) => {
501
531
// All of the regions in the type should either have been
502
532
// erased by writeback, or mapped back to named regions by
503
533
// borrow checking.
0 commit comments