{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreif3d6gb6bvjgklqexamqhdatnzmszq3kt6wbcdtktaf6mp3dprwuq",
    "uri": "at://did:plc:ivbknywyskln22er3nkssdhl/app.bsky.feed.post/3meu2cehcj7o2"
  },
  "path": "/t/pre-pre-rfc-splatting-for-named-arguments-and-function-overloading/24012#post_1",
  "publishedAt": "2026-02-14T21:04:30.000Z",
  "site": "https://internals.rust-lang.org",
  "tags": [
    "on Zulip",
    "`std::marker::Tuple`",
    "Struct sugar",
    "Pre-RFC v2 - Static Function Argument Unpacking",
    "Pre-RFC v2 - Static Function Argument Unpacking"
  ],
  "textContent": "> While discussing C++ overloading on Zulip, a bunch of us (re?)discovered a pretty cute idea, which I'm taking the liberty to flesh out here.\n\nThis RFC comes from the realization that \"we have named arguments at home\" and \"we have function overloading at home\":\n\n  * Named arguments at home:\n\n\n\n\n    struct MethodArgs {\n        a: u32,\n        b: Option<String> = None, // note the default field value here\n        c: bool,\n    }\n    impl Bar {\n        fn method(&self, args: MethodArgs) { /* whatever */ }\n    }\n\n    bar.method(MethodArgs { a: 42, c: true, .. }); // using the `..` default field value syntax\n\n\n  * Function overloading at home:\n\n\n\n\n    trait MethodArgs: std::marker::Tuple {\n        fn call_method(self, this: &Foo);\n    }\n    impl MethodArgs for (i32, String) {\n        fn call_method(self, this: &Foo) { /* actual code */ }\n    }\n    impl MethodArgs for (i32,) {\n        fn call_method(self, this: &Foo) { /* actual code */ }\n    }\n\n    impl Foo {\n        fn method(&self, args: impl MethodArgs) { args.call_method(self) }\n    }\n\n    foo.method((42,));\n    foo.method((42, \"asdf\".to_owned()));\n\n\n## Proposed feature\n\nThis RFC proposes a `..` syntax when declaring function arguments, which we can apply to our examples above as follows:\n\n\n    impl Bar {\n        fn method(&self, ..args: MethodArgs) { ... }\n    }\n\n    bar.method(a: 42, c: true, ..);\n\n    impl Foo {\n        fn method(&self, ..args: impl MethodArgs) { args.call_method(self) }\n    }\n\n    foo.method(42);\n    foo.method(42, \"asdf\".to_owned());\n\n\nThe syntax is `..ident: Type` in function arguments, and is called \"splatting\". It is only allowed on the last argument of a function. It is allowed if `Type` is a struct or if it implements `std::marker::Tuple`. This then changes the call syntax of the function.\n\n### Struct case\n\n\n    struct Args { /* whatever */ }\n    fn foo(x: T, y: U, ..args: Args) { /* whatever */ }\n\n    foo(<expr1>, <expr2>, x: <expr3>, y: <expr4>)\n    // actually means, in the normal call syntax:\n    foo(<expr1>, <expr2>, Args { x: <expr3>, y: <expr4> })\n\n    foo(<expr1>, <expr2>, x: <expr3>, y: <expr4>, ..)\n    // actually means, in the normal call syntax:\n    foo(<expr1>, <expr2>, Args { x: <expr3>, y: <expr4>, .. })\n\n\n### Tuple case\n\n\n    trait FooArgs: Tuple { /* whatever */ }\n    fn foo(x: T, y: U, ..args: impl FooArgs) { /* whatever */ }\n\n    foo(<expr1>, <expr2>)\n    // actually means, in the normal call syntax:\n    foo(<expr1>, <expr2>, ())\n\n    foo(<expr1>, <expr2>, <expr3>)\n    // actually means, in the normal call syntax:\n    foo(<expr1>, <expr2>, (<expr3>,))\n\n    foo(<expr1>, <expr2>, <expr3>, <expr4>)\n    // actually means, in the normal call syntax:\n    foo(<expr1>, <expr2>, (<expr3>, <expr4>))\n\n\n## Related work\n\nThere are a large number of named arguments proposals on this forum. The one that looks closest to this one is Struct sugar .This is also quite related to Pre-RFC v2 - Static Function Argument Unpacking . Haven't looked into function overloading.\n\n## Possible extension\n\nI propose that, if a function uses splatting, then `foo(<expr1>, <expr2>, ..<expr3>)` is allowed if `expr3` has exactly the expected type, and skips the splatting. E.g. with my two running examples above, we could also write this:\n\n\n    let args = MethodArgs { a: 42, c: true, .. };\n    bar.method(..args); // passes the struct directly\n\n    let args = (42, \"asdf\".to_owned());\n    foo.method(..args); // passes the tuple directly\n\n\nI do not propose that this syntax should be allowed on functions that don't use splatting, but I know such a thing has been proposed before (e.g. Pre-RFC v2 - Static Function Argument Unpacking).\n\n> Actually `..expr` is already a half-open range. We should probably use `...` instead...",
  "title": "[Pre-pre-RFC] \"splatting\" for named arguments and function overloading"
}