Rollup merge of #126722 - adwinwhite:ptr_fn_abi, r=celinval · rust-lang/rust@1f9793f (original) (raw)
File tree
4 files changed
lines changed
- rustc_smir/src/rustc_smir
- tests/ui-fulldeps/stable-mir
4 files changed
lines changed
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -533,6 +533,13 @@ impl<'tcx> Context for TablesWrapper<'tcx> { | ||
533 | 533 | Ok(tables.fn_abi_of_instance(instance, List::empty())?.stable(&mut *tables)) |
534 | 534 | } |
535 | 535 | |
536 | +fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result<FnAbi, Error> { | |
537 | +let mut tables = self.0.borrow_mut(); | |
538 | +let tcx = tables.tcx; | |
539 | +let sig = fn_ptr.internal(&mut *tables, tcx); | |
540 | +Ok(tables.fn_abi_of_fn_ptr(sig, List::empty())?.stable(&mut *tables)) | |
541 | +} | |
542 | + | |
536 | 543 | fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId { |
537 | 544 | let mut tables = self.0.borrow_mut(); |
538 | 545 | let def_id = tables.instances[def].def_id(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -215,6 +215,9 @@ pub trait Context { | ||
215 | 215 | /// Get an instance ABI. |
216 | 216 | fn instance_abi(&self, def: InstanceDef) -> Result<FnAbi, Error>; |
217 | 217 | |
218 | +/// Get the ABI of a function pointer. | |
219 | + fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result<FnAbi, Error>; | |
220 | + | |
218 | 221 | /// Get the layout of a type. |
219 | 222 | fn ty_layout(&self, ty: Ty) -> Result<Layout, Error>; |
220 | 223 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -2,7 +2,7 @@ use super::{ | ||
2 | 2 | mir::{Body, Mutability, Safety}, |
3 | 3 | with, DefId, Error, Symbol, |
4 | 4 | }; |
5 | -use crate::abi::Layout; | |
5 | +use crate::abi::{FnAbi, Layout}; | |
6 | 6 | use crate::crate_def::{CrateDef, CrateDefType}; |
7 | 7 | use crate::mir::alloc::{read_target_int, read_target_uint, AllocId}; |
8 | 8 | use crate::mir::mono::StaticDef; |
@@ -996,6 +996,16 @@ pub struct AliasTerm { | ||
996 | 996 | |
997 | 997 | pub type PolyFnSig = Binder<FnSig>; |
998 | 998 | |
999 | +impl PolyFnSig { | |
1000 | +/// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers. | |
1001 | + /// | |
1002 | + /// NB: this doesn't handle virtual calls - those should use `Instance::fn_abi` | |
1003 | + /// instead, where the instance is an `InstanceKind::Virtual`. | |
1004 | + pub fn fn_ptr_abi(self) -> Result<FnAbi, Error> { | |
1005 | +with(|cx | |
1006 | +} | |
1007 | +} | |
1008 | + | |
999 | 1009 | #[derive(Clone, Debug, Eq, PartialEq)] |
1000 | 1010 | pub struct FnSig { |
1001 | 1011 | pub inputs_and_output: Vec<Ty>, |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -54,6 +54,21 @@ fn test_stable_mir() -> ControlFlow<()> { | ||
54 | 54 | let variadic_fn = *get_item(&items, (ItemKind::Fn, "variadic_fn")).unwrap(); |
55 | 55 | check_variadic(variadic_fn); |
56 | 56 | |
57 | +// Extract function pointers. | |
58 | +let fn_ptr_holder = *get_item(&items, (ItemKind::Fn, "fn_ptr_holder")).unwrap(); | |
59 | +let fn_ptr_holder_instance = Instance::try_from(fn_ptr_holder).unwrap(); | |
60 | +let body = fn_ptr_holder_instance.body().unwrap(); | |
61 | +let args = body.arg_locals(); | |
62 | + | |
63 | +// Test fn_abi of function pointer version. | |
64 | +let ptr_fn_abi = args[0].ty.kind().fn_sig().unwrap().fn_ptr_abi().unwrap(); | |
65 | +assert_eq!(ptr_fn_abi, fn_abi); | |
66 | + | |
67 | +// Test variadic_fn of function pointer version. | |
68 | +let ptr_variadic_fn_abi = args[1].ty.kind().fn_sig().unwrap().fn_ptr_abi().unwrap(); | |
69 | +assert!(ptr_variadic_fn_abi.c_variadic); | |
70 | +assert_eq!(ptr_variadic_fn_abi.args.len(), 1); | |
71 | + | |
57 | 72 | ControlFlow::Continue(()) |
58 | 73 | } |
59 | 74 | |
@@ -164,6 +179,14 @@ fn generate_input(path: &str) -> std::io::Result<()> { | ||
164 | 179 | pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) -> usize {{ |
165 | 180 | 0 |
166 | 181 | }} |
182 | + | |
183 | + pub type ComplexFn = fn([u8; 0], char, NonZero) -> Result<usize, &'static str>; | |
184 | + pub type VariadicFn = unsafe extern "C" fn(usize, ...) -> usize; | |
185 | + | |
186 | + pub fn fn_ptr_holder(complex_fn: ComplexFn, variadic_fn: VariadicFn) {{ | |
187 | + // We only care about the signature. | |
188 | + todo!() | |
189 | + }} | |
167 | 190 | "# |
168 | 191 | )?; |
169 | 192 | Ok(()) |