Uh oh!
There was an error while loading. Please reload this page.
Check #[thread_local] statics correctly in the compiler. - #43746
Conversation
rust-highfive
commented
Aug 8, 2017
(rust_highfive has picked a reviewer for you, use r? to override) |
eddyb
commented
Aug 8, 2017
cc @rust-lang/libs @rust-lang/compiler |
est31
commented
Aug 8, 2017
If |
eddyb
commented
Aug 8, 2017
@est31 I expect it be replaced by macros 2.0 hygiene. |
There was a problem hiding this comment.
Looks like 2-space indent here?
There was a problem hiding this comment.
The entire file has broken (read: old-skool match rules) indentation, I'm actually on a multiple of 4 and the Def::Static line above is wrong.
There was a problem hiding this comment.
Oh I just mentioned this b/c the line just after these modifications is 4-space indented, but yes it looks like the indentation is off in most of this file.
alexcrichton
commented
Aug 9, 2017
Is the intention to get thread-local statics "working" in the sense that it's harder to get them wrong in the compiler? Do you think we should get them on the path to stabilization? Other programs which work today and "shouldn't" work are: #![feature(thread_local)]#[thread_local]staticA:u32 = 1;staticB:&'staticu32 = &A;fnmain(){}but maybe this patch starts to reject that? |
eddyb
commented
Aug 9, 2017
@alexcrichton Interesting, I didn't consider that. Does that not ICE? Trigger an LLVM assertion or linker error? That is, I don't know what meaningful codegen LLVM could possibly have for As for the intention, I want people to stop pitching |
alexcrichton
commented
Aug 9, 2017
LMRTFY (let me rust that for you) It works, and I wouldn't expect it to work (I'd expect a rustc error) |
Out of minimal reduction, on Release mode, we have this LLVM IR: @A = thread_localconstanti321, align4@B = local_unnamed_addrconstanti32*@A, align8And these assembly entries: .type A,@object .section .tdata.A,"awT",@progbits .globl A .p2align 2A: .long 1 .size A,4 .type B,@object .section .data.rel.ro.B,"aw",@progbits .globl B .p2align 3B: .quad A .size B,8What I suspect is happening is EDIT: okay, so I was right about the addresses (see playpen) but... changes to the TLS are reflected in the original?! Or is EDIT2: oh it just looks like the loads from EDIT3: fixed up demo - however, because of the aggressive load folding behavior which changes uses of |
eddyb
commented
Aug 10, 2017
@alexcrichton I've just pushed an updated version of the PR which also checks those cases. |
alexcrichton
commented
Aug 10, 2017
@bors: r+ 👍 |
bors
commented
Aug 10, 2017
📌 Commit 44dbbeb has been approved by |
bors
commented
Aug 11, 2017
⌛ Testing commit 44dbbeb3da7305b94241901f539034cbfd8150cb with merge 86293a2c4fe7cd45130286b270638779e2ae824f... |
bors
commented
Aug 11, 2017
💔 Test failed - status-travis |
est31
commented
Aug 11, 2017
Looks legit |
eddyb
commented
Aug 11, 2017
Ah, fallout from #43522, I'll rebase and try to fix it. |
eddyb
commented
Aug 11, 2017
@bors r=alexcrichton |
bors
commented
Aug 11, 2017
📌 Commit eba7592 has been approved by |
bors
commented
Aug 11, 2017
Check #[thread_local] statics correctly in the compiler. Fixes#43733 by introducing `#[allow_internal_unsafe]` analogous to `#[allow_internal_unstable]`, for letting a macro expand to `unsafe` blocks and functions even in `#![forbid(unsafe_code)]` crates. Fixes#17954 by not letting references to `#[thread_local]` statics escape the function they're taken in - we can't just use a magical lifetime because Rust has *lifetime parametrism*, so if we added the often-proposed `'thread` lifetime, we'd have no way to check it in generic code. To avoid potential edge cases in the compiler, the lifetime is actually that of a temporary at the same position, i.e. `&TLS_STATIC` has the same lifetime `&non_const_fn()` would. Referring to `#[thread_local]` `static`s at compile-time is banned now (as per PR discussion). Additionally, to remove `unsafe impl Sync` from `std::thread::local::fast::Key`, `#[thread_local]` statics are now not required to implement `Sync`, as they are not shared between threads.
bors
commented
Aug 11, 2017
💔 Test failed - status-appveyor |
est31
commented
Aug 11, 2017
looks legit |
eddyb
commented
Aug 11, 2017
So the borrow-checker is more clever than I gave it credit for. Maybe I don't need the |
eddyb
commented
Aug 12, 2017
@bors r=alexcrichton |
bors
commented
Aug 12, 2017
📌 Commit 61ca14f has been approved by |
bors
commented
Aug 12, 2017
⌛ Testing commit 61ca14f10f55dac0fbee1525d570fd9e01780431 with merge ffbde4279123b29b6fc73c1e8023751bdbde44ad... |
bors
commented
Aug 12, 2017
💔 Test failed - status-travis |
[00:59:58] ---- [run-pass] run-pass/thread-local-extern-static.rs stdout ----
[00:59:58][00:59:58] error: auxiliary build of "/checkout/src/test/run-pass/auxiliary/thread-local-extern-static.rs" failed to compile:[00:59:58] status: exit code:101[00:59:58] command: /checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc /checkout/src/test/run-pass/auxiliary/thread-local-extern-static.rs -L /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-pass --target=arm-linux-androideabi --crate-type=dylib -L /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-pass/thread-local-extern-static.stage2-arm-linux-androideabi.run-pass.libaux -C prefer-dynamic --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-pass/thread-local-extern-static.stage2-arm-linux-androideabi.run-pass.libaux -Clinker=/android/ndk/arm-9/bin/arm-linux-androideabi-gcc -Crpath -O -Lnative=/checkout/obj/build/arm-linux-androideabi/native/rust-test-helpers
[00:59:58] stdout:[00:59:58] ------------------------------------------
[00:59:58][00:59:58] ------------------------------------------
[00:59:58] stderr:[00:59:58] ------------------------------------------
[00:59:58] error[E0277]: the trait bound `std::cell::Cell<u32>: std::marker::Sync` is not satisfied
[00:59:58] --> /checkout/src/test/run-pass/auxiliary/thread-local-extern-static.rs:18:1[00:59:58] |
[00:59:58]18 | pub static FOO:Cell<u32> = Cell::new(3);[00:59:58] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::Cell<u32>` cannot be shared between threads safely
[00:59:58] |
[00:59:58] = help: the trait `std::marker::Sync` is not implemented for `std::cell::Cell<u32>`
[00:59:58] = note: shared static variables must have a type that implements `Sync`
[00:59:58][00:59:58] error: aborting due to previous error
[00:59:58][00:59:58][00:59:58] ------------------------------------------
[00:59:58][00:59:58] thread '[run-pass] run-pass/thread-local-extern-static.rs' panicked at 'explicit panic', /checkout/src/tools/compiletest/src/runtest.rs:2511:8[00:59:58] note:Run with `RUST_BACKTRACE=1` for a backtrace.[00:59:58][00:59:58][00:59:58] failures:[00:59:58][run-pass] run-pass/thread-local-extern-static.rs[00:59:58][00:59:58] test result:FAILED.2707passed;1 failed;20 ignored;0 measured;0 filtered out |
eddyb
commented
Aug 12, 2017
@kennytm No, I guess no architecture with OS TLS got to the tests before. |
eddyb
commented
Aug 12, 2017
@bors r=alexcrichton |
bors
commented
Aug 12, 2017
📌 Commit 92892d3 has been approved by |
bors
commented
Aug 12, 2017
Check #[thread_local] statics correctly in the compiler. Fixes#43733 by introducing `#[allow_internal_unsafe]` analogous to `#[allow_internal_unstable]`, for letting a macro expand to `unsafe` blocks and functions even in `#![forbid(unsafe_code)]` crates. Fixes#17954 by not letting references to `#[thread_local]` statics escape the function they're taken in - we can't just use a magical lifetime because Rust has *lifetime parametrism*, so if we added the often-proposed `'thread` lifetime, we'd have no way to check it in generic code. To avoid potential edge cases in the compiler, the lifetime is actually that of a temporary at the same position, i.e. `&TLS_STATIC` has the same lifetime `&non_const_fn()` would. Referring to `#[thread_local]` `static`s at compile-time is banned now (as per PR discussion). Additionally, to remove `unsafe impl Sync` from `std::thread::local::fast::Key`, `#[thread_local]` statics are now not required to implement `Sync`, as they are not shared between threads.
bors
commented
Aug 12, 2017
☀️ Test successful - status-appveyor, status-travis |
- New allocator API - Remove the "allocator" feature, which should be unnecessary due to how the new allocator API works - NonZero no longer implements Deref (rust-lang/rust#41064) - NonZero::new() returns an Option; use NonZero::new_unchecked() - Thread locals are no longer 'static (rust-lang/rust#43746) - Changes to feature flags - Use unsafe to access extern static (rust-lang/rust#36247)
Fixes#43733 by introducing
#[allow_internal_unsafe]analogous to#[allow_internal_unstable], for letting a macro expand tounsafeblocks and functions even in#![forbid(unsafe_code)]crates.Fixes#17954 by not letting references to
#[thread_local]statics escape the function they're taken in - we can't just use a magical lifetime because Rust has lifetime parametrism, so if we added the often-proposed'threadlifetime, we'd have no way to check it in generic code.To avoid potential edge cases in the compiler, the lifetime is actually that of a temporary at the same position, i.e.
&TLS_STATIChas the same lifetime&non_const_fn()would.Referring to
#[thread_local]statics at compile-time is banned now (as per PR discussion).Additionally, to remove
unsafe impl Syncfromstd::thread::local::fast::Key,#[thread_local]statics are now not required to implementSync, as they are not shared between threads.