Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d25ab9c

Browse files
committedMar 2, 2024
Auto merge of rust-lang#121904 - matthiaskrgr:rollup-qcq0d3h, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#121666 (Use the OS thread name by default if `THREAD_INFO` has not been initialized) - rust-lang#121758 (Move thread local implementation to `sys`) - rust-lang#121759 (attempt to further clarify addr_of docs) - rust-lang#121855 (Correctly generate item info of trait items) - rust-lang#121888 (style library/core/src/error.rs) - rust-lang#121892 (The ordinary lowering of `thir::ExprKind::Let` is unreachable) - rust-lang#121895 (avoid collecting into vecs in some places) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 5257aee + fcf5805 commit d25ab9c

File tree

33 files changed

+269
-107
lines changed

33 files changed

+269
-107
lines changed
 

‎compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -357,31 +357,27 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) {
357357

358358
let ignore_unused_generics = tcx.sess.instrument_coverage_except_unused_generics();
359359

360-
let eligible_def_ids: Vec<DefId> = tcx
361-
.mir_keys(())
362-
.iter()
363-
.filter_map(|local_def_id| {
364-
let def_id = local_def_id.to_def_id();
365-
let kind = tcx.def_kind(def_id);
366-
// `mir_keys` will give us `DefId`s for all kinds of things, not
367-
// just "functions", like consts, statics, etc. Filter those out.
368-
// If `ignore_unused_generics` was specified, filter out any
369-
// generic functions from consideration as well.
370-
if !matches!(kind, DefKind::Fn | DefKind::AssocFn | DefKind::Closure) {
371-
return None;
372-
}
373-
if ignore_unused_generics && tcx.generics_of(def_id).requires_monomorphization(tcx) {
374-
return None;
375-
}
376-
Some(local_def_id.to_def_id())
377-
})
378-
.collect();
360+
let eligible_def_ids = tcx.mir_keys(()).iter().filter_map(|local_def_id| {
361+
let def_id = local_def_id.to_def_id();
362+
let kind = tcx.def_kind(def_id);
363+
// `mir_keys` will give us `DefId`s for all kinds of things, not
364+
// just "functions", like consts, statics, etc. Filter those out.
365+
// If `ignore_unused_generics` was specified, filter out any
366+
// generic functions from consideration as well.
367+
if !matches!(kind, DefKind::Fn | DefKind::AssocFn | DefKind::Closure) {
368+
return None;
369+
}
370+
if ignore_unused_generics && tcx.generics_of(def_id).requires_monomorphization(tcx) {
371+
return None;
372+
}
373+
Some(local_def_id.to_def_id())
374+
});
379375

380376
let codegenned_def_ids = codegenned_and_inlined_items(tcx);
381377

382378
// For each `DefId` that should have coverage instrumentation but wasn't
383379
// codegenned, add it to the function coverage map as an unused function.
384-
for def_id in eligible_def_ids.into_iter().filter(|id| !codegenned_def_ids.contains(id)) {
380+
for def_id in eligible_def_ids.filter(|id| !codegenned_def_ids.contains(id)) {
385381
// Skip any function that didn't have coverage data added to it by the
386382
// coverage instrumentor.
387383
let body = tcx.instance_mir(ty::InstanceDef::Item(def_id));

‎compiler/rustc_hir_analysis/src/astconv/mod.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -860,10 +860,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
860860
traits with associated type `{name}`, you could use the \
861861
fully-qualified path",
862862
),
863-
traits
864-
.iter()
865-
.map(|trait_str| format!("<Example as {trait_str}>::{name}"))
866-
.collect::<Vec<_>>(),
863+
traits.iter().map(|trait_str| format!("<Example as {trait_str}>::{name}")),
867864
Applicability::HasPlaceholders,
868865
);
869866
}

‎compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2156,10 +2156,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21562156
err.span_suggestions(
21572157
span.shrink_to_hi().with_hi(expr_span.hi()),
21582158
"you might have meant to use an associated function to build this type",
2159-
items
2160-
.iter()
2161-
.map(|(_, name, args)| suggestion(name, *args))
2162-
.collect::<Vec<String>>(),
2159+
items.iter().map(|(_, name, args)| suggestion(name, *args)),
21632160
Applicability::MaybeIncorrect,
21642161
);
21652162
}

‎compiler/rustc_mir_build/src/build/expr/into.rs

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -109,38 +109,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
109109
this.cfg.goto(else_blk, source_info, join_block);
110110
join_block.unit()
111111
}
112-
ExprKind::Let { expr, ref pat } => {
113-
let scope = this.local_scope();
114-
let (true_block, false_block) = this.in_if_then_scope(scope, expr_span, |this| {
115-
this.lower_let_expr(block, expr, pat, scope, None, expr_span, true)
116-
});
117-
118-
this.cfg.push_assign_constant(
119-
true_block,
120-
source_info,
121-
destination,
122-
ConstOperand {
123-
span: expr_span,
124-
user_ty: None,
125-
const_: Const::from_bool(this.tcx, true),
126-
},
127-
);
128-
129-
this.cfg.push_assign_constant(
130-
false_block,
131-
source_info,
132-
destination,
133-
ConstOperand {
134-
span: expr_span,
135-
user_ty: None,
136-
const_: Const::from_bool(this.tcx, false),
137-
},
138-
);
139-
140-
let join_block = this.cfg.start_new_block();
141-
this.cfg.goto(true_block, source_info, join_block);
142-
this.cfg.goto(false_block, source_info, join_block);
143-
join_block.unit()
112+
ExprKind::Let { .. } => {
113+
// After desugaring, `let` expressions should only appear inside `if`
114+
// expressions or `match` guards, possibly nested within a let-chain.
115+
// In both cases they are specifically handled by the lowerings of
116+
// those expressions, so this case is currently unreachable.
117+
span_bug!(expr_span, "unexpected let expression outside of if or match-guard");
144118
}
145119
ExprKind::NeverToAny { source } => {
146120
let source_expr = &this.thir[source];

‎compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1884,10 +1884,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
18841884
err.span_suggestions_with_style(
18851885
path_span.shrink_to_hi().with_hi(call_span.hi()),
18861886
"you might have meant to use an associated function to build this type",
1887-
items
1888-
.iter()
1889-
.map(|(_, name, len)| suggestion(name, *len))
1890-
.collect::<Vec<String>>(),
1887+
items.iter().map(|(_, name, len)| suggestion(name, *len)),
18911888
Applicability::MaybeIncorrect,
18921889
SuggestionStyle::ShowAlways,
18931890
);

‎compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl<'tcx> ObligationStorage<'tcx> {
5757

5858
fn take_pending(&mut self) -> Vec<PredicateObligation<'tcx>> {
5959
let mut obligations = mem::take(&mut self.pending);
60-
obligations.extend(self.overflowed.drain(..));
60+
obligations.append(&mut self.overflowed);
6161
obligations
6262
}
6363

‎library/core/src/error.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ pub trait Error: Debug + Display {
183183
#[allow(unused_variables)]
184184
fn provide<'a>(&'a self, request: &mut Request<'a>) {}
185185
}
186+
186187
mod private {
187188
// This is a hack to prevent `type_id` from being overridden by `Error`
188189
// implementations, since that can enable unsound downcasting.

‎library/core/src/ptr/mod.rs

Lines changed: 63 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2071,11 +2071,16 @@ impl<F: FnPtr> fmt::Debug for F {
20712071
/// as all other references. This macro can create a raw pointer *without* creating
20722072
/// a reference first.
20732073
///
2074-
/// The `expr` in `addr_of!(expr)` is evaluated as a place expression, but never loads
2075-
/// from the place or requires the place to be dereferenceable. This means that
2076-
/// `addr_of!(*ptr)` is defined behavior even if `ptr` is null, dangling, or misaligned.
2077-
/// Note however that `addr_of!((*ptr).field)` still requires the projection to
2078-
/// `field` to be in-bounds, using the same rules as [`offset`].
2074+
/// See [`addr_of_mut`] for how to create a pointer to uninitialized data.
2075+
/// Doing that with `addr_of` would not make much sense since one could only
2076+
/// read the data, and that would be Undefined Behavior.
2077+
///
2078+
/// # Safety
2079+
///
2080+
/// The `expr` in `addr_of!(expr)` is evaluated as a place expression, but never loads from the
2081+
/// place or requires the place to be dereferenceable. This means that `addr_of!((*ptr).field)`
2082+
/// still requires the projection to `field` to be in-bounds, using the same rules as [`offset`].
2083+
/// However, `addr_of!(*ptr)` is defined behavior even if `ptr` is null, dangling, or misaligned.
20792084
///
20802085
/// Note that `Deref`/`Index` coercions (and their mutable counterparts) are applied inside
20812086
/// `addr_of!` like everywhere else, in which case a reference is created to call `Deref::deref` or
@@ -2086,6 +2091,8 @@ impl<F: FnPtr> fmt::Debug for F {
20862091
///
20872092
/// # Example
20882093
///
2094+
/// **Correct usage: Creating a pointer to unaligned data**
2095+
///
20892096
/// ```
20902097
/// use std::ptr;
20912098
///
@@ -2101,9 +2108,27 @@ impl<F: FnPtr> fmt::Debug for F {
21012108
/// assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
21022109
/// ```
21032110
///
2104-
/// See [`addr_of_mut`] for how to create a pointer to uninitialized data.
2105-
/// Doing that with `addr_of` would not make much sense since one could only
2106-
/// read the data, and that would be Undefined Behavior.
2111+
/// **Incorrect usage: Out-of-bounds fields projection**
2112+
///
2113+
/// ```rust,no_run
2114+
/// use std::ptr;
2115+
///
2116+
/// #[repr(C)]
2117+
/// struct MyStruct {
2118+
/// field1: i32,
2119+
/// field2: i32,
2120+
/// }
2121+
///
2122+
/// let ptr: *const MyStruct = ptr::null();
2123+
/// let fieldptr = unsafe { ptr::addr_of!((*ptr).field2) }; // Undefined Behavior ⚠️
2124+
/// ```
2125+
///
2126+
/// The field projection `.field2` would offset the pointer by 4 bytes,
2127+
/// but the pointer is not in-bounds of an allocation for 4 bytes,
2128+
/// so this offset is Undefined Behavior.
2129+
/// See the [`offset`] docs for a full list of requirements for inbounds pointer arithmetic; the
2130+
/// same requirements apply to field projections, even inside `addr_of!`. (In particular, it makes
2131+
/// no difference whether the pointer is null or dangling.)
21072132
#[stable(feature = "raw_ref_macros", since = "1.51.0")]
21082133
#[rustc_macro_transparency = "semitransparent"]
21092134
#[allow_internal_unstable(raw_ref_op)]
@@ -2120,11 +2145,12 @@ pub macro addr_of($place:expr) {
21202145
/// as all other references. This macro can create a raw pointer *without* creating
21212146
/// a reference first.
21222147
///
2123-
/// The `expr` in `addr_of_mut!(expr)` is evaluated as a place expression, but never loads
2124-
/// from the place or requires the place to be dereferenceable. This means that
2125-
/// `addr_of_mut!(*ptr)` is defined behavior even if `ptr` is null, dangling, or misaligned.
2126-
/// Note however that `addr_of_mut!((*ptr).field)` still requires the projection to
2127-
/// `field` to be in-bounds, using the same rules as [`offset`].
2148+
/// # Safety
2149+
///
2150+
/// The `expr` in `addr_of_mut!(expr)` is evaluated as a place expression, but never loads from the
2151+
/// place or requires the place to be dereferenceable. This means that `addr_of_mut!((*ptr).field)`
2152+
/// still requires the projection to `field` to be in-bounds, using the same rules as [`offset`].
2153+
/// However, `addr_of_mut!(*ptr)` is defined behavior even if `ptr` is null, dangling, or misaligned.
21282154
///
21292155
/// Note that `Deref`/`Index` coercions (and their mutable counterparts) are applied inside
21302156
/// `addr_of_mut!` like everywhere else, in which case a reference is created to call `Deref::deref`
@@ -2135,7 +2161,7 @@ pub macro addr_of($place:expr) {
21352161
///
21362162
/// # Examples
21372163
///
2138-
/// **Creating a pointer to unaligned data:**
2164+
/// **Correct usage: Creating a pointer to unaligned data**
21392165
///
21402166
/// ```
21412167
/// use std::ptr;
@@ -2153,7 +2179,7 @@ pub macro addr_of($place:expr) {
21532179
/// assert_eq!({packed.f2}, 42); // `{...}` forces copying the field instead of creating a reference.
21542180
/// ```
21552181
///
2156-
/// **Creating a pointer to uninitialized data:**
2182+
/// **Correct usage: Creating a pointer to uninitialized data**
21572183
///
21582184
/// ```rust
21592185
/// use std::{ptr, mem::MaybeUninit};
@@ -2169,6 +2195,28 @@ pub macro addr_of($place:expr) {
21692195
/// unsafe { f1_ptr.write(true); }
21702196
/// let init = unsafe { uninit.assume_init() };
21712197
/// ```
2198+
///
2199+
/// **Incorrect usage: Out-of-bounds fields projection**
2200+
///
2201+
/// ```rust,no_run
2202+
/// use std::ptr;
2203+
///
2204+
/// #[repr(C)]
2205+
/// struct MyStruct {
2206+
/// field1: i32,
2207+
/// field2: i32,
2208+
/// }
2209+
///
2210+
/// let ptr: *mut MyStruct = ptr::null_mut();
2211+
/// let fieldptr = unsafe { ptr::addr_of_mut!((*ptr).field2) }; // Undefined Behavior ⚠️
2212+
/// ```
2213+
///
2214+
/// The field projection `.field2` would offset the pointer by 4 bytes,
2215+
/// but the pointer is not in-bounds of an allocation for 4 bytes,
2216+
/// so this offset is Undefined Behavior.
2217+
/// See the [`offset`] docs for a full list of requirements for inbounds pointer arithmetic; the
2218+
/// same requirements apply to field projections, even inside `addr_of_mut!`. (In particular, it
2219+
/// makes no difference whether the pointer is null or dangling.)
21722220
#[stable(feature = "raw_ref_macros", since = "1.51.0")]
21732221
#[rustc_macro_transparency = "semitransparent"]
21742222
#[allow_internal_unstable(raw_ref_op)]

‎library/std/src/sys/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ pub mod cmath;
99
pub mod locks;
1010
pub mod os_str;
1111
pub mod path;
12+
#[allow(dead_code)]
13+
#[allow(unused_imports)]
14+
pub mod thread_local;
1215

1316
// FIXME(117276): remove this, move feature implementations into individual
1417
// submodules.

‎library/std/src/sys/pal/common/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212

1313
pub mod alloc;
1414
pub mod small_c_string;
15-
#[allow(unused_imports)]
16-
pub mod thread_local;
1715

1816
#[cfg(test)]
1917
mod tests;

‎library/std/src/sys/pal/hermit/thread.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use super::abi;
44
use super::thread_local_dtor::run_dtors;
5-
use crate::ffi::CStr;
5+
use crate::ffi::{CStr, CString};
66
use crate::io;
77
use crate::mem;
88
use crate::num::NonZero;
@@ -71,6 +71,10 @@ impl Thread {
7171
// nope
7272
}
7373

74+
pub fn get_name() -> Option<CString> {
75+
None
76+
}
77+
7478
#[inline]
7579
pub fn sleep(dur: Duration) {
7680
unsafe {

‎library/std/src/sys/pal/itron/thread.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use super::{
88
};
99
use crate::{
1010
cell::UnsafeCell,
11-
ffi::CStr,
11+
ffi::{CStr, CString},
1212
hint, io,
1313
mem::ManuallyDrop,
1414
num::NonZero,
@@ -204,6 +204,10 @@ impl Thread {
204204
// nope
205205
}
206206

207+
pub fn get_name() -> Option<CString> {
208+
None
209+
}
210+
207211
pub fn sleep(dur: Duration) {
208212
for timeout in dur2reltims(dur) {
209213
expect_success(unsafe { abi::dly_tsk(timeout) }, &"dly_tsk");

‎library/std/src/sys/pal/sgx/thread.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![cfg_attr(test, allow(dead_code))] // why is this necessary?
22
use super::unsupported;
3-
use crate::ffi::CStr;
3+
use crate::ffi::{CStr, CString};
44
use crate::io;
55
use crate::num::NonZero;
66
use crate::time::Duration;
@@ -133,6 +133,10 @@ impl Thread {
133133
// which succeeds as-is with the SGX target.
134134
}
135135

136+
pub fn get_name() -> Option<CString> {
137+
None
138+
}
139+
136140
pub fn sleep(dur: Duration) {
137141
usercalls::wait_timeout(0, dur, || true);
138142
}

‎library/std/src/sys/pal/teeos/thread.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use core::convert::TryInto;
22

33
use crate::cmp;
4-
use crate::ffi::CStr;
4+
use crate::ffi::{CStr, CString};
55
use crate::io;
66
use crate::mem;
77
use crate::num::NonZero;
@@ -101,6 +101,10 @@ impl Thread {
101101
// contact the teeos rustzone team.
102102
}
103103

104+
pub fn get_name() -> Option<CString> {
105+
None
106+
}
107+
104108
/// only main thread could wait for sometime in teeos
105109
pub fn sleep(dur: Duration) {
106110
let sleep_millis = dur.as_millis();

‎library/std/src/sys/pal/uefi/thread.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::unsupported;
2-
use crate::ffi::CStr;
2+
use crate::ffi::{CStr, CString};
33
use crate::io;
44
use crate::num::NonZero;
55
use crate::ptr::NonNull;
@@ -23,6 +23,10 @@ impl Thread {
2323
// nope
2424
}
2525

26+
pub fn get_name() -> Option<CString> {
27+
None
28+
}
29+
2630
pub fn sleep(dur: Duration) {
2731
let boot_services: NonNull<r_efi::efi::BootServices> =
2832
crate::os::uefi::env::boot_services().expect("can't sleep").cast();

‎library/std/src/sys/pal/unix/thread.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::cmp;
2-
use crate::ffi::CStr;
2+
use crate::ffi::{CStr, CString};
33
use crate::io;
44
use crate::mem;
55
use crate::num::NonZero;
@@ -225,6 +225,44 @@ impl Thread {
225225
// Newlib, Emscripten, and VxWorks have no way to set a thread name.
226226
}
227227

228+
#[cfg(target_os = "linux")]
229+
pub fn get_name() -> Option<CString> {
230+
const TASK_COMM_LEN: usize = 16;
231+
let mut name = vec![0u8; TASK_COMM_LEN];
232+
let res = unsafe {
233+
libc::pthread_getname_np(libc::pthread_self(), name.as_mut_ptr().cast(), name.len())
234+
};
235+
if res != 0 {
236+
return None;
237+
}
238+
name.truncate(name.iter().position(|&c| c == 0)?);
239+
CString::new(name).ok()
240+
}
241+
242+
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
243+
pub fn get_name() -> Option<CString> {
244+
let mut name = vec![0u8; libc::MAXTHREADNAMESIZE];
245+
let res = unsafe {
246+
libc::pthread_getname_np(libc::pthread_self(), name.as_mut_ptr().cast(), name.len())
247+
};
248+
if res != 0 {
249+
return None;
250+
}
251+
name.truncate(name.iter().position(|&c| c == 0)?);
252+
CString::new(name).ok()
253+
}
254+
255+
#[cfg(not(any(
256+
target_os = "linux",
257+
target_os = "macos",
258+
target_os = "ios",
259+
target_os = "tvos",
260+
target_os = "watchos"
261+
)))]
262+
pub fn get_name() -> Option<CString> {
263+
None
264+
}
265+
228266
#[cfg(not(target_os = "espidf"))]
229267
pub fn sleep(dur: Duration) {
230268
let mut secs = dur.as_secs();

‎library/std/src/sys/pal/unsupported/thread.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::unsupported;
2-
use crate::ffi::CStr;
2+
use crate::ffi::{CStr, CString};
33
use crate::io;
44
use crate::num::NonZero;
55
use crate::time::Duration;
@@ -22,6 +22,10 @@ impl Thread {
2222
// nope
2323
}
2424

25+
pub fn get_name() -> Option<CString> {
26+
None
27+
}
28+
2529
pub fn sleep(_dur: Duration) {
2630
panic!("can't sleep");
2731
}

‎library/std/src/sys/pal/wasi/thread.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::ffi::CStr;
1+
use crate::ffi::{CStr, CString};
22
use crate::io;
33
use crate::mem;
44
use crate::num::NonZero;
@@ -134,6 +134,10 @@ impl Thread {
134134
// nope
135135
}
136136

137+
pub fn get_name() -> Option<CString> {
138+
None
139+
}
140+
137141
pub fn sleep(dur: Duration) {
138142
let nanos = dur.as_nanos();
139143
assert!(nanos <= u64::MAX as u128);

‎library/std/src/sys/pal/windows/c.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,12 @@ compat_fn_with_fallback! {
344344
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); E_NOTIMPL
345345
}
346346

347+
// >= Win10 1607
348+
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getthreaddescription
349+
pub fn GetThreadDescription(hthread: HANDLE, lpthreaddescription: *mut PWSTR) -> HRESULT {
350+
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); E_NOTIMPL
351+
}
352+
347353
// >= Win8 / Server 2012
348354
// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime
349355
pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> () {

‎library/std/src/sys/pal/windows/c/bindings.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1923,6 +1923,7 @@ Windows.Win32.Foundation.HANDLE_FLAG_INHERIT
19231923
Windows.Win32.Foundation.HANDLE_FLAG_PROTECT_FROM_CLOSE
19241924
Windows.Win32.Foundation.HANDLE_FLAGS
19251925
Windows.Win32.Foundation.HMODULE
1926+
Windows.Win32.Foundation.LocalFree
19261927
Windows.Win32.Foundation.MAX_PATH
19271928
Windows.Win32.Foundation.NO_ERROR
19281929
Windows.Win32.Foundation.NTSTATUS

‎library/std/src/sys/pal/windows/c/windows_sys.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,10 @@ extern "system" {
379379
) -> BOOL;
380380
}
381381
#[link(name = "kernel32")]
382+
extern "system" {
383+
pub fn LocalFree(hmem: HLOCAL) -> HLOCAL;
384+
}
385+
#[link(name = "kernel32")]
382386
extern "system" {
383387
pub fn MoveFileExW(
384388
lpexistingfilename: PCWSTR,
@@ -3441,6 +3445,7 @@ pub type HANDLE_FLAGS = u32;
34413445
pub const HANDLE_FLAG_INHERIT: HANDLE_FLAGS = 1u32;
34423446
pub const HANDLE_FLAG_PROTECT_FROM_CLOSE: HANDLE_FLAGS = 2u32;
34433447
pub const HIGH_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 128u32;
3448+
pub type HLOCAL = *mut ::core::ffi::c_void;
34443449
pub type HMODULE = *mut ::core::ffi::c_void;
34453450
pub type HRESULT = i32;
34463451
pub const IDLE_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 64u32;

‎library/std/src/sys/pal/windows/thread.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::sys::handle::Handle;
99
use crate::sys::stack_overflow;
1010
use crate::sys_common::FromInner;
1111
use crate::time::Duration;
12-
12+
use alloc::ffi::CString;
1313
use core::ffi::c_void;
1414

1515
use super::time::WaitableTimer;
@@ -71,6 +71,29 @@ impl Thread {
7171
};
7272
}
7373

74+
pub fn get_name() -> Option<CString> {
75+
unsafe {
76+
let mut ptr = core::ptr::null_mut();
77+
let result = c::GetThreadDescription(c::GetCurrentThread(), &mut ptr);
78+
if result < 0 {
79+
return None;
80+
}
81+
let name = String::from_utf16_lossy({
82+
let mut len = 0;
83+
while *ptr.add(len) != 0 {
84+
len += 1;
85+
}
86+
core::slice::from_raw_parts(ptr, len)
87+
})
88+
.into_bytes();
89+
// Attempt to free the memory.
90+
// This should never fail but if it does then there's not much we can do about it.
91+
let result = c::LocalFree(ptr.cast::<c_void>());
92+
debug_assert!(result.is_null());
93+
if name.is_empty() { None } else { Some(CString::from_vec_unchecked(name)) }
94+
}
95+
}
96+
7497
pub fn join(self) {
7598
let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) };
7699
if rc == c::WAIT_FAILED {

‎library/std/src/sys/pal/xous/thread.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::ffi::CStr;
1+
use crate::ffi::{CStr, CString};
22
use crate::io;
33
use crate::num::NonZero;
44
use crate::os::xous::ffi::{
@@ -113,6 +113,10 @@ impl Thread {
113113
// nope
114114
}
115115

116+
pub fn get_name() -> Option<CString> {
117+
None
118+
}
119+
116120
pub fn sleep(dur: Duration) {
117121
// Because the sleep server works on units of `usized milliseconds`, split
118122
// the messages up into these chunks. This means we may run into issues

‎library/std/src/sys_common/thread_info.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![allow(dead_code)] // stack_guard isn't used right now on all platforms
22

33
use crate::cell::OnceCell;
4+
use crate::sys;
45
use crate::sys::thread::guard::Guard;
56
use crate::thread::Thread;
67

@@ -23,7 +24,8 @@ impl ThreadInfo {
2324
{
2425
THREAD_INFO
2526
.try_with(move |thread_info| {
26-
let thread = thread_info.thread.get_or_init(|| Thread::new(None));
27+
let thread =
28+
thread_info.thread.get_or_init(|| Thread::new(sys::thread::Thread::get_name()));
2729
f(thread, &thread_info.stack_guard)
2830
})
2931
.ok()

‎library/std/src/thread/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ cfg_if::cfg_if! {
205205
#[doc(hidden)]
206206
#[unstable(feature = "thread_local_internals", issue = "none")]
207207
pub mod local_impl {
208-
pub use crate::sys::common::thread_local::{thread_local_inner, Key, abort_on_dtor_unwind};
208+
pub use crate::sys::thread_local::{thread_local_inner, Key, abort_on_dtor_unwind};
209209
}
210210
}
211211
}

‎library/std/src/thread/tests.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,25 @@ fn test_named_thread_truncation() {
6969
result.unwrap().join().unwrap();
7070
}
7171

72+
#[cfg(any(
73+
target_os = "windows",
74+
target_os = "linux",
75+
target_os = "macos",
76+
target_os = "ios",
77+
target_os = "tvos",
78+
target_os = "watchos"
79+
))]
80+
#[test]
81+
fn test_get_os_named_thread() {
82+
use crate::sys::thread::Thread;
83+
let handler = thread::spawn(|| {
84+
let name = c"test me please";
85+
Thread::set_name(name);
86+
assert_eq!(name, Thread::get_name().unwrap().as_c_str());
87+
});
88+
handler.join().unwrap();
89+
}
90+
7291
#[test]
7392
#[should_panic]
7493
fn test_invalid_named_thread() {

‎src/librustdoc/html/render/mod.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,7 +1680,7 @@ fn render_impl(
16801680
write!(
16811681
&mut doc_buffer,
16821682
"{}",
1683-
document_short(item, cx, link, parent, rendering_params.show_def_docs,)
1683+
document_short(item, cx, link, parent, rendering_params.show_def_docs)
16841684
);
16851685
}
16861686
}
@@ -2043,15 +2043,13 @@ pub(crate) fn render_impl_summary(
20432043
w.write_str("</h3>");
20442044

20452045
let is_trait = inner_impl.trait_.is_some();
2046-
if is_trait {
2047-
if let Some(portability) = portability(&i.impl_item, Some(parent)) {
2048-
write!(
2049-
w,
2050-
"<span class=\"item-info\">\
2051-
<div class=\"stab portability\">{portability}</div>\
2052-
</span>",
2053-
);
2054-
}
2046+
if is_trait && let Some(portability) = portability(&i.impl_item, Some(parent)) {
2047+
write!(
2048+
w,
2049+
"<span class=\"item-info\">\
2050+
<div class=\"stab portability\">{portability}</div>\
2051+
</span>",
2052+
);
20552053
}
20562054

20572055
w.write_str("</section>");

‎src/librustdoc/html/render/print_item.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use crate::html::format::{
3333
};
3434
use crate::html::layout::Page;
3535
use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine};
36+
use crate::html::render::{document_full, document_item_info};
3637
use crate::html::url_parts_builder::UrlPartsBuilder;
3738
use crate::html::{highlight, static_files};
3839

@@ -818,8 +819,10 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
818819
info!("Documenting {name} on {ty_name:?}", ty_name = t.name);
819820
let item_type = m.type_();
820821
let id = cx.derive_id(format!("{item_type}.{name}"));
822+
821823
let mut content = Buffer::empty_from(w);
822-
write!(&mut content, "{}", document(cx, m, Some(t), HeadingOffset::H5));
824+
write!(content, "{}", document_full(m, cx, HeadingOffset::H5));
825+
823826
let toggled = !content.is_empty();
824827
if toggled {
825828
let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" };
@@ -836,8 +839,8 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
836839
cx,
837840
RenderMode::Normal,
838841
);
839-
w.write_str("</h4>");
840-
w.write_str("</section>");
842+
w.write_str("</h4></section>");
843+
document_item_info(cx, m, Some(t)).render_into(w).unwrap();
841844
if toggled {
842845
write!(w, "</summary>");
843846
w.push_buffer(content);

‎tests/rustdoc/trait-item-info.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// This is a regression test for <https://github.com/rust-lang/rust/issues/121772>.
2+
// The goal is to ensure that the item information is always part of the `<summary>`
3+
// if there is one.
4+
5+
#![crate_name = "foo"]
6+
#![feature(staged_api)]
7+
8+
#![unstable(feature = "test", issue = "none")]
9+
10+
// @has 'foo/trait.Foo.html'
11+
12+
#[stable(feature = "rust2", since = "2.2.2")]
13+
pub trait Foo {
14+
// @has - '//div[@class="methods"]/span[@class="item-info"]' 'bla'
15+
// Should not be in a `<details>` because there is no doc.
16+
#[unstable(feature = "bla", reason = "bla", issue = "111")]
17+
fn bla() {}
18+
19+
// @has - '//details[@class="toggle method-toggle"]/summary/span[@class="item-info"]' 'bar'
20+
// Should have a `<summary>` in the `<details>` containing the unstable info.
21+
/// doc
22+
#[unstable(feature = "bar", reason = "bla", issue = "222")]
23+
fn bar() {}
24+
}

0 commit comments

Comments
 (0)
This repository has been archived.