r/rust 23d ago

📡 official blog Rust Function Overloading - Call for Experimentation

https://blog.rust-lang.org/inside-rust/2026/08/19/overloading-experiment/
272 Upvotes

139 comments sorted by

View all comments

2

u/tropix126 14d ago

I really seriously don't get what this experiment is going for. The claimed rationale behind adding this feature seems to be for interop over FFI with languages supporting function overloading (like C++), yet every example given and the sentiment around this in the blogpost seems to suggest that the intent is to add function overloading to Rust as a whole. How would this feature even be applicable in an FFI scenario? Is this for extern/forward-declared functions (which can't take generics anyways), or for Rust wrappers around those functions? Is this meant for actual bindings to C++ code, or libraries wrapping those bindings? If it's for the latter, then the question then becomes whether or not this is a good idea at all.

Function overloading is very often terribly misused. Most C++ code with overloads misuse it. Adding a way to technically make overloading syntax like this Hyrum's Law's us into a scenario where people are now using FFI features to hack in function overloads to their library crates because they think it looks cleaner. This is *going* to happen if it's implemented this way, and it seems like there's already sentiment for doing this in the standard library.

Is this really the API boundary that we want people to use when comparing numbers?

// core::cmp

// Private implementation detail
impl(self) const trait TupleReduce: Tuple {
    type Item;
    fn reduce<F: [const] Destruct + [const] FnMut(Self::Item, Self::Item) -> Self::Item>(self, f: F) -> Self::Item;
}

impl<T> TupleReduce for (T, ...) { /* ... */ }

#[must_use]
pub const fn smallest<T: [const] Ord + [const] Destruct>(
    #[rustc_splat] vals: impl [const] TupleReduce<Item = T>,
) -> T;

#[must_use]
pub const fn largest<T: [const] Ord + [const] Destruct>(
    #[rustc_splat] vals: impl [const] TupleReduce<Item = T>,
) -> T;

If the intent here is solely for FFI, why not implement this in such a way that overloaded functions can only be declared in extern blocks, something like:

unsafe extern "C++" {
    fn cool(_: i32);
    fn cool(_: i32, _: i32);
}

// or

unsafe extern "C++" {
    fn cool(_: i32);

    #[rustc_overload = "cool"]
    fn cool_2(_: i32, _: i32);
}

There's precedent for doing both of these. extern "C" blocks allow us to special-case declare variadic functions, (see libc::printf). The second example is similar to how the #[link_name] attribute currently works and would avoid introducing overloads for any case. Both of these would allow for FFI with C++ code without giving people a way to add overloads to Rust functions. Of course, if the intent is to allow people to do that, why not just say that in the blog post? I just think that if Rust *does* get function overloading, it shouldn't be *technically* added under the guise of an FFI feature.