From 996962243670f15a88910f5c52b30fbc7b409138 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sat, 13 Sep 2025 20:16:58 +0200 Subject: [PATCH 1/8] Improve the documentation around ZERO_AR_DATE --- compiler/rustc_target/src/spec/base/apple/mod.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index ecc7426416059..39e604bcce7ce 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -158,12 +158,22 @@ pub(crate) fn base( SplitDebuginfo::Off, ]), + // Tell the linker that we would like it to avoid irreproducible binaries. + // // This environment variable is pretty magical but is intended for // producing deterministic builds. This was first discovered to be used // by the `ar` tool as a way to control whether or not mtime entries in - // the archive headers were set to zero or not. It appears that - // eventually the linker got updated to do the same thing and now reads - // this environment variable too in recent versions. + // the archive headers were set to zero or not. + // + // In `ld64-351.8`, shipped with Xcode 9.3, the linker was updated to + // read this flag too. Linker versions that don't support this flag + // may embed modification timestamps in binaries (especially in debug + // information). + // + // A cleaner alternative would be to pass the `-reproducible` flag, + // though that is only supported since `ld64-819.6` shipped with Xcode + // 14, which is too new for our minimum supported version: + // https://doc.rust-lang.org/rustc/platform-support/apple-darwin.html#host-tooling // // For some more info see the commentary on #47086 link_env: Cow::Borrowed(&[(Cow::Borrowed("ZERO_AR_DATE"), Cow::Borrowed("1"))]), From 9e2f9edd7f79c1e11339277bfb83a0c888740438 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Mon, 15 Sep 2025 21:43:13 -0400 Subject: [PATCH 2/8] =?UTF-8?q?Don=E2=80=99t=20suggest=20foreign=20`doc(hi?= =?UTF-8?q?dden)`=20types=20in=20E0277=20diagnostics?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../traits/fulfillment_errors.rs | 17 ++++++- tests/ui/proc-macro/quote/not-quotable.stderr | 4 +- .../ui/suggestions/auxiliary/hidden-struct.rs | 26 +++++++++-- .../dont-suggest-foreign-doc-hidden.rs | 18 ++++++-- .../dont-suggest-foreign-doc-hidden.stderr | 44 ++++++++++++++++--- 5 files changed, 94 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 149f5e638b1ad..dff846cfc0af3 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1894,6 +1894,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { other: bool, param_env: ty::ParamEnv<'tcx>, ) -> bool { + let parent_map = self.tcx.visible_parent_map(()); let alternative_candidates = |def_id: DefId| { let mut impl_candidates: Vec<_> = self .tcx @@ -1918,7 +1919,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // FIXME(compiler-errors): This could be generalized, both to // be more granular, and probably look past other `#[fundamental]` // types, too. - self.tcx.visibility(def.did()).is_accessible_from(body_def_id, self.tcx) + let mut did = def.did(); + if self.tcx.visibility(did).is_accessible_from(body_def_id, self.tcx) { + // don't suggest foreign `#[doc(hidden)]` types + if !did.is_local() { + while let Some(parent) = parent_map.get(&did) { + if self.tcx.is_doc_hidden(did) { + return false; + } + did = *parent; + } + } + true + } else { + false + } } else { true } diff --git a/tests/ui/proc-macro/quote/not-quotable.stderr b/tests/ui/proc-macro/quote/not-quotable.stderr index d1c3d06f2b661..62a02638e548b 100644 --- a/tests/ui/proc-macro/quote/not-quotable.stderr +++ b/tests/ui/proc-macro/quote/not-quotable.stderr @@ -15,8 +15,8 @@ LL | let _ = quote! { $ip }; Cow<'_, T> Option Rc - RepInterp - and 25 others + bool + and 24 others error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/auxiliary/hidden-struct.rs b/tests/ui/suggestions/auxiliary/hidden-struct.rs index 30d69acac2097..1f495a9f2224a 100644 --- a/tests/ui/suggestions/auxiliary/hidden-struct.rs +++ b/tests/ui/suggestions/auxiliary/hidden-struct.rs @@ -1,3 +1,5 @@ +// `Foo` and `Bar` should not be suggested in diagnostics of dependents + #[doc(hidden)] pub mod hidden { pub struct Foo; @@ -5,13 +7,29 @@ pub mod hidden { pub mod hidden1 { #[doc(hidden)] - pub struct Foo; + pub struct Bar; } +// `Baz` and `Quux` *should* be suggested in diagnostics of dependents #[doc(hidden)] -pub(crate) mod hidden2 { - pub struct Bar; +pub mod hidden2 { + pub struct Baz; +} + +pub use hidden2::Baz; + +#[doc(hidden)] +pub(crate) mod hidden3 { + pub struct Quux; } -pub use hidden2::Bar; +pub use hidden3::Quux; + +pub trait Marker {} + +impl Marker for Option {} +impl Marker for hidden::Foo {} +impl Marker for hidden1::Bar {} +impl Marker for Baz {} +impl Marker for Quux {} diff --git a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs index 281975dcc2f3b..a83e496f2703d 100644 --- a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs +++ b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs @@ -1,5 +1,4 @@ //@ aux-build:hidden-struct.rs -//@ compile-flags: --crate-type lib extern crate hidden_struct; @@ -9,7 +8,20 @@ mod local { } pub fn test(_: Foo) {} -//~^ ERROR cannot find type `Foo` in this scope +//~^ ERROR [E0412] pub fn test2(_: Bar) {} -//~^ ERROR cannot find type `Bar` in this scope +//~^ ERROR [E0412] + +pub fn test3(_: Baz) {} +//~^ ERROR [E0412] + +pub fn test4(_: Quux) {} +//~^ ERROR [E0412] + +fn test5() {} + +fn main() { + test5::(); + //~^ ERROR [E0277] +} diff --git a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr index 7fb4d95ff9bf5..7036708756d6c 100644 --- a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr +++ b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `Foo` in this scope - --> $DIR/dont-suggest-foreign-doc-hidden.rs:11:16 + --> $DIR/dont-suggest-foreign-doc-hidden.rs:10:16 | LL | pub fn test(_: Foo) {} | ^^^ not found in this scope @@ -10,16 +10,50 @@ LL + use local::Foo; | error[E0412]: cannot find type `Bar` in this scope - --> $DIR/dont-suggest-foreign-doc-hidden.rs:14:17 + --> $DIR/dont-suggest-foreign-doc-hidden.rs:13:17 | LL | pub fn test2(_: Bar) {} | ^^^ not found in this scope + +error[E0412]: cannot find type `Baz` in this scope + --> $DIR/dont-suggest-foreign-doc-hidden.rs:16:17 + | +LL | pub fn test3(_: Baz) {} + | ^^^ not found in this scope | help: consider importing this struct | -LL + use hidden_struct::Bar; +LL + use hidden_struct::Baz; + | + +error[E0412]: cannot find type `Quux` in this scope + --> $DIR/dont-suggest-foreign-doc-hidden.rs:19:17 + | +LL | pub fn test4(_: Quux) {} + | ^^^^ not found in this scope + | +help: consider importing this struct + | +LL + use hidden_struct::Quux; + | + +error[E0277]: the trait bound `i32: Marker` is not satisfied + --> $DIR/dont-suggest-foreign-doc-hidden.rs:25:13 + | +LL | test5::(); + | ^^^ the trait `Marker` is not implemented for `i32` + | + = help: the following other types implement trait `Marker`: + Baz + Option + Quux +note: required by a bound in `test5` + --> $DIR/dont-suggest-foreign-doc-hidden.rs:22:13 | +LL | fn test5() {} + | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test5` -error: aborting due to 2 previous errors +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0412`. +Some errors have detailed explanations: E0277, E0412. +For more information about an error, try `rustc --explain E0277`. From 79c9f6ee9b3229279ffdaa0515c7b0320c0b0737 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 16 Sep 2025 21:36:45 +1000 Subject: [PATCH 3/8] Stop using `as_c_char_ptr` for coverage-related bindings --- .../rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs | 7 +++---- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 12 +++++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs index bc4f6bb6a82bc..2aa3dec813173 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs @@ -2,7 +2,6 @@ use std::ffi::CString; -use crate::common::AsCCharPtr; use crate::coverageinfo::ffi; use crate::llvm; @@ -34,7 +33,7 @@ pub(crate) fn create_pgo_func_name_var<'ll>( unsafe { llvm::LLVMRustCoverageCreatePGOFuncNameVar( llfn, - mangled_fn_name.as_c_char_ptr(), + mangled_fn_name.as_ptr(), mangled_fn_name.len(), ) } @@ -44,7 +43,7 @@ pub(crate) fn write_filenames_to_buffer(filenames: &[impl AsRef]) -> Vec, Vec<_>>(); llvm::build_byte_buffer(|buffer| unsafe { @@ -89,7 +88,7 @@ pub(crate) fn write_function_mappings_to_buffer( /// Hashes some bytes into a 64-bit hash, via LLVM's `IndexedInstrProf::ComputeHash`, /// as required for parts of the LLVM coverage mapping format. pub(crate) fn hash_bytes(bytes: &[u8]) -> u64 { - unsafe { llvm::LLVMRustCoverageHashBytes(bytes.as_c_char_ptr(), bytes.len()) } + unsafe { llvm::LLVMRustCoverageHashBytes(bytes.as_ptr(), bytes.len()) } } /// Returns LLVM's `coverage::CovMapVersion::CurrentVersion` (CoverageMapping.h) diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 0679f55ab7f08..52c24169f893a 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2080,8 +2080,11 @@ unsafe extern "C" { ConstraintsLen: size_t, ) -> bool; + /// A list of pointer-length strings is passed as two pointer-length slices, + /// one slice containing pointers and one slice containing their corresponding + /// lengths. The implementation will check that both slices have the same length. pub(crate) fn LLVMRustCoverageWriteFilenamesToBuffer( - Filenames: *const *const c_char, + Filenames: *const *const c_uchar, // See "PTR_LEN_STR". FilenamesLen: size_t, Lengths: *const size_t, LengthsLen: size_t, @@ -2104,10 +2107,13 @@ unsafe extern "C" { pub(crate) fn LLVMRustCoverageCreatePGOFuncNameVar( F: &Value, - FuncName: *const c_char, + FuncName: *const c_uchar, // See "PTR_LEN_STR". FuncNameLen: size_t, ) -> &Value; - pub(crate) fn LLVMRustCoverageHashBytes(Bytes: *const c_char, NumBytes: size_t) -> u64; + pub(crate) fn LLVMRustCoverageHashBytes( + Bytes: *const c_uchar, // See "PTR_LEN_STR". + NumBytes: size_t, + ) -> u64; pub(crate) fn LLVMRustCoverageWriteCovmapSectionNameToString(M: &Module, OutStr: &RustString); From 06a7460455284aca27fbf65505c385e3dc275da3 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 16 Sep 2025 21:44:40 +1000 Subject: [PATCH 4/8] Mark some coverage-related bindings as safe --- .../src/coverageinfo/llvm_cov.rs | 8 ++++---- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 16 ++++++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs index 2aa3dec813173..d50eb533ffdbb 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs @@ -6,21 +6,21 @@ use crate::coverageinfo::ffi; use crate::llvm; pub(crate) fn covmap_var_name() -> CString { - CString::new(llvm::build_byte_buffer(|s| unsafe { + CString::new(llvm::build_byte_buffer(|s| { llvm::LLVMRustCoverageWriteCovmapVarNameToString(s); })) .expect("covmap variable name should not contain NUL") } pub(crate) fn covmap_section_name(llmod: &llvm::Module) -> CString { - CString::new(llvm::build_byte_buffer(|s| unsafe { + CString::new(llvm::build_byte_buffer(|s| { llvm::LLVMRustCoverageWriteCovmapSectionNameToString(llmod, s); })) .expect("covmap section name should not contain NUL") } pub(crate) fn covfun_section_name(llmod: &llvm::Module) -> CString { - CString::new(llvm::build_byte_buffer(|s| unsafe { + CString::new(llvm::build_byte_buffer(|s| { llvm::LLVMRustCoverageWriteCovfunSectionNameToString(llmod, s); })) .expect("covfun section name should not contain NUL") @@ -95,5 +95,5 @@ pub(crate) fn hash_bytes(bytes: &[u8]) -> u64 { /// as a raw numeric value. For historical reasons, the numeric value is 1 less /// than the number in the version's name, so `Version7` is actually `6u32`. pub(crate) fn mapping_version() -> u32 { - unsafe { llvm::LLVMRustCoverageMappingVersion() } + llvm::LLVMRustCoverageMappingVersion() } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 52c24169f893a..74251cd2b4949 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2115,13 +2115,17 @@ unsafe extern "C" { NumBytes: size_t, ) -> u64; - pub(crate) fn LLVMRustCoverageWriteCovmapSectionNameToString(M: &Module, OutStr: &RustString); - - pub(crate) fn LLVMRustCoverageWriteCovfunSectionNameToString(M: &Module, OutStr: &RustString); - - pub(crate) fn LLVMRustCoverageWriteCovmapVarNameToString(OutStr: &RustString); + pub(crate) safe fn LLVMRustCoverageWriteCovmapSectionNameToString( + M: &Module, + OutStr: &RustString, + ); + pub(crate) safe fn LLVMRustCoverageWriteCovfunSectionNameToString( + M: &Module, + OutStr: &RustString, + ); + pub(crate) safe fn LLVMRustCoverageWriteCovmapVarNameToString(OutStr: &RustString); - pub(crate) fn LLVMRustCoverageMappingVersion() -> u32; + pub(crate) safe fn LLVMRustCoverageMappingVersion() -> u32; pub(crate) fn LLVMRustDebugMetadataVersion() -> u32; pub(crate) fn LLVMRustVersionMajor() -> u32; pub(crate) fn LLVMRustVersionMinor() -> u32; From adf9cbd69ccd9c1e973fe179fbf3e53b23b4a5ae Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 12 Nov 2024 18:31:54 +0000 Subject: [PATCH 5/8] Add a dummy codegen backend This allows building a rustc capable of running the frontend without any backend present. While this may not seem all that useful, it allows running the frontend of rustc to report errors or running miri to interpret a program without any backend present. This is useful when you are trying to say run miri in the browser as upstream LLVM can't be compiled for wasm yet. Or to run rustc itself in miri like I did a while ago and caught some UB. --- compiler/rustc_interface/src/util.rs | 74 ++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 76ccd12797e5e..6a6e64773f353 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -1,3 +1,4 @@ +use std::any::Any; use std::env::consts::{DLL_PREFIX, DLL_SUFFIX}; use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicBool, Ordering}; @@ -6,13 +7,20 @@ use std::{env, thread}; use rustc_ast as ast; use rustc_attr_parsing::{ShouldEmit, validate_attr}; +use rustc_codegen_ssa::back::archive::ArArchiveBuilderBuilder; +use rustc_codegen_ssa::back::link::link_binary; use rustc_codegen_ssa::traits::CodegenBackend; +use rustc_codegen_ssa::{CodegenResults, CrateInfo}; +use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::jobserver::Proxy; use rustc_data_structures::sync; use rustc_errors::LintBuffer; -use rustc_metadata::{DylibError, load_symbol_from_dylib}; -use rustc_middle::ty::CurrentGcx; -use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple}; +use rustc_metadata::{DylibError, EncodedMetadata, load_symbol_from_dylib}; +use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::ty::{CurrentGcx, TyCtxt}; +use rustc_session::config::{ + Cfg, CrateType, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple, +}; use rustc_session::output::{CRATE_TYPES, categorize_crate_type}; use rustc_session::{EarlyDiagCtxt, Session, filesearch, lint}; use rustc_span::edit_distance::find_best_match_for_name; @@ -316,12 +324,13 @@ pub fn get_codegen_backend( let backend = backend_name .or(target.default_codegen_backend.as_deref()) .or(option_env!("CFG_DEFAULT_CODEGEN_BACKEND")) - .unwrap_or("llvm"); + .unwrap_or("dummy"); match backend { filename if filename.contains('.') => { load_backend_from_dylib(early_dcx, filename.as_ref()) } + "dummy" => || Box::new(DummyCodegenBackend), #[cfg(feature = "llvm")] "llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new, backend_name => get_codegen_sysroot(early_dcx, sysroot, backend_name), @@ -334,6 +343,63 @@ pub fn get_codegen_backend( unsafe { load() } } +struct DummyCodegenBackend; + +impl CodegenBackend for DummyCodegenBackend { + fn locale_resource(&self) -> &'static str { + "" + } + + fn name(&self) -> &'static str { + "dummy" + } + + fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box { + Box::new(CodegenResults { + modules: vec![], + allocator_module: None, + crate_info: CrateInfo::new(tcx, String::new()), + }) + } + + fn join_codegen( + &self, + ongoing_codegen: Box, + _sess: &Session, + _outputs: &OutputFilenames, + ) -> (CodegenResults, FxIndexMap) { + (*ongoing_codegen.downcast().unwrap(), FxIndexMap::default()) + } + + fn link( + &self, + sess: &Session, + codegen_results: CodegenResults, + metadata: EncodedMetadata, + outputs: &OutputFilenames, + ) { + // JUSTIFICATION: TyCtxt no longer available here + #[allow(rustc::bad_opt_access)] + if sess.opts.crate_types.iter().any(|&crate_type| crate_type != CrateType::Rlib) { + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] + sess.dcx().fatal(format!( + "crate type {} not supported by the dummy codegen backend", + sess.opts.crate_types[0], + )); + } + + link_binary( + sess, + &ArArchiveBuilderBuilder, + codegen_results, + metadata, + outputs, + self.name(), + ); + } +} + // This is used for rustdoc, but it uses similar machinery to codegen backend // loading, so we leave the code here. It is potentially useful for other tools // that want to invoke the rustc binary while linking to rustc as well. From 817e181ee80256d93156bbb8ba0a1daafb3cf4fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 29 Sep 2025 15:00:10 +0200 Subject: [PATCH 6/8] test bevy compute_implied_bounds hack with new trait solver --- tests/ui/implied-bounds/bevy_world_query.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/ui/implied-bounds/bevy_world_query.rs b/tests/ui/implied-bounds/bevy_world_query.rs index 6548c03d1b00c..e2750bcf957ea 100644 --- a/tests/ui/implied-bounds/bevy_world_query.rs +++ b/tests/ui/implied-bounds/bevy_world_query.rs @@ -1,6 +1,8 @@ -#![crate_name = "bevy_ecs"] - //@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +#![crate_name = "bevy_ecs"] // We currently special case bevy from erroring on incorrect implied bounds // from normalization (issue #109628). From cbaec31c10c5eff7342e5273360521911fbf7631 Mon Sep 17 00:00:00 2001 From: Josh Simmons Date: Thu, 26 Jun 2025 21:31:05 +0200 Subject: [PATCH 7/8] Add fast-path for accessing the current thread id Accessing the thread id is often used in profiling and debugging, as well as some approaches for sound single-threaded access to data. Currently the only way to access the thread id is by first obtaining a handle to the current thread. While this is not exactly slow, it does require an atomic inc-ref and dec-ref operation, as well as the injection of `Thread`'s drop code into the caller. This publicly exposes the existing fast-path for accessing the current thread id. --- library/std/src/thread/current.rs | 24 ++++++++++++++++++++++-- library/std/src/thread/mod.rs | 4 +++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/library/std/src/thread/current.rs b/library/std/src/thread/current.rs index 7da1621da45ce..f00212bfcb617 100644 --- a/library/std/src/thread/current.rs +++ b/library/std/src/thread/current.rs @@ -133,12 +133,32 @@ pub(super) fn set_current(thread: Thread) -> Result<(), Thread> { Ok(()) } -/// Gets the id of the thread that invokes it. +/// Gets the unique identifier of the thread which invokes it. +/// +/// Calling this function may be more efficient than accessing the current +/// thread id through the current thread handle. i.e. `thread::current().id()`. /// /// This function will always succeed, will always return the same value for /// one thread and is guaranteed not to call the global allocator. +/// +/// # Examples +/// +/// ``` +/// #![feature(current_thread_id)] +/// +/// use std::thread; +/// +/// let other_thread = thread::spawn(|| { +/// thread::current_id() +/// }); +/// +/// let other_thread_id = other_thread.join().unwrap(); +/// assert_ne!(thread::current_id(), other_thread_id); +/// ``` #[inline] -pub(crate) fn current_id() -> ThreadId { +#[must_use] +#[unstable(feature = "current_thread_id", issue = "147194")] +pub fn current_id() -> ThreadId { // If accessing the persistent thread ID takes multiple TLS accesses, try // to retrieve it from the current thread handle, which will only take one // TLS access. diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 4d09b2b4e9d2e..1768369792ae2 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -183,7 +183,9 @@ mod current; #[stable(feature = "rust1", since = "1.0.0")] pub use current::current; -pub(crate) use current::{current_id, current_or_unnamed, current_os_id, drop_current}; +#[unstable(feature = "current_thread_id", issue = "147194")] +pub use current::current_id; +pub(crate) use current::{current_or_unnamed, current_os_id, drop_current}; use current::{set_current, try_with_current}; mod spawnhook; From 80e598bb12297c5df04e5b380a4f51aa4dfc5d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 30 Sep 2025 13:29:39 +0200 Subject: [PATCH 8/8] clone region obligations instead of taking in implied bounds hack --- compiler/rustc_infer/src/infer/outlives/obligations.rs | 4 ++++ .../src/traits/query/type_op/implied_outlives_bounds.rs | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index b989d419057b1..a640dcb1b4e1e 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -170,6 +170,10 @@ impl<'tcx> InferCtxt<'tcx> { std::mem::take(&mut self.inner.borrow_mut().region_obligations) } + pub fn clone_registered_region_obligations(&self) -> Vec> { + self.inner.borrow().region_obligations.clone() + } + pub fn register_region_assumption(&self, assumption: ty::ArgOutlivesPredicate<'tcx>) { let mut inner = self.inner.borrow_mut(); inner.undo_log.push(UndoLog::PushRegionAssumption); diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index 7540cbe3fd1a4..e55ffb4d5fdb9 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -55,6 +55,12 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( span: Span, disable_implied_bounds_hack: bool, ) -> Result>, NoSolution> { + // Inside mir borrowck, each computation starts with an empty list. + assert!( + ocx.infcx.inner.borrow().region_obligations().is_empty(), + "compute_implied_outlives_bounds assumes region obligations are empty before starting" + ); + let normalize_ty = |ty| -> Result<_, NoSolution> { // We must normalize the type so we can compute the right outlives components. // for example, if we have some constrained param type like `T: Trait`, @@ -143,7 +149,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( && ty.visit_with(&mut ContainsBevyParamSet { tcx: ocx.infcx.tcx }).is_break() { for TypeOutlivesConstraint { sup_type, sub_region, .. } in - ocx.infcx.take_registered_region_obligations() + ocx.infcx.clone_registered_region_obligations() { let mut components = smallvec![]; push_outlives_components(ocx.infcx.tcx, sup_type, &mut components);