Repository: rust
Issue: Custom section generation under `wasm32-unknown-unknown` is inconsistent and unintuitive
Labels: A-linkage,O-wasm

Assume we have a crate named `dependency` with the following content:

```rust
pub fn trigger() {
    submodule::call();
}
pub mod submodule {
    pub fn call() {
        #[link_section = "some-custom-section"]
        static SNIPPET: [u8; 3] = [b'X', b'Y', b'Z'];

        extern "C" {
            fn require_XYZ();
        }

        unsafe {
            require_XYZ();
        }
    }
}
```

And we have another crate which uses the `dependency`:

```rust
extern crate dependency;

#[no_mangle]
pub fn main() {
    dependency::trigger();
}
```

If I compile this crate like this:

```
$ cargo build --target=wasm32-unknown-unknown --release
```

and dump it with `wasm-objdump` then the `"some-custom-section"` custom section will be missing. However, if I change the `dependency` crate to look like this (I've moved the `call` function from the `submodule` to the crate root and even made it private):

```rust
pub fn trigger() {
    call();
}
fn call() {
    #[link_section = "some-custom-section"]
    static SNIPPET: [u8; 3] = [b'X', b'Y', b'Z'];

    extern "C" {
        fn require_XYZ();
    }

    unsafe {
        require_XYZ();
    }
}
```

and build the main crate again then the custom section *is* generated. Calling `dependency::submodule::call` directly instead of `dependency::trigger` also results in the custom section being generated.

Based on my experiments the custom section generation currently works like this:

| In which crate is the custom section defined? | Where is the function containing the section? | How is the function containing the custom section called? | Is it generated? |
| --------------------------------------------- | --------------------------------------------- | --------------------------------------------------------- | ---------------- |
| External crate | Submodule | Not called | No  |
| External crate | Submodule | Indirectly | No  |
| External crate | Submodule | Directly   | Yes |
| External crate | In root   | Not called | No  |
| External crate | In root   | Indirectly | Yes |
| External crate | In root   | Directly   | Yes |
| Main crate     | Any       | Any        | Yes |

I have an example crate here which reproduces the issue:

```
$ git clone https://github.com/koute/rust-custom-section-issue
$ cd rust-custom-section-issue

# This will not generate a custom section:
$ cargo build --target=wasm32-unknown-unknown --release --features broken
$ wasm-objdump -s target/wasm32-unknown-unknown/release/rust_custom_section_issue.wasm

# This will:
$ cargo build --target=wasm32-unknown-unknown --release --features working
$ wasm-objdump -s target/wasm32-unknown-unknown/release/rust_custom_section_issue.wasm
```

I'm using the most recent nightly: `rustc 1.32.0-nightly (4a45578bc 2018-12-07)`

Could we make this somewhat consistent?

Some background: as a first step towards `wasm-bindgen` compatibility I'm converting [`stdweb`](https://github.com/koute/stdweb)'s `js!` macro to use custom sections, however to make it not break existing downstream users I need to have either a) every custom section in the whole crate graph be generated, or b) always generated if the custom section is defined inside of a potentially reachable (at runtime) function. Otherwise I end up generating an import for a snippet for which the corresponding custom section entry doesn't exist.

cc @alexcrichton