Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix proc-macro constructor support and document it #1520

Merged
merged 2 commits into from
Apr 27, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
20 changes: 18 additions & 2 deletions docs/manual/src/proc_macro/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,28 @@ struct MyObject {

#[uniffi::export]
impl MyObject {
// All methods must have a `self` argument
// Constructors need to be annotated as such.
// As of right now, they must return `Arc<Self>`, this might change.
// If the constructor is named `new`, it is treated as the primary
// constructor, so in most languages this is invoked with `MyObject()`.
#[uniffi::constructor]
fn new(argument: String) -> Arc<Self> {
// ...
}

// Constructors with different names are also supported, usually invoked
// as `MyObject.named()` (depending on the target language)
#[uniffi::constructor]
fn named() -> Arc<Self> {
// ...
}

// All functions that are not constructors must have a `self` argument
fn method_a(&self) {
// ...
}

// Arc<Self> is also supported
// `Arc<Self>` is also supported
fn method_b(self: Arc<Self>) {
// ...
}
Expand Down
10 changes: 8 additions & 2 deletions fixtures/proc-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,14 @@ pub struct Object;
#[uniffi::export]
impl Object {
#[uniffi::constructor]
fn new() -> Arc<Object> {
Arc::new(Object)
fn new() -> Arc<Self> {
Arc::new(Self)
}

#[uniffi::constructor]
fn named_ctor(arg: u32) -> Arc<Self> {
_ = arg;
Self::new()
}

fn is_heavy(&self) -> MaybeBool {
Expand Down
3 changes: 2 additions & 1 deletion fixtures/proc-macro/tests/bindings/test_proc_macro.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ assert(one.inner == 123)
val two = Two("a", null)
assert(takeTwo(two) == "a")

val obj = Object()
var obj = Object()
obj = Object.namedCtor(1u)
assert(obj.isHeavy() == MaybeBool.UNCERTAIN)

assert(enumIdentity(MaybeBool.TRUE) == MaybeBool.TRUE)
Expand Down
1 change: 1 addition & 0 deletions fixtures/proc-macro/tests/bindings/test_proc_macro.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
assert take_two(two) == "a"

obj = Object()
obj = Object.named_ctor(1)
assert obj.is_heavy() == MaybeBool.UNCERTAIN

assert enum_identity(MaybeBool.TRUE) == MaybeBool.TRUE
Expand Down
3 changes: 2 additions & 1 deletion fixtures/proc-macro/tests/bindings/test_proc_macro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ assert(one.inner == 123)
let two = Two(a: "a", b: nil)
assert(takeTwo(two: two) == "a")

let obj = Object()
var obj = Object()
obj = Object.namedCtor(arg: 1)
assert(obj.isHeavy() == .uncertain)

assert(enumIdentity(value: .true) == .true)
Expand Down
2 changes: 1 addition & 1 deletion uniffi_macros/src/export/scaffolding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub(super) fn gen_constructor_scaffolding(
const RECEIVER_ERROR: &str = "constructors must not have a self parameter";

let mut bits = ScaffoldingBits::new();
bits.collect_params(sig.inputs.iter().skip(1), RECEIVER_ERROR);
bits.collect_params(&sig.inputs, RECEIVER_ERROR);
bits.set_rust_fn_call(quote! { #self_ident::#ident });

let metadata_var = bits.gen_constructor_meta_static_var(self_ident, &sig, mod_path);
Expand Down