autocxx
autocxx copied to clipboard
Overloaded function renaming might cause conflicts
Describe the bug
Overloaded function renaming might cause conflicts
To Reproduce
See https://github.com/google/autocxx/pull/1317
I have a class:
class Image {
public:
static uint64_t byteSwap(uint64_t value, bool bSwap);
static uint32_t byteSwap(uint32_t value, bool bSwap);
static uint16_t byteSwap(uint16_t value, bool bSwap);
static uint16_t byteSwap2(const DataBuf& buf, size_t offset, bool bSwap);
};
calling generate!
on it will cause byteSwap2
to be generated twice. One for the overload, one for the actual byteSwap2.
pub unsafe fn byteSwap(value: u64, bSwap: bool) -> u64 { }
pub unsafe fn byteSwap1(value: u32, bSwap: bool) -> u32 { }
pub unsafe fn byteSwap2(value: u16, bSwap: bool) -> u16 { }
pub unsafe fn byteSwap2(buf: &root::Exiv2::DataBuf,
offset: usize,
bSwap: bool,
) -> u16 {}
This is because the renaming of the return u16 overload is byteSwap2
and there is an actual byteSwap2
function.
Expected behavior
Find a better renaming.
Or throw an error from the macro
Additional context
Yeah, this isn't great and as the manual says, this all needs to be overhauled a bit. Meanwhile though I do certainly consider this a bug, and I'd accept a pull request for a temporary solution, e.g. if SomeOverloadedFunction2
already exists, then use a different suffix such as SomeOverloadedFunction_autocxx_overload2
. I'm unlikely to get a chance to do this any time soon, but this might be a fairly easy fix so I'm going to mark it as Good First Issue in case someone else can help out.
Closely related to #995
Just sharing some random thoughts on overloaded functions. Would the following options be better?
-
Generate macros for the overloaded functions?
A potential problem I can see is overloads that have the same number of args but the args are of different types, like the three
byteSwap
functions mentioned above. -
Generate trait for the overloaded functions?
What I am picturing is something like below. I guess a potential problem would be generating multiple traits of the same name.
struct Image;
pub trait ByteSwap<Args> {
type Output;
fn byte_swap(args: Args) -> Self::Output;
}
impl ByteSwap<(u64, bool)> for Image {
type Output = u64;
fn byte_swap(args: (u64, bool)) -> u64 { todo!() }
}
impl ByteSwap<(u32, bool)> for Image {
type Output = u32;
fn byte_swap(args: (u32, bool)) -> u32 { todo!() }
}
impl ByteSwap<(u16, bool)> for Image {
type Output = u16;
fn byte_swap(args: (u16, bool)) -> u16 { todo!() }
}
Or generate a trait for the args so that the trait doesn't need to be public
mod ffi {
pub struct Image;
impl Image {
fn byte_swap<Args: ByteSwapArgs<Image>>(args: Args) -> Args::Output {
ByteSwapArgs::<Image>::perform_byte_swap(args)
}
}
trait ByteSwapArgs<T> {
type Output;
fn perform_byte_swap(self) -> Self::Output;
}
impl ByteSwapArgs<Image> for (u64, bool) {
type Output = u64;
fn perform_byte_swap(self) -> u64 { todo!() }
}
impl ByteSwapArgs<Image> for (u32, bool) {
type Output = u32;
fn perform_byte_swap(self) -> u32 { todo!() }
}
impl ByteSwapArgs<Image> for (u16, bool) {
type Output = u16;
fn perform_byte_swap(self) -> u16 { todo!() }
}
}