Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions crates/libs/rdl/rdl.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,33 @@ mod Contoso {
}
```

**Method Overloads (WinRT):**

WinRT interfaces may contain overloaded methods — multiple methods that share a logical name but have unique WINMD names. The `#[overload("Name")]` pseudo-attribute records the shared logical name (the value of `Windows.Foundation.Metadata.OverloadAttribute` in the binary metadata), while the actual method name is the unique identifier used in the vtable.

**Syntax:**

```rust
#[overload("LogicalName")]
fn UniqueName(&self, ...) -> ReturnType;
```

**Example:**

```rust
#[winrt]
mod Contoso {
mod Sprockets {
interface ISprocketFactory {
#[overload("Create")]
fn CreateDefault(&self) -> Sprocket;
#[overload("Create")]
fn CreateWithOptions(&self, options: SprocketOptions) -> Sprocket;
}
}
}
```

---

#### Delegates
Expand Down
20 changes: 20 additions & 0 deletions crates/libs/rdl/src/reader/attribute_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,26 @@ impl Encoder<'_> {
continue;
}

// `#[overload("Name")]` is a pseudo-attribute that maps to the WinRT metadata
// `Windows.Foundation.Metadata.OverloadAttribute`.
if path.is_ident("overload") {
let name: syn::LitStr = attr.parse_args().map_err(|_| {
self.error(
attr,
"`#[overload]` requires a single string literal argument",
)
})?;
let attr_ref = AttributeRef {
type_name: metadata::TypeName::named(
"Windows.Foundation.Metadata",
"OverloadAttribute",
),
args: vec![("".to_string(), metadata::Value::Utf8(name.value()))],
};
self.encode_named_attribute(has_attribute, &attr_ref);
continue;
}

let attr_ref = self.resolve_attribute_ref(attr)?;
self.encode_named_attribute(has_attribute, &attr_ref);
}
Expand Down
9 changes: 9 additions & 0 deletions crates/libs/rdl/src/writer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,15 @@ fn write_custom_attributes_except<'a>(
return Ok(quote! { #[typedef] });
}

// `OverloadAttribute` is written back as the `#[overload("Name")]` pseudo-attribute.
if attr.namespace() == "Windows.Foundation.Metadata"
&& attr.name() == "OverloadAttribute"
{
if let Some((_, metadata::Value::Utf8(name))) = attr.value().first() {
return Ok(quote! { #[overload(#name)] });
}
}

let attr_ns = attr.namespace();
let attr_short = attr
.name()
Expand Down
13 changes: 13 additions & 0 deletions crates/tests/libs/rdl/tests/roundtrip/overload-method.rdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#[winrt]
mod Test {
interface IFoo {
#[overload("Method")]
fn MethodOne(&self) -> i32;
#[overload("Method")]
fn MethodTwo(&self, a: i32) -> i32;
#[overload("Other")]
fn OtherVariantA(&self, x: f32, y: f32) -> bool;
#[overload("Other")]
fn OtherVariantB(&self, x: f32, y: f32, z: f32) -> bool;
Comment on lines +4 to +11
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot this .rdl looks right but the .winmd representation is such that the MethodDef name stores the common name while the attribute stores the unique name. So keep this .rdl representation but make sure the metadata is actually encoded correctly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 912ca1a. The WINMD encoding is now correct:

  • MethodDef.Name = common/logical name (e.g. "Method") — taken from the #[overload("...")] arg
  • OverloadAttribute.value = unique vtable name (e.g. "MethodOne") — taken from the fn identifier

Added overload_encoding.rs which directly reads the produced WINMD and asserts this layout.

}
}
Loading