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

#[no_mangle] on associated functions #1837

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant