Skip to content

Commit f16a83c

Browse files
committed
Auto merge of rust-lang#124330 - fmease:rollup-a98y7jf, r=fmease
Rollup of 6 pull requests Successful merges: - rust-lang#123316 (Test `#[unix_sigpipe = "inherit"]` with both `SIG_DFL` and `SIG_IGN`) - rust-lang#123794 (More DefineOpaqueTypes::Yes) - rust-lang#123881 (Bump Fuchsia versions) - rust-lang#124281 (fix weak memory bug in TLS on Windows) - rust-lang#124282 (windows fill_utf16_buf: explain the expected return value) - rust-lang#124308 (Add diagnostic item for `std::iter::Enumerate`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 5557f8c + eaeaeb9 commit f16a83c

File tree

15 files changed

+365
-24
lines changed

15 files changed

+365
-24
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1139,7 +1139,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11391139
// are the same function and their parameters have a LUB.
11401140
match self.commit_if_ok(|_| {
11411141
self.at(cause, self.param_env).lub(
1142-
DefineOpaqueTypes::No,
1142+
DefineOpaqueTypes::Yes,
11431143
prev_ty,
11441144
new_ty,
11451145
)

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ symbols! {
192192
Duration,
193193
Encodable,
194194
Encoder,
195+
Enumerate,
195196
Eq,
196197
Equal,
197198
Err,

library/core/src/iter/adapters/enumerate.rs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::ops::Try;
1515
#[derive(Clone, Debug)]
1616
#[must_use = "iterators are lazy and do nothing unless consumed"]
1717
#[stable(feature = "rust1", since = "1.0.0")]
18+
#[cfg_attr(not(test), rustc_diagnostic_item = "Enumerate")]
1819
pub struct Enumerate<I> {
1920
iter: I,
2021
count: usize,

library/std/src/sys/pal/windows/mod.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,21 @@ pub fn to_u16s<S: AsRef<OsStr>>(s: S) -> crate::io::Result<Vec<u16>> {
201201
// currently reside in the buffer. This function is an abstraction over these
202202
// functions by making them easier to call.
203203
//
204-
// The first callback, `f1`, is yielded a (pointer, len) pair which can be
204+
// The first callback, `f1`, is passed a (pointer, len) pair which can be
205205
// passed to a syscall. The `ptr` is valid for `len` items (u16 in this case).
206-
// The closure is expected to return what the syscall returns which will be
207-
// interpreted by this function to determine if the syscall needs to be invoked
208-
// again (with more buffer space).
206+
// The closure is expected to:
207+
// - On success, return the actual length of the written data *without* the null terminator.
208+
// This can be 0. In this case the last_error must be left unchanged.
209+
// - On insufficient buffer space,
210+
// - either return the required length *with* the null terminator,
211+
// - or set the last-error to ERROR_INSUFFICIENT_BUFFER and return `len`.
212+
// - On other failure, return 0 and set last_error.
213+
//
214+
// This is how most but not all syscalls indicate the required buffer space.
215+
// Other syscalls may need translation to match this protocol.
209216
//
210217
// Once the syscall has completed (errors bail out early) the second closure is
211-
// yielded the data which has been read from the syscall. The return value
218+
// passed the data which has been read from the syscall. The return value
212219
// from this closure is then the return value of the function.
213220
pub fn fill_utf16_buf<F1, F2, T>(mut f1: F1, f2: F2) -> crate::io::Result<T>
214221
where

library/std/src/sys/pal/windows/os.rs

+2
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ fn home_dir_crt() -> Option<PathBuf> {
326326

327327
super::fill_utf16_buf(
328328
|buf, mut sz| {
329+
// GetUserProfileDirectoryW does not quite use the usual protocol for
330+
// negotiating the buffer size, so we have to translate.
329331
match c::GetUserProfileDirectoryW(
330332
ptr::without_provenance_mut(CURRENT_PROCESS_TOKEN),
331333
buf,

library/std/src/sys/pal/windows/thread_local_key.rs

+22-4
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,15 @@ impl StaticKey {
141141
panic!("out of TLS indexes");
142142
}
143143

144-
self.key.store(key + 1, Release);
145144
register_dtor(self);
146145

146+
// Release-storing the key needs to be the last thing we do.
147+
// This is because in `fn key()`, other threads will do an acquire load of the key,
148+
// and if that sees this write then it will entirely bypass the `InitOnce`. We thus
149+
// need to establish synchronization through `key`. In particular that acquire load
150+
// must happen-after the register_dtor above, to ensure the dtor actually runs!
151+
self.key.store(key + 1, Release);
152+
147153
let r = c::InitOnceComplete(self.once.get(), 0, ptr::null_mut());
148154
debug_assert_eq!(r, c::TRUE);
149155

@@ -313,17 +319,29 @@ unsafe fn run_dtors() {
313319
// Use acquire ordering to observe key initialization.
314320
let mut cur = DTORS.load(Acquire);
315321
while !cur.is_null() {
316-
let key = (*cur).key.load(Relaxed) - 1;
322+
let pre_key = (*cur).key.load(Acquire);
317323
let dtor = (*cur).dtor.unwrap();
324+
cur = (*cur).next.load(Relaxed);
325+
326+
// In StaticKey::init, we register the dtor before setting `key`.
327+
// So if one thread's `run_dtors` races with another thread executing `init` on the same
328+
// `StaticKey`, we can encounter a key of 0 here. That means this key was never
329+
// initialized in this thread so we can safely skip it.
330+
if pre_key == 0 {
331+
continue;
332+
}
333+
// If this is non-zero, then via the `Acquire` load above we synchronized with
334+
// everything relevant for this key. (It's not clear that this is needed, since the
335+
// release-acquire pair on DTORS also establishes synchronization, but better safe than
336+
// sorry.)
337+
let key = pre_key - 1;
318338

319339
let ptr = c::TlsGetValue(key);
320340
if !ptr.is_null() {
321341
c::TlsSetValue(key, ptr::null_mut());
322342
dtor(ptr as *mut _);
323343
any_run = true;
324344
}
325-
326-
cur = (*cur).next.load(Relaxed);
327345
}
328346

329347
if !any_run {

src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
set -euf -o pipefail
77

8-
INTEGRATION_SHA=56310bca298872ffb5ea02e665956d9b6dc41171
8+
INTEGRATION_SHA=1011e3298775ee7cdf6f6dc73e808d6a86e33bd6
99
PICK_REFS=()
1010

1111
checkout=fuchsia

src/ci/docker/scripts/build-fuchsia-toolchain.sh

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ set -ex
44
source shared.sh
55

66
FUCHSIA_SDK_URL=https://chrome-infra-packages.appspot.com/dl/fuchsia/sdk/core/linux-amd64
7-
FUCHSIA_SDK_ID=MrhQwtmP8CpZre-i_PNOREcThbUcrX3bA-45d6WQr-cC
8-
FUCHSIA_SDK_SHA256=32b850c2d98ff02a59adefa2fcf34e44471385b51cad7ddb03ee3977a590afe7
7+
FUCHSIA_SDK_ID=version:20.20240412.3.1
8+
FUCHSIA_SDK_SHA256=cc52f3497487dd813c89d9316e6967efcea89c7759edccf3e40fcf3662e53f19
99
FUCHSIA_SDK_USR_DIR=/usr/local/core-linux-amd64-fuchsia-sdk
1010
CLANG_DOWNLOAD_URL=\
1111
https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/clang/linux-amd64
12-
CLANG_DOWNLOAD_ID=Tpc85d1ZwSlZ6UKl2d96GRUBGNA5JKholOKe24sRDr0C
13-
CLANG_DOWNLOAD_SHA256=4e973ce5dd59c12959e942a5d9df7a19150118d03924a86894e29edb8b110ebd
12+
CLANG_DOWNLOAD_ID=git_revision:c777c011a709dffd4fa5e79cad7947b7c3405d02
13+
CLANG_DOWNLOAD_SHA256=779167422ad73c292f049dcea5569f84577af9292189ed2749518b966a4d0844
1414

1515
install_clang() {
1616
mkdir -p clang_download

src/ci/docker/scripts/fuchsia-test-runner.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ def start(self):
280280
# Look up the product bundle transfer manifest.
281281
self.log_info("Looking up the product bundle transfer manifest...")
282282
product_name = "minimal." + self.triple_to_arch(self.target)
283-
fuchsia_version = "14.20230811.2.1"
283+
fuchsia_version = "20.20240412.3.1"
284284

285285
# FIXME: We should be able to replace this with the machine parsable
286286
# `ffx --machine json product lookup ...` once F15 is released.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//@ aux-crate: sigpipe_utils=sigpipe-utils.rs
2+
3+
#![feature(unix_sigpipe)]
4+
5+
#[unix_sigpipe = "inherit"]
6+
fn main() {
7+
sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default);
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//@ aux-crate: sigpipe_utils=sigpipe-utils.rs
2+
3+
#![feature(unix_sigpipe)]
4+
5+
#[unix_sigpipe = "inherit"]
6+
fn main() {
7+
sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore);
8+
}
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
1+
//@ ignore-cross-compile because aux-bin does not yet support it
2+
//@ only-unix because SIGPIPE is a unix thing
3+
//@ aux-bin: assert-inherit-sig_dfl.rs
4+
//@ aux-bin: assert-inherit-sig_ign.rs
15
//@ run-pass
2-
//@ aux-build:sigpipe-utils.rs
36

4-
#![feature(unix_sigpipe)]
7+
#![feature(rustc_private, unix_sigpipe)]
58

6-
#[unix_sigpipe = "inherit"]
9+
extern crate libc;
10+
11+
// By default the Rust runtime resets SIGPIPE to SIG_DFL before exec:ing child
12+
// processes so opt-out of that with `#[unix_sigpipe = "sig_dfl"]`. See
13+
// https://github.com/rust-lang/rust/blob/bf4de3a874753bbee3323081c8b0c133444fed2d/library/std/src/sys/pal/unix/process/process_unix.rs#L359-L384
14+
#[unix_sigpipe = "sig_dfl"]
715
fn main() {
8-
extern crate sigpipe_utils;
16+
// First expect SIG_DFL in a child process with #[unix_sigpipe = "inherit"].
17+
assert_inherit_sigpipe_disposition("auxiliary/bin/assert-inherit-sig_dfl");
18+
19+
// With SIG_IGN we expect #[unix_sigpipe = "inherit"] to also get SIG_IGN.
20+
unsafe {
21+
libc::signal(libc::SIGPIPE, libc::SIG_IGN);
22+
}
23+
assert_inherit_sigpipe_disposition("auxiliary/bin/assert-inherit-sig_ign");
24+
}
925

10-
// #[unix_sigpipe = "inherit"] is active, so SIGPIPE shall NOT be ignored,
11-
// instead the default handler shall be installed. (We assume that the
12-
// process that runs these tests have the default handler.)
13-
sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default);
26+
fn assert_inherit_sigpipe_disposition(aux_bin: &str) {
27+
let mut cmd = std::process::Command::new(aux_bin);
28+
assert!(cmd.status().unwrap().success());
1429
}

tests/ui/fn/fn_def_coercion.rs

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//! Test that coercing between function items of the same function,
2+
//! but with different generic args succeeds in typeck, but then fails
3+
//! in borrowck when the lifetimes can't actually be merged.
4+
5+
fn foo<T>(t: T) -> T {
6+
t
7+
}
8+
9+
fn f<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
10+
let mut x = foo::<&'a ()>; //~ ERROR: lifetime may not live long enough
11+
x = foo::<&'b ()>; //~ ERROR: lifetime may not live long enough
12+
x = foo::<&'c ()>;
13+
x(a);
14+
x(b);
15+
x(c);
16+
}
17+
18+
fn g<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
19+
let x = foo::<&'c ()>;
20+
let _: &'c () = x(a); //~ ERROR lifetime may not live long enough
21+
}
22+
23+
fn h<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
24+
let x = foo::<&'a ()>;
25+
let _: &'a () = x(c);
26+
}
27+
28+
fn i<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
29+
let mut x = foo::<&'c ()>;
30+
x = foo::<&'b ()>; //~ ERROR lifetime may not live long enough
31+
x = foo::<&'a ()>; //~ ERROR lifetime may not live long enough
32+
x(a);
33+
x(b);
34+
x(c);
35+
}
36+
37+
fn j<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
38+
let x = match true {
39+
true => foo::<&'b ()>, //~ ERROR lifetime may not live long enough
40+
false => foo::<&'a ()>, //~ ERROR lifetime may not live long enough
41+
};
42+
x(a);
43+
x(b);
44+
x(c);
45+
}
46+
47+
fn k<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
48+
let x = match true {
49+
true => foo::<&'c ()>,
50+
false => foo::<&'a ()>, //~ ERROR lifetime may not live long enough
51+
};
52+
53+
x(a);
54+
x(b); //~ ERROR lifetime may not live long enough
55+
x(c);
56+
}
57+
58+
fn main() {}

0 commit comments

Comments
 (0)