Skip to content

Hygiene issues with use declarations in thread_local! implementation #131863

@Timbals

Description

@Timbals
use std::cell::RefCell;

struct Dom;

type Storage<T> = RefCell<Option<T>>;

thread_local! {
    static CURRENT_DOM: Storage<Dom> = const { RefCell::new(None) };
}

The above code worked in 1.80.1 but fails to compile with 1.81.0 on platforms without cfg(target_thread_local). In my case this was aarch64-linux-android.

The issue seems to be that the macro expansion contains a use declaration that pulls in another type called Storage into the scope:

use $crate::thread::LocalKey;
use $crate::thread::local_impl::Storage;

This changed recently in #126953.

A similar change was made to the implementation for platforms with cfg(target_thread_local) in #125525:

use $crate::mem::needs_drop;
use $crate::thread::LocalKey;
use $crate::thread::local_impl::EagerStorage;

Replacing Storage with EagerStorage in the example produces a similar regression for 1.79.0 -> 1.80.0.

The example is from yakui.

Version it worked on

It most recently worked on: 1.80.1

Version with regression

rustc --version --verbose:

rustc 1.81.0 (eeb90cda1 2024-09-04)
binary: rustc
commit-hash: eeb90cda1969383f56a2637cbd3037bdf598841c
commit-date: 2024-09-04
host: x86_64-pc-windows-msvc
release: 1.81.0
LLVM version: 18.1.7

Backtrace

Backtrace

error[E0658]: use of unstable library feature 'thread_local_internals': internal details of the thread_local macro
 --> src\lib.rs:8:25
  |
8 |     static CURRENT_DOM: Storage<Dom> = const { RefCell::new(None) };
  |                         ^^^^^^^^^^^^

error[E0271]: expected `__init` to be a fn item that returns `Storage<Dom>`, but it returns `RefCell<Option<Dom>>`
 --> src\lib.rs:7:1
  |
7 | / thread_local! {
8 | |     static CURRENT_DOM: Storage<Dom> = const { RefCell::new(None) };
9 | | }
  | | ^
  | | |
  | |_expected `Storage<Dom>`, found `RefCell<Option<Dom>>`
  |   required by a bound introduced by this call
  |
  = note: expected struct `std::thread::local_impl::Storage<Dom>`
             found struct `RefCell<Option<Dom>>`
note: required by a bound in `std::thread::local_impl::Storage::<T>::get`
 --> /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sys/thread_local/os.rs:69:5
  = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
 --> src\lib.rs:7:1
  |
7 | / thread_local! {
8 | |     static CURRENT_DOM: Storage<Dom> = const { RefCell::new(None) };
9 | | }
  | | ^
  | | |
  | |_expected `Option<&mut Option<Storage<Dom>>>`, found `Option<&mut Option<RefCell<...>>>`
  |   arguments to this method are incorrect
  |
  = note: expected enum `Option<&mut Option<std::thread::local_impl::Storage<Dom>>>`
             found enum `Option<&mut Option<RefCell<Option<Dom>>>>`
note: method defined here
 --> /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sys/thread_local/os.rs:69:12
  = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
 --> src\lib.rs:7:1
  |
7 | / thread_local! {
8 | |     static CURRENT_DOM: Storage<Dom> = const { RefCell::new(None) };
9 | | }
  | |_^ expected `*const RefCell<Option<Dom>>`, found `*const Storage<Dom>`
  |
  = note: expected raw pointer `*const RefCell<Option<Dom>>`
             found raw pointer `*const std::thread::local_impl::Storage<Dom>`
  = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)

Some errors have detailed explanations: E0271, E0308, E0658.
For more information about an error, try `rustc --explain E0271`.
error: could not compile `minimal` (lib) due to 4 previous errors

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.T-libsRelevant to the library team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions