@@ -26,8 +26,8 @@ use rustc_macros::extension;
2626use rustc_middle:: mir:: RETURN_PLACE ;
2727use rustc_middle:: ty:: print:: with_no_trimmed_paths;
2828use rustc_middle:: ty:: {
29- self , GenericArgs , GenericArgsRef , InlineConstArgs , InlineConstArgsParts , RegionExt , RegionVid ,
30- Ty , TyCtxt , TypeFoldable , TypeVisitableExt , fold_regions,
29+ self , BoundVariableKind , GenericArgs , GenericArgsRef , InlineConstArgs , InlineConstArgsParts ,
30+ List , RegionExt , RegionVid , Ty , TyCtxt , TypeFoldable , TypeVisitableExt , fold_regions,
3131} ;
3232use rustc_middle:: { bug, span_bug} ;
3333use rustc_span:: { ErrorGuaranteed , kw, sym} ;
@@ -183,21 +183,52 @@ impl<'tcx> DefiningTy<'tcx> {
183183 }
184184 }
185185
186- #[ instrument( level = "debug" , skip( tcx, c_variadic_region) , ret) ]
187- fn inputs_and_output (
188- self ,
189- tcx : TyCtxt < ' tcx > ,
190- c_variadic_region : impl FnOnce ( ) -> ty:: Region < ' tcx > ,
191- ) -> ty:: Binder < ' tcx , & ' tcx ty:: List < Ty < ' tcx > > > {
186+ /// The bound variables for a given defining type. This differs from their usual bound vars
187+ /// in that closures and coroutine closures have an additional `'env`, while C-variadic
188+ /// functions have an additional region for their implicit `VaList` input.
189+ pub ( crate ) fn bound_vars ( self , tcx : TyCtxt < ' tcx > ) -> & ' tcx List < BoundVariableKind < ' tcx > > {
190+ match self {
191+ DefiningTy :: Closure ( _, args) => {
192+ let closure_sig = args. as_closure ( ) . sig ( ) ;
193+ let inputs_and_output = closure_sig. inputs_and_output ( ) ;
194+ tcx. mk_bound_variable_kinds_from_iter ( inputs_and_output. bound_vars ( ) . iter ( ) . chain (
195+ iter:: once ( ty:: BoundVariableKind :: Region ( ty:: BoundRegionKind :: ClosureEnv ) ) ,
196+ ) )
197+ }
198+
199+ DefiningTy :: CoroutineClosure ( _, args) => {
200+ let closure_sig = args. as_coroutine_closure ( ) . coroutine_closure_sig ( ) ;
201+ tcx. mk_bound_variable_kinds_from_iter ( closure_sig. bound_vars ( ) . iter ( ) . chain (
202+ iter:: once ( ty:: BoundVariableKind :: Region ( ty:: BoundRegionKind :: ClosureEnv ) ) ,
203+ ) )
204+ }
205+
206+ DefiningTy :: FnDef ( def_id, _) => {
207+ let sig = tcx. fn_sig ( def_id) . instantiate_identity ( ) . skip_norm_wip ( ) ;
208+ if sig. skip_binder ( ) . c_variadic ( ) {
209+ // FIXME(#160495): Don't use an anonymous region here
210+ tcx. mk_bound_variable_kinds_from_iter ( sig. bound_vars ( ) . iter ( ) . chain (
211+ iter:: once ( ty:: BoundVariableKind :: Region ( ty:: BoundRegionKind :: Anon ) ) ,
212+ ) )
213+ } else {
214+ sig. bound_vars ( )
215+ }
216+ }
217+
218+ DefiningTy :: Coroutine ( ..)
219+ | DefiningTy :: Const ( ..)
220+ | DefiningTy :: InlineConst ( ..)
221+ | DefiningTy :: GlobalAsm ( ..) => ty:: List :: empty ( ) ,
222+ }
223+ }
224+
225+ #[ instrument( level = "debug" , skip( tcx) , ret) ]
226+ fn inputs_and_output ( self , tcx : TyCtxt < ' tcx > ) -> ty:: Binder < ' tcx , & ' tcx ty:: List < Ty < ' tcx > > > {
192227 match self {
193228 DefiningTy :: Closure ( def_id, args) => {
194229 let closure_sig = args. as_closure ( ) . sig ( ) ;
195230 let inputs_and_output = closure_sig. inputs_and_output ( ) ;
196- let bound_vars = tcx. mk_bound_variable_kinds_from_iter (
197- inputs_and_output. bound_vars ( ) . iter ( ) . chain ( iter:: once (
198- ty:: BoundVariableKind :: Region ( ty:: BoundRegionKind :: ClosureEnv ) ,
199- ) ) ,
200- ) ;
231+ let bound_vars = self . bound_vars ( tcx) ;
201232 let br = ty:: BoundRegion {
202233 var : ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) ,
203234 kind : ty:: BoundRegionKind :: ClosureEnv ,
@@ -245,10 +276,7 @@ impl<'tcx> DefiningTy<'tcx> {
245276 // Then we wrap it all up into a list of inputs and output.
246277 DefiningTy :: CoroutineClosure ( def_id, args) => {
247278 let closure_sig = args. as_coroutine_closure ( ) . coroutine_closure_sig ( ) ;
248- let bound_vars =
249- tcx. mk_bound_variable_kinds_from_iter ( closure_sig. bound_vars ( ) . iter ( ) . chain (
250- iter:: once ( ty:: BoundVariableKind :: Region ( ty:: BoundRegionKind :: ClosureEnv ) ) ,
251- ) ) ;
279+ let bound_vars = self . bound_vars ( tcx) ;
252280 let br = ty:: BoundRegion {
253281 var : ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) ,
254282 kind : ty:: BoundRegionKind :: ClosureEnv ,
@@ -290,17 +318,24 @@ impl<'tcx> DefiningTy<'tcx> {
290318 if tcx. fn_sig ( def_id) . skip_binder ( ) . c_variadic ( ) {
291319 let va_list_did = tcx. require_lang_item ( LangItem :: VaList , tcx. def_span ( def_id) ) ;
292320
293- let region = c_variadic_region ( ) ;
321+ let bound_vars = self . bound_vars ( tcx) ;
322+ let br = ty:: BoundRegion {
323+ var : ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) ,
324+ kind : ty:: BoundRegionKind :: Anon ,
325+ } ;
326+ let region = ty:: Region :: new_bound ( tcx, ty:: INNERMOST , br) ;
294327 let va_list_ty =
295328 tcx. type_of ( va_list_did) . instantiate ( tcx, & [ region. into ( ) ] ) . skip_norm_wip ( ) ;
296329
297330 // The signature needs to follow the order [input_tys, va_list_ty, output_ty]
298- return inputs_and_output. map_bound ( |tys| {
299- let ( output_ty, input_tys) = tys. split_last ( ) . unwrap ( ) ;
331+ let ( output_ty, input_tys) =
332+ inputs_and_output. skip_binder ( ) . split_last ( ) . unwrap ( ) ;
333+ return ty:: Binder :: bind_with_vars (
300334 tcx. mk_type_list_from_iter (
301335 input_tys. iter ( ) . copied ( ) . chain ( [ va_list_ty, * output_ty] ) ,
302- )
303- } ) ;
336+ ) ,
337+ bound_vars,
338+ ) ;
304339 }
305340
306341 inputs_and_output
@@ -678,7 +713,9 @@ impl<'tcx> UniversalRegionsBuilder<'_, 'tcx> {
678713 } else {
679714 // If this is a closure, coroutine, or inline-const, then the late-bound regions from the enclosing
680715 // function/closures are actually external regions to us. For example, here, 'a is not local
681- // to the closure c (although it is local to the fn foo):
716+ // to the closure c (although it is local to the fn foo). We need to add them as they could be
717+ // explicitly named in this body:
718+ //
682719 // fn foo<'a>() {
683720 // let c = || { let x: &'a u32 = ...; }
684721 // }
@@ -708,8 +745,9 @@ impl<'tcx> UniversalRegionsBuilder<'_, 'tcx> {
708745 // on its signature are local.
709746 //
710747 // We manually loop over `bound_inputs_and_output` instead of using
711- // `for_each_late_bound_region_in_item` as we may need to add the otherwise
712- // implicit `ClosureEnv` region.
748+ // `for_each_late_bound_region_in_item` as both closures and function
749+ // definitions have implicit late bound regions. Closures have a `'env`
750+ // regions while c-variadic function definitions have a `&VaList` argument.
713751 let bound_inputs_and_output = self . compute_inputs_and_output ( & indices, defining_ty) ;
714752 for ( idx, bound_var) in bound_inputs_and_output. bound_vars ( ) . iter ( ) . enumerate ( ) {
715753 if let ty:: BoundVariableKind :: Region ( kind) = bound_var {
@@ -825,12 +863,7 @@ impl<'tcx> UniversalRegionsBuilder<'_, 'tcx> {
825863 defining_ty : DefiningTy < ' tcx > ,
826864 ) -> ty:: Binder < ' tcx , & ' tcx ty:: List < Ty < ' tcx > > > {
827865 let tcx = self . infcx . tcx ;
828- let inputs_and_output = defining_ty. inputs_and_output ( tcx, || {
829- self . infcx . next_nll_region_var ( NllRegionVariableOrigin :: FreeRegion , || {
830- RegionCtxt :: Free ( sym:: c_dash_variadic)
831- } )
832- } ) ;
833-
866+ let inputs_and_output = defining_ty. inputs_and_output ( tcx) ;
834867 let inputs_and_output = indices. fold_to_region_vids ( tcx, inputs_and_output) ;
835868
836869 // FIXME(#129952): We probably want a more principled approach here.
0 commit comments