Move c-variadic arguments handling into compute_inputs_and_output

This commit is contained in:
tiif 2025-12-28 05:51:01 +00:00
parent 23d01cd241
commit 791fa37df5
2 changed files with 39 additions and 35 deletions

View file

@ -543,38 +543,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
&indices,
);
let (unnormalized_output_ty, mut unnormalized_input_tys) =
let (unnormalized_output_ty, unnormalized_input_tys) =
inputs_and_output.split_last().unwrap();
// C-variadic fns also have a `VaList` input that's not listed in the signature
// (as it's created inside the body itself, not passed in from outside).
if let DefiningTy::FnDef(def_id, _) = defining_ty {
if self.infcx.tcx.fn_sig(def_id).skip_binder().c_variadic() {
let va_list_did = self
.infcx
.tcx
.require_lang_item(LangItem::VaList, self.infcx.tcx.def_span(self.mir_def));
let reg_vid = self
.infcx
.next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || {
RegionCtxt::Free(sym::c_dash_variadic)
})
.as_var();
let region = ty::Region::new_var(self.infcx.tcx, reg_vid);
let va_list_ty = self
.infcx
.tcx
.type_of(va_list_did)
.instantiate(self.infcx.tcx, &[region.into()]);
unnormalized_input_tys = self.infcx.tcx.mk_type_list_from_iter(
unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)),
);
}
}
let fr_fn_body = self
.infcx
.next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || {
@ -816,7 +787,40 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
DefiningTy::FnDef(def_id, _) => {
let sig = tcx.fn_sig(def_id).instantiate_identity();
let sig = indices.fold_to_region_vids(tcx, sig);
sig.inputs_and_output()
let inputs_and_output = sig.inputs_and_output();
// C-variadic fns also have a `VaList` input that's not listed in the signature
// (as it's created inside the body itself, not passed in from outside).
if self.infcx.tcx.fn_sig(def_id).skip_binder().c_variadic() {
let va_list_did = self
.infcx
.tcx
.require_lang_item(LangItem::VaList, self.infcx.tcx.def_span(self.mir_def));
let reg_vid = self
.infcx
.next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || {
RegionCtxt::Free(sym::c_dash_variadic)
})
.as_var();
let region = ty::Region::new_var(self.infcx.tcx, reg_vid);
let va_list_ty = self
.infcx
.tcx
.type_of(va_list_did)
.instantiate(self.infcx.tcx, &[region.into()]);
// The signature needs to follow the order [input_tys, va_list_ty, output_ty]
return inputs_and_output.map_bound(|tys| {
let (output_ty, input_tys) = tys.split_last().unwrap();
tcx.mk_type_list_from_iter(
input_tys.iter().copied().chain([va_list_ty, *output_ty]),
)
});
}
inputs_and_output
}
DefiningTy::Const(def_id, _) => {

View file

@ -30,9 +30,9 @@ error: lifetime may not live long enough
--> $DIR/variadic-ffi-4.rs:22:5
|
LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) {
| ------- ------- has type `VaList<'2>`
| ------- ------- has type `VaList<'1>`
| |
| has type `&mut VaList<'1>`
| has type `&mut VaList<'2>`
LL | ap0 = &mut ap1;
| ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
|
@ -44,9 +44,9 @@ error: lifetime may not live long enough
--> $DIR/variadic-ffi-4.rs:22:5
|
LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) {
| ------- ------- has type `VaList<'2>`
| ------- ------- has type `VaList<'1>`
| |
| has type `&mut VaList<'1>`
| has type `&mut VaList<'2>`
LL | ap0 = &mut ap1;
| ^^^^^^^^^^^^^^ assignment requires that `'2` must outlive `'1`
|