Skip to content

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

@Luro02

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.

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