Skip to content

#[no_mangle] on associated functions #1837

New issue

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

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

Already on GitHub? # to your account

Closed
ghost opened this issue Jun 15, 2021 · 2 comments · Fixed by #1871
Closed

#[no_mangle] on associated functions #1837

ghost opened this issue Jun 15, 2021 · 2 comments · Fixed by #1871

Comments

@ghost
Copy link

ghost commented Jun 15, 2021

This program works with rustc, but not in Miri (playground):

struct AssocFn;

impl AssocFn {
    #[no_mangle]
    fn foo() {}
}

fn main() {
    extern "Rust" {
        fn foo();
    }
    AssocFn::foo();
    unsafe { foo() }
}

(And unlike #[no_mangle] on normal functions, if AsocFn::foo is not used directly, it also does not work with rustc: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=f1244afcdd26e2a28445f6e82ca46b50.)

cc #1833 (comment)

@RalfJung
Copy link
Member

(And unlike #[no_mangle] on normal functions, if AsocFn::foo is not used directly, it also does not work with rustc: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=f1244afcdd26e2a28445f6e82ca46b50.)

That sounds like a rustc bug?

@ghost
Copy link
Author

ghost commented Jun 20, 2021

rust-lang/rust#76211 looks related. I have a patch that fixes my playground example above and non-public associated functions in rlib crates for rustc. I haven't tested it for Miri and the rustc issue yet.

bors added a commit to rust-lang-ci/rust that referenced this issue Aug 13, 2021
Associated functions that contain extern indicator or have `#[rustc_std_internal_symbol]` are reachable

Previously these fails to link with ``undefined reference to `foo'``:

<details>
<summary>Example 1</summary>

```rs
struct AssocFn;

impl AssocFn {
    #[no_mangle]
    fn foo() {}
}

fn main() {
    extern "Rust" {
        fn foo();
    }
    unsafe { foo() }
}
```
([Playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=f1244afcdd26e2a28445f6e82ca46b50))
</details>

<details>
<summary>Example 2</summary>

```rs
#![crate_name = "lib"]
#![crate_type = "lib"]

struct AssocFn;

impl AssocFn {
    #[no_mangle]
    fn foo() {}
}
```
```rs
extern crate lib;

fn main() {
    extern "Rust" {
        fn foo();
    }
    unsafe { foo() }
}
```
</details>

But I believe they should link successfully, because this works:
<details>

```rs
#[no_mangle]
fn foo() {}

fn main() {
    extern "Rust" {
        fn foo();
    }
    unsafe { foo() }
}
```
([Playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=789b3f283ee6126f53939429103ed98d))
</details>

This PR fixes the problem, by adding associated functions that have "custom linkage" to `reachable_set`, just like normal functions.

I haven't tested whether rust-lang#76211 and [Miri](rust-lang/miri#1837) are fixed by this PR yet, but I'm submitting this anyway since this fixes the examples above.

I added a `run-pass` test that combines my two examples above, but I'm not sure if that's the right way to test this. Maybe I should add / modify an existing codegen test (`src/test/codegen/export-no-mangle.rs`?) instead?
@bors bors closed this as completed in e8ac524 Aug 15, 2021
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant