Skip to content

#[no_mangle] in thread_local! requires unsafe wrapping in edition 2021 #142182

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

Open
elftausend opened this issue Jun 7, 2025 · 7 comments · May be fixed by #142261
Open

#[no_mangle] in thread_local! requires unsafe wrapping in edition 2021 #142182

elftausend opened this issue Jun 7, 2025 · 7 comments · May be fixed by #142261
Labels
A-attributes Area: Attributes (`#[…]`, `#![…]`) A-edition-2024 Area: The 2024 edition A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug. I-prioritize Issue: Indicates that prioritization has been requested for this issue. regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-edition Relevant to the edition team. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Comments

@elftausend
Copy link

elftausend commented Jun 7, 2025

I tried this code to compile in Edition 2021:

#[no_mangle] // fine
static TEST_OUTSIDE: usize = 0;

thread_local! {
    #[no_mangle] // unsafe attribute used without unsafe wrap error
    static TEST: usize = 0;
}

However, compilation fails because the attribute must be wrapped in unsafe(...).
This breaks existing libraries like litequad, even though it wasn't upgraded to edition 2024.

Meta

[package]
name = "no_mangle_test"
version = "0.1.0"
edition = "2021"

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a63572490a930b126b003b57c58c9df0

error: unsafe attribute used without unsafe
 --> src/main.rs:6:7
  |
6 |     #[no_mangle]
  |       ^^^^^^^^^ usage of unsafe attribute
  |
help: wrap the attribute in `unsafe(...)`
  |
6 |     #[unsafe(no_mangle)]
  |       +++++++         +

error: could not compile `no_mangle_test` (bin "no_mangle_test") due to 1 previous error

@elftausend elftausend added the C-bug Category: This is a bug. label Jun 7, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jun 7, 2025
@workingjubilee
Copy link
Member

this seems to be a similar class of bug as to what we fixed via #138717 because the spans get their edition based on the crate the macro is defined in, and for a more recent rustc, std is Edition 2024

@workingjubilee workingjubilee added regression-from-stable-to-stable Performance or correctness regression from one stable version to another. D-edition Diagnostics: An error or lint that should account for edition differences. T-edition Relevant to the edition team. labels Jun 7, 2025
@rustbot rustbot added the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Jun 7, 2025
@workingjubilee workingjubilee added A-attributes Area: Attributes (`#[…]`, `#![…]`) A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) T-libs Relevant to the library team, which will review and decide on the PR/issue. and removed D-edition Diagnostics: An error or lint that should account for edition differences. labels Jun 7, 2025
@Noratrieb Noratrieb removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jun 8, 2025
@bjorn3
Copy link
Member

bjorn3 commented Jun 8, 2025

I don't think #[no_mangle] inside thread_local! {} is supposed to work. What would it actually apply to? The #[thread_local] static? (there may not be any), the static containing the pthread_key_t (again there may not be any), the std::thread::LocalKey (likely to surprise people who want to interoperate with C and it may not even be stored in a static in the first place) or something else?

@workingjubilee
Copy link
Member

...that is an interesting question, yeah.

@apiraino
Copy link
Contributor

apiraino commented Jun 9, 2025

@elftausend I'm slightly confused about which edition that snippet used to compile for you (IIUC your report). Does it compile with --edition=2018 or --edition=2021? Can you share how do you exactly compile that snippet? Thanks

@hanna-kruppe
Copy link
Contributor

It not compiling with older edition but new Rust release is the bug. The playground only has the newest stable Rust, but you can compare 1.87 vs 1.86 on godbolt.

@apiraino
Copy link
Contributor

apiraino commented Jun 9, 2025

thanks @hanna-kruppe. Yes, as probably expected this started in #138162 when the standard library moved to Edition 2024

@ehuss
Copy link
Contributor

ehuss commented Jun 9, 2025

As for why this is happening, this is mostly an unfortunate result of needing to use $meta. The edition checking code here only looks at the entire span of the attribute. This means that the # token is the load-bearing token for determining the edition. The thread_local attribute is ignoring/dropping the # token from the input and substituting it with its own here.

My expectation would be that the name of the attribute should be the span that it checks for the edition.

I think that could be implemented by calling attr.get_normal_item().span() instead of attr.span() (or something like that).
cc @compiler-errors @folkertdev if that would make sense?

@ehuss ehuss added the A-edition-2024 Area: The 2024 edition label Jun 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-attributes Area: Attributes (`#[…]`, `#![…]`) A-edition-2024 Area: The 2024 edition A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug. I-prioritize Issue: Indicates that prioritization has been requested for this issue. regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-edition Relevant to the edition team. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants