Skip to content

Applying #[link_section = ".mysection"] to a function in an impl is now a warning with potential error in the future? #147411

Description

@Luro02

Code

I tried this code:

#[derive(Default)]
pub struct Abc123 {
    value: u32,
}

impl Abc123 {
    #[no_mangle]
    #[link_section = ".mysection"]
    fn inside_abc_123(&self) {
        println!("Hello World!: {}", self.value);
    }
}

#[no_mangle]
#[link_section = ".mysection"]
fn should_always_link() {
    println!("Hello World!");
}

fn main() {
    // This should be in the .mysection section
    should_always_link();
    // This too?
    Abc123::default().inside_abc_123();
}

I expected to see this happen: Code should compile without warnings and the functions should be in .mysection.

Instead, this happened:

➜  rust-playground git:(master) ✗ cargo build
   Compiling rust-playground v0.1.0 (/mnt/c/projects/rust-playground)
warning: `#[link_section]` attribute cannot be used on inherent methods
  --> src/main.rs:36:5
   |
36 |     #[link_section = ".mysection"]
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = help: `#[link_section]` can be applied to statics and functions
   = note: `#[warn(unused_attributes)]` (part of `#[warn(unused)]`) on by default

warning: `rust-playground` (bin "rust-playground") generated 1 warnings (run `cargo fix --bin "rust-playground"` to apply 1 suggestions)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 5.53s
➜  rust-playground git:(master) ✗

Note: The warning suggests that what I am doing is not working, but this is not true:

➜  rust-playground git:(master) ✗ objdump -t target/debug/rust-playground | grep inside
0000000000056c80 g     F .mysection     0000000000000056              inside_abc_123
➜  rust-playground git:(master) ✗ objdump -t target/debug/rust-playground | grep should_always
0000000000056ce0 g     F .mysection     0000000000000026              should_always_link
➜  rust-playground git:(master) ✗

I would be surprised if this is intentional. Why should a

impl Abc123 {
    fn inside_abc_123(&self) {
        println!("Hello World!: {}", self.value);
    }
}

be treated differently from

fn inside_abc_123(this: &Self) {
        println!("Hello World!: {}", this.value);
}

? Isn't this mostly syntactic sugar?

Version it worked on

It most recently worked on: Rust 1.90

Version with regression

rustc --version --verbose:

rustc 1.92.0-nightly (839222065 2025-10-05)
binary: rustc
commit-hash: 839222065a44ac21c15df68ed2f2f3c0127b0b8e
commit-date: 2025-10-05
host: x86_64-unknown-linux-gnu
release: 1.92.0-nightly
LLVM version: 21.1.2

@rustbot modify labels: +regression-from-stable-to-nightly -regression-untriaged

I think this was introduced with #145085, but it has been quite a while since then, shouldn't this have moved to stable by now?

By the way, ideally I should be able to apply this to any function? Not just foreign ones? The use-case here is that I am working on a library where some functions must be placed in a special section of the binary to improve loading times for these functions.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

A-attributesArea: Attributes (`#[…]`, `#![…]`)C-bugCategory: This is a bug.P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-betaPerformance or correctness regression from stable to beta.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions