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

Support Arc<Self> ? #282

Open
arrtchiu opened this issue Aug 28, 2019 · 4 comments
Open

Support Arc<Self> ? #282

arrtchiu opened this issue Aug 28, 2019 · 4 comments
Assignees
Labels
C++ C++ only related issues enhancement
Milestone

Comments

@arrtchiu
Copy link
Contributor

arrtchiu commented Aug 28, 2019

Title of issue #20 suggests this was fixed but I can't seem to get it to work or find it in your test cases :)

foreign_class!(class Foo {
    self_type Foo;
    constructor Foo::new() -> Arc<Foo>;
    fn bar(self: Arc<Self>); // Error: `self` is only valid as the first argument of an associated function
    fn bar2(self: Arc<Foo>); // Error: `self` is only valid as the first argument of an associated function
});
@Dushistov
Copy link
Owner

This should work,
the idea of "constructor return type" and "self_type" is that rust_swig automatically handle constructor type -> self type conversation.

use std::sync::Arc;
pub struct Foo1;
impl Foo1 {
    fn bar(&self) {}
    fn bar2(&self) {}
}

foreign_class!(class Foo1 {
    self_type Foo1;
    constructor Foo1::new() -> Arc<Foo1> {
        Arc::new(Foo1)
    }
    fn Foo1::bar(&self);
    fn Foo1::bar2(&self);
});

@arrtchiu
Copy link
Contributor Author

arrtchiu commented Aug 29, 2019

Sorry I didn't do a very good example. My issue is when I'm trying to have the actual Rust Foo take an Arc<Self> like this:

struct Foo;
impl Foo {
    // this fn needs to be able to copy a strong ref to itself
    fn bar_by_arc(self: Arc<Self>) {}
}

foreign_class!(class Foo {
    // ...
    // none of these work:
    fn Foo::bar_by_arc(&self);
    fn Foo::bar_by_arc(self: Arc<Self>);
});

Obviously one workaround is to do it with a free function:

fn bar_by_arc(foo: Arc<Foo>) {
    // logic that would go inside foo::bar_by_arc in here instead
}

related: https://stackoverflow.com/a/25463033

@arrtchiu
Copy link
Contributor Author

arrtchiu commented Aug 29, 2019

Workaround is a little stranger actually, because on C++ side it wants to consume Foo when you call bar_by_arc:

Foo f;
Foo::bar_by_arc(f); // error: copy ctor is deleted

Instead I return a new Arc<Foo>:

foreign_class!(class Foo {
    fn bar_by_arc(foo: &Arc<Foo>) -> Arc<Foo> {
        // keep a copy for returning
        let ret_foo = Arc::clone(&foo);

        // copy the ref so Foo can work with it
        let foo = Arc::clone(&foo);
        foo.bar_by_arc();

        ret_foo
    }
})

Then on C++ side:

Foo f;
f = Foo::bar_by_arc(std::move(f));
// now i can keep my `f`

@Dushistov Dushistov added C++ C++ only related issues enhancement labels Aug 29, 2019
@Dushistov
Copy link
Owner

  1. Any kind of fn method(self, where self should be passed "by value" is impossible to
    implement for other languages, so I lean to just report error for this during macros parsing.
    This is because none of languages that I know except Rust support such semantic, and foreign_class! is the way to describe how your class will look like for other language.
    So I lean to error reporting instead of automatically convert such code into "static member function"

  2. There is syntax especially for this, but it wasn't implemented for C++, for now it was implemented only for Java, see https://github.com/Dushistov/rust_swig/blob/56601b07c05ac0b2aaf8285212f039939c17ee64/jni_tests/src/java_glue.rs.in#L1001
    If you pass around "class" marked as SmartPtrCopy it will be "copied" (just usage counter will be incremented) instead of "moved".

@Dushistov Dushistov mentioned this issue Aug 29, 2019
7 tasks
@Dushistov Dushistov self-assigned this Sep 2, 2019
@Dushistov Dushistov added this to the 0.5.0 milestone Sep 2, 2019
@Dushistov Dushistov modified the milestones: 0.5.0, 0.6.0 Jun 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C++ C++ only related issues enhancement
Projects
None yet
Development

No branches or pull requests

2 participants