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(()) |