From a5e4dc9a9abcf10b36f1fd1fef2051b13aa0098a Mon Sep 17 00:00:00 2001 From: Pieter-Louis Schoeman Date: Thu, 28 May 2026 16:23:43 +0000 Subject: [PATCH 01/26] Handle generic reborrow in expression-use adjustment walking * Handle generic reborrow in expression-use adjustment walking * Require generic reborrow to be terminal in adjustment walks --- .../rustc_hir_typeck/src/expr_use_visitor.rs | 17 +++++----- ...neric-reborrow-expr-use-visitor-closure.rs | 34 +++++++++++++++++++ .../generic-reborrow-expr-use-visitor.rs | 32 +++++++++++++++++ 3 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 tests/ui/reborrow/generic-reborrow-expr-use-visitor-closure.rs create mode 100644 tests/ui/reborrow/generic-reborrow-expr-use-visitor.rs diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index a924a81f89b0d..7b39b953e3be0 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -727,7 +727,8 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx let typeck_results = self.cx.typeck_results(); let adjustments = typeck_results.expr_adjustments(expr); let mut place_with_id = self.cat_expr_unadjusted(expr)?; - for adjustment in adjustments { + for (adjustment_index, adjustment) in adjustments.iter().enumerate() { + let is_last_adjustment = adjustment_index + 1 == adjustments.len(); debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment); match adjustment.kind { adjustment::Adjust::NeverToAny | adjustment::Adjust::Pointer(_) => { @@ -752,13 +753,13 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx self.walk_autoref(expr, &place_with_id, autoref); } - adjustment::Adjust::GenericReborrow(_reborrow) => { - // To build an expression as a place expression, it needs to be a field - // projection or deref at the outmost layer. So it is field projection or deref - // on an adjusted value. But this means that adjustment is applied on a - // subexpression that is not the final operand/rvalue for function call or - // assignment. This is a contradiction. - unreachable!("Reborrow trait usage during adjustment walk"); + adjustment::Adjust::GenericReborrow(mutability) if is_last_adjustment => { + let bk = ty::BorrowKind::from_mutbl(mutability); + self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk); + } + + adjustment::Adjust::GenericReborrow(_) => { + span_bug!(expr.span, "generic reborrow adjustment must be terminal"); } } place_with_id = self.cat_expr_adjusted(expr, place_with_id, adjustment)?; diff --git a/tests/ui/reborrow/generic-reborrow-expr-use-visitor-closure.rs b/tests/ui/reborrow/generic-reborrow-expr-use-visitor-closure.rs new file mode 100644 index 0000000000000..c28cb1ef4fda4 --- /dev/null +++ b/tests/ui/reborrow/generic-reborrow-expr-use-visitor-closure.rs @@ -0,0 +1,34 @@ +//@ check-pass + +#![feature(reborrow)] + +use std::marker::{CoerceShared, Reborrow}; + +#[allow(unused)] +struct CustomMut<'a, T>(&'a mut T); +impl<'a, T> Reborrow for CustomMut<'a, T> {} +impl<'a, T> CoerceShared> for CustomMut<'a, T> {} + +#[allow(unused)] +struct CustomRef<'a, T>(&'a T); +impl<'a, T> Clone for CustomRef<'a, T> { + fn clone(&self) -> Self { + Self(self.0) + } +} +impl<'a, T> Copy for CustomRef<'a, T> {} + +fn takes_mut(_: CustomMut<'_, ()>) {} +fn takes_shared(_: CustomRef<'_, ()>) {} + +fn main() { + let a = CustomMut(&mut ()); + + let mut f = || { + takes_mut(a); + takes_shared(a); + }; + + f(); + f(); +} diff --git a/tests/ui/reborrow/generic-reborrow-expr-use-visitor.rs b/tests/ui/reborrow/generic-reborrow-expr-use-visitor.rs new file mode 100644 index 0000000000000..d513577e901a0 --- /dev/null +++ b/tests/ui/reborrow/generic-reborrow-expr-use-visitor.rs @@ -0,0 +1,32 @@ +//@ check-pass + +#![feature(reborrow)] + +use std::marker::{CoerceShared, Reborrow}; + +#[allow(unused)] +struct CustomMut<'a, T>(&'a mut T); +impl<'a, T> Reborrow for CustomMut<'a, T> {} +impl<'a, T> CoerceShared> for CustomMut<'a, T> {} + +#[allow(unused)] +struct CustomRef<'a, T>(&'a T); +impl<'a, T> Clone for CustomRef<'a, T> { + fn clone(&self) -> Self { + Self(self.0) + } +} +impl<'a, T> Copy for CustomRef<'a, T> {} + +fn takes_mut(_: CustomMut<'_, ()>) {} +fn takes_shared(_: CustomRef<'_, ()>) {} + +fn main() { + let a = CustomMut(&mut ()); + + takes_mut(a); + takes_mut(a); + + takes_shared(a); + takes_shared(a); +} From 640d7ae06d2d0f205bf3920d26fda730de5ff6aa Mon Sep 17 00:00:00 2001 From: XMH <970252187@qq.com> Date: Wed, 10 Jun 2026 14:56:00 +0800 Subject: [PATCH 02/26] Update task.rs --- library/alloc/src/task.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs index bc668f78bf740..45c22b845799d 100644 --- a/library/alloc/src/task.rs +++ b/library/alloc/src/task.rs @@ -37,6 +37,10 @@ use crate::sync::Arc; /// link ../../std/task/struct.Waker.html#impl-From%3CArc%3CW,+Global%3E%3E-for-Waker /// without getting a link-checking error in CI. --> /// +/// # Memory Ordering +/// +/// To avoid missed wakeups, all runtimes must adhere to the requirement described for [`Waker::wake`]. +/// /// # Examples /// /// A basic `block_on` function that takes a future and runs it to completion on From 4671f48aa62496dfbd6c017dd289f6a59447b2a9 Mon Sep 17 00:00:00 2001 From: XMH <970252187@qq.com> Date: Wed, 10 Jun 2026 15:02:29 +0800 Subject: [PATCH 03/26] Update wake.rs --- library/core/src/task/wake.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 14f0980ff6045..0d50f9151e181 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -432,6 +432,13 @@ impl Waker { /// executor’s choice which task to run and the executor may choose to run the /// current task again. /// + /// To avoid missed wakeups, runtimes must ensure that for any call to `wake`, + /// there is a subsequent call to `poll` such that the `wake()` return _happens-before_ + /// the beginning of the invocation of `poll`. + /// In particular, this means that if a task self-wakes (invokes `wake` on itself during `poll`), + /// then the `poll` must be invoked again because the call to `wake` _happens-after_ the beginning + /// of the current invocation of `poll`. + /// /// [`poll()`]: crate::future::Future::poll #[inline] #[stable(feature = "futures_api", since = "1.36.0")] From 452882786afde92ac75b87f6be05b83b2fe8f3be Mon Sep 17 00:00:00 2001 From: XMH <970252187@qq.com> Date: Wed, 10 Jun 2026 15:41:12 +0800 Subject: [PATCH 04/26] Update wake.rs --- library/core/src/task/wake.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 0d50f9151e181..c184225778f9d 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -433,7 +433,7 @@ impl Waker { /// current task again. /// /// To avoid missed wakeups, runtimes must ensure that for any call to `wake`, - /// there is a subsequent call to `poll` such that the `wake()` return _happens-before_ + /// there is a subsequent call to `poll` such that the `wake()` _happens-before_ /// the beginning of the invocation of `poll`. /// In particular, this means that if a task self-wakes (invokes `wake` on itself during `poll`), /// then the `poll` must be invoked again because the call to `wake` _happens-after_ the beginning From 61aa16370b53d07c397812040210aede961ef34d Mon Sep 17 00:00:00 2001 From: XMH <970252187@qq.com> Date: Wed, 10 Jun 2026 16:10:30 +0800 Subject: [PATCH 05/26] Update library/core/src/task/wake.rs Co-authored-by: Alice Ryhl --- library/core/src/task/wake.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index c184225778f9d..732a1855989ce 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -433,7 +433,7 @@ impl Waker { /// current task again. /// /// To avoid missed wakeups, runtimes must ensure that for any call to `wake`, - /// there is a subsequent call to `poll` such that the `wake()` _happens-before_ + /// there is a subsequent call to `poll` such that the call to `wake()` _happens-before_ /// the beginning of the invocation of `poll`. /// In particular, this means that if a task self-wakes (invokes `wake` on itself during `poll`), /// then the `poll` must be invoked again because the call to `wake` _happens-after_ the beginning From c5c5e814c6933a1d4a71332f6de68ba1e30c42d7 Mon Sep 17 00:00:00 2001 From: XMH <970252187@qq.com> Date: Wed, 10 Jun 2026 16:20:09 +0800 Subject: [PATCH 06/26] Update wake.rs --- library/core/src/task/wake.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 732a1855989ce..1428762db6234 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -434,7 +434,7 @@ impl Waker { /// /// To avoid missed wakeups, runtimes must ensure that for any call to `wake`, /// there is a subsequent call to `poll` such that the call to `wake()` _happens-before_ - /// the beginning of the invocation of `poll`. + /// the beginning of the invocation of `poll`. /// In particular, this means that if a task self-wakes (invokes `wake` on itself during `poll`), /// then the `poll` must be invoked again because the call to `wake` _happens-after_ the beginning /// of the current invocation of `poll`. From e65db4278bd9612d4145741dd9657ddcbea942cd Mon Sep 17 00:00:00 2001 From: XMH <970252187@qq.com> Date: Wed, 10 Jun 2026 17:51:02 +0800 Subject: [PATCH 07/26] Update library/core/src/task/wake.rs Co-authored-by: Alice Ryhl --- library/core/src/task/wake.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 1428762db6234..89c39e8b7836a 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -432,12 +432,13 @@ impl Waker { /// executor’s choice which task to run and the executor may choose to run the /// current task again. /// - /// To avoid missed wakeups, runtimes must ensure that for any call to `wake`, - /// there is a subsequent call to `poll` such that the call to `wake()` _happens-before_ - /// the beginning of the invocation of `poll`. - /// In particular, this means that if a task self-wakes (invokes `wake` on itself during `poll`), - /// then the `poll` must be invoked again because the call to `wake` _happens-after_ the beginning - /// of the current invocation of `poll`. + /// To avoid missed wakeups, runtimes must ensure that for any call to + /// `wake`, there is a subsequent call to `poll` such that the call to + /// `wake()` _happens-before_ the beginning of the invocation of `poll`. In + /// particular, this means that if a task self-wakes (invokes `wake` on + /// itself during `poll`), then the `poll` must be invoked again because the + /// call to `wake` _happens-after_ the beginning of the current invocation + /// of `poll`. /// /// [`poll()`]: crate::future::Future::poll #[inline] From 16ccf8e66ca9ef666f7ba76f863cc7c2a6f24ec2 Mon Sep 17 00:00:00 2001 From: XMH <970252187@qq.com> Date: Thu, 11 Jun 2026 09:46:23 +0800 Subject: [PATCH 08/26] Update library/alloc/src/task.rs Co-authored-by: Kevin Reid --- library/alloc/src/task.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs index 45c22b845799d..0e36c91f466fd 100644 --- a/library/alloc/src/task.rs +++ b/library/alloc/src/task.rs @@ -39,7 +39,7 @@ use crate::sync::Arc; /// /// # Memory Ordering /// -/// To avoid missed wakeups, all runtimes must adhere to the requirement described for [`Waker::wake`]. +/// To avoid missed wakeups, all executors must adhere to the requirement described for [`Waker::wake`]. /// /// # Examples /// From a0ecf25ca93d432786c0f5428eed76dd549ac8c8 Mon Sep 17 00:00:00 2001 From: XMH <970252187@qq.com> Date: Thu, 11 Jun 2026 09:46:38 +0800 Subject: [PATCH 09/26] Update library/core/src/task/wake.rs Co-authored-by: Kevin Reid --- library/core/src/task/wake.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 89c39e8b7836a..c3f7672a61a37 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -432,7 +432,7 @@ impl Waker { /// executor’s choice which task to run and the executor may choose to run the /// current task again. /// - /// To avoid missed wakeups, runtimes must ensure that for any call to + /// To avoid missed wakeups, executors must ensure that for any call to /// `wake`, there is a subsequent call to `poll` such that the call to /// `wake()` _happens-before_ the beginning of the invocation of `poll`. In /// particular, this means that if a task self-wakes (invokes `wake` on From 0954d4c64447fcce89c388af8d13e473db43b383 Mon Sep 17 00:00:00 2001 From: XMH <970252187@qq.com> Date: Fri, 12 Jun 2026 13:52:01 +0800 Subject: [PATCH 10/26] Update wake.rs --- library/core/src/task/wake.rs | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index c3f7672a61a37..bdf6c59a80b80 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -418,28 +418,21 @@ unsafe impl Sync for Waker {} impl Waker { /// Wakes up the task associated with this `Waker`. /// - /// As long as the executor keeps running and the task is not finished, it is - /// guaranteed that each invocation of [`wake()`](Self::wake) (or + /// As long as the executor keeps running and the task is not finished, + /// it is guaranteed that each invocation of [`wake()`](Self::wake) (or /// [`wake_by_ref()`](Self::wake_by_ref)) will be followed by at least one - /// [`poll()`] of the task to which this `Waker` belongs. This makes - /// it possible to temporarily yield to other tasks while running potentially - /// unbounded processing loops. + /// [`poll()`] of the task to which this `Waker` belongs, and the call to + /// [`wake()`](Self::wake) (or [`wake_by_ref()`](Self::wake_by_ref)) _happens-before_ + /// the beginning of the invocation of [`poll()`]. This makes it possible to temporarily + /// yield to other tasks while running potentially unbounded processing loops. /// /// Note that the above implies that multiple wake-ups may be coalesced into a - /// single [`poll()`] invocation by the runtime. + /// single [`poll()`] invocation by the executor. /// /// Also note that yielding to competing tasks is not guaranteed: it is the /// executor’s choice which task to run and the executor may choose to run the /// current task again. /// - /// To avoid missed wakeups, executors must ensure that for any call to - /// `wake`, there is a subsequent call to `poll` such that the call to - /// `wake()` _happens-before_ the beginning of the invocation of `poll`. In - /// particular, this means that if a task self-wakes (invokes `wake` on - /// itself during `poll`), then the `poll` must be invoked again because the - /// call to `wake` _happens-after_ the beginning of the current invocation - /// of `poll`. - /// /// [`poll()`]: crate::future::Future::poll #[inline] #[stable(feature = "futures_api", since = "1.36.0")] From 42538cac1a8c47f1635abe328a7f9fd997fa9b8d Mon Sep 17 00:00:00 2001 From: XMH <970252187@qq.com> Date: Mon, 15 Jun 2026 14:11:06 +0800 Subject: [PATCH 11/26] Update library/core/src/task/wake.rs Co-authored-by: Alice Ryhl --- library/core/src/task/wake.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index bdf6c59a80b80..63b7691582a7d 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -421,7 +421,7 @@ impl Waker { /// As long as the executor keeps running and the task is not finished, /// it is guaranteed that each invocation of [`wake()`](Self::wake) (or /// [`wake_by_ref()`](Self::wake_by_ref)) will be followed by at least one - /// [`poll()`] of the task to which this `Waker` belongs, and the call to + /// [`poll()`] of the task to which this `Waker` belongs, such that the call to /// [`wake()`](Self::wake) (or [`wake_by_ref()`](Self::wake_by_ref)) _happens-before_ /// the beginning of the invocation of [`poll()`]. This makes it possible to temporarily /// yield to other tasks while running potentially unbounded processing loops. From c3fc863f27dbce61babc1932f2a5be4e9e50a40c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 15 Jun 2026 22:34:45 +0200 Subject: [PATCH 12/26] Make `proc_macro::ConversionErrorKind` non exhaustive --- library/proc_macro/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index e335fe1c70264..98b00c600f5ef 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -197,6 +197,7 @@ impl fmt::Display for EscapeError { /// Errors returned when trying to retrieve a literal unescaped value. #[unstable(feature = "proc_macro_value", issue = "136652")] #[derive(Debug, PartialEq, Eq)] +#[non_exhaustive] pub enum ConversionErrorKind { /// The literal failed to be escaped, take a look at [`EscapeError`] for more information. FailedToUnescape(EscapeError), From d8953cd1146473ec633f9850c97aa8021cd54137 Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Wed, 17 Jun 2026 13:24:04 +1000 Subject: [PATCH 13/26] Document Panic in `get_module_children` Also replicated documentation on `TyCtxt::module_children` --- compiler/rustc_metadata/src/rmeta/decoder.rs | 8 +++++++- compiler/rustc_middle/src/queries.rs | 9 +++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 1cc789f6bcaa3..bd3b2445759e7 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1274,6 +1274,10 @@ impl CrateMetadata { /// including both proper items and reexports. /// Module here is understood in name resolution sense - it can be a `mod` item, /// or a crate root, or an enum, or a trait. + /// + /// # Panics + /// + /// May panic if the provided `id` does not refer to a module. fn get_module_children(&self, tcx: TyCtxt<'_>, id: DefIndex) -> impl Iterator { gen move { if let Some(data) = &self.root.proc_macro_data { @@ -1287,7 +1291,9 @@ impl CrateMetadata { } else { // Iterate over all children. let non_reexports = self.root.tables.module_children_non_reexports.get(self, id); - for child_index in non_reexports.unwrap().decode((self, tcx)) { + let non_reexports = + non_reexports.expect("provided `DefIndex` must refer to a module-like item"); + for child_index in non_reexports.decode((self, tcx)) { yield self.get_mod_child(tcx, child_index); } diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index c01ff3d5d0561..d4817888468fa 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -2161,6 +2161,15 @@ rustc_queries! { desc { "fetching what a crate is named" } separate_provide_extern } + + /// Iterates over all named children of the given module, + /// including both proper items and reexports. + /// Module here is understood in name resolution sense - it can be a `mod` item, + /// or a crate root, or an enum, or a trait. + /// + /// # Panics + /// + /// May panic if the provided `id` does not refer to a module. query module_children(def_id: DefId) -> &'tcx [ModChild] { desc { "collecting child items of module `{}`", tcx.def_path_str(def_id) } separate_provide_extern From b8d7dcb0696417e0190e8740ee3d9da8f7a16e54 Mon Sep 17 00:00:00 2001 From: Kevin Valerio Date: Wed, 17 Jun 2026 17:06:42 +0200 Subject: [PATCH 14/26] fix(thir): visit reborrow source expressions --- compiler/rustc_middle/src/thir/visit.rs | 2 +- tests/ui/reborrow/reborrow-source-unsafety.rs | 28 +++++++++++++++++++ .../reborrow/reborrow-source-unsafety.stderr | 11 ++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tests/ui/reborrow/reborrow-source-unsafety.rs create mode 100644 tests/ui/reborrow/reborrow-source-unsafety.stderr diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index a96f4e9457cb0..f1f3e2d98b226 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -187,7 +187,7 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( } ThreadLocalRef(_) => {} Yield { value } => visitor.visit_expr(&visitor.thir()[value]), - Reborrow { .. } => {} + Reborrow { source, .. } => visitor.visit_expr(&visitor.thir()[source]), } } diff --git a/tests/ui/reborrow/reborrow-source-unsafety.rs b/tests/ui/reborrow/reborrow-source-unsafety.rs new file mode 100644 index 0000000000000..e6f3540768a44 --- /dev/null +++ b/tests/ui/reborrow/reborrow-source-unsafety.rs @@ -0,0 +1,28 @@ +// Regression test for rust-lang/rust#158033. + +#![feature(reborrow)] +#![allow(dead_code)] +#![deny(unsafe_code)] + +use std::marker::Reborrow; + +struct Thing<'a> { + field: &'a mut usize, +} + +impl<'a> Reborrow for Thing<'a> {} + +fn takes(_: Thing<'_>) {} + +fn main() { + let mut x = 0; + let thing = Thing { field: &mut x }; + let y = 123usize; + + takes({ + let p: *const usize = &y; + std::hint::black_box(std::ptr::read(p)); + //~^ ERROR call to unsafe function `std::ptr::read` is unsafe + thing + }); +} diff --git a/tests/ui/reborrow/reborrow-source-unsafety.stderr b/tests/ui/reborrow/reborrow-source-unsafety.stderr new file mode 100644 index 0000000000000..431893a4d0ced --- /dev/null +++ b/tests/ui/reborrow/reborrow-source-unsafety.stderr @@ -0,0 +1,11 @@ +error[E0133]: call to unsafe function `std::ptr::read` is unsafe and requires unsafe function or block + --> $DIR/reborrow-source-unsafety.rs:24:30 + | +LL | std::hint::black_box(std::ptr::read(p)); + | ^^^^^^^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0133`. From a487aec39ae75c92fe6f0e3dccb83f07c224c5ef Mon Sep 17 00:00:00 2001 From: Kevin Valerio <24193167+kevin-valerio@users.noreply.github.com> Date: Wed, 17 Jun 2026 17:58:52 +0200 Subject: [PATCH 15/26] Match all fields and removing `..` Co-authored-by: Timo <30553356+y21@users.noreply.github.com> --- compiler/rustc_middle/src/thir/visit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index f1f3e2d98b226..e3366e74b5f26 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -187,7 +187,7 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( } ThreadLocalRef(_) => {} Yield { value } => visitor.visit_expr(&visitor.thir()[value]), - Reborrow { source, .. } => visitor.visit_expr(&visitor.thir()[source]), + Reborrow { source, mutability: _, target: _ } => visitor.visit_expr(&visitor.thir()[source]), } } From ef672ad0120cab59576e245df472bd662af29e45 Mon Sep 17 00:00:00 2001 From: Kevin Valerio Date: Wed, 17 Jun 2026 18:14:59 +0200 Subject: [PATCH 16/26] format reborrow visitor arm --- compiler/rustc_middle/src/thir/visit.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index e3366e74b5f26..24aa4ac513d45 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -187,7 +187,9 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( } ThreadLocalRef(_) => {} Yield { value } => visitor.visit_expr(&visitor.thir()[value]), - Reborrow { source, mutability: _, target: _ } => visitor.visit_expr(&visitor.thir()[source]), + Reborrow { source, mutability: _, target: _ } => { + visitor.visit_expr(&visitor.thir()[source]) + } } } From 36f5b3f260e6e16a5e32fd50f4946e760493b32a Mon Sep 17 00:00:00 2001 From: Valentyn Kit Date: Wed, 17 Jun 2026 22:58:37 +0300 Subject: [PATCH 17/26] Document transient connection errors from TcpListener::accept `accept` can return an error that belongs to a single incoming connection, not to the listener itself, for example a connection aborted by the peer before it could be accepted. The listener stays usable in that case, so code serving a long-lived listener usually wants to log the error and keep accepting connections rather than treat it as fatal. This was previously undocumented. - Add an `# Errors` section to `accept` that describes this behavior without listing specific error codes. - Note that `Interrupted` errors are retried internally on Unix. - Point `incoming` and `into_incoming` at `accept` for the same details. --- library/std/src/net/tcp.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs index 2e8779e05ca76..53bef0b4de609 100644 --- a/library/std/src/net/tcp.rs +++ b/library/std/src/net/tcp.rs @@ -876,6 +876,22 @@ impl TcpListener { /// is established. When established, the corresponding [`TcpStream`] and the /// remote peer's address will be returned. /// + /// # Errors + /// + /// Some errors returned by this function relate to a single incoming + /// connection that failed before it could be accepted, such as one aborted + /// by the peer ([`ConnectionAborted`]). Such an error does not indicate a + /// problem with the listener itself, which remains usable. Code serving a + /// long-lived listener will usually want to log the error and continue + /// accepting connections rather than treat it as fatal. Which errors can + /// occur this way is platform-specific. + /// + /// On Unix, [`Interrupted`] errors are retried internally rather than being + /// returned. + /// + /// [`ConnectionAborted`]: io::ErrorKind::ConnectionAborted + /// [`Interrupted`]: io::ErrorKind::Interrupted + /// /// # Examples /// /// ```no_run @@ -902,6 +918,11 @@ impl TcpListener { /// the peer's [`SocketAddr`] structure. Iterating over it is equivalent to /// calling [`TcpListener::accept`] in a loop. /// + /// # Errors + /// + /// Each connection yielded by the iterator can fail for the same reasons as + /// [`TcpListener::accept`]; see its documentation for details. + /// /// # Examples /// /// ```no_run @@ -937,6 +958,11 @@ impl TcpListener { /// the peer's [`SocketAddr`] structure. Iterating over it is equivalent to /// calling [`TcpListener::accept`] in a loop. /// + /// # Errors + /// + /// Each connection yielded by the iterator can fail for the same reasons as + /// [`TcpListener::accept`]; see its documentation for details. + /// /// # Examples /// /// ```no_run From 7786ffce5b9f2f5870cc8bc4dafbc7e04336ac3e Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Thu, 18 Jun 2026 11:57:21 +0200 Subject: [PATCH 18/26] Bump thin-vec to 0.2.18 to address RUSTSEC-2026-0103 thin-vec versions before 0.2.16 have a use-after-free / double-free in `IntoIter::drop` and `ThinVec::clear` when an element's `Drop` panics (RUSTSEC-2026-0103). The requirement now sits past the affected range. --- Cargo.lock | 4 ++-- compiler/rustc_ast/Cargo.toml | 2 +- compiler/rustc_ast_lowering/Cargo.toml | 2 +- compiler/rustc_ast_passes/Cargo.toml | 2 +- compiler/rustc_ast_pretty/Cargo.toml | 2 +- compiler/rustc_attr_parsing/Cargo.toml | 2 +- compiler/rustc_builtin_macros/Cargo.toml | 2 +- compiler/rustc_data_structures/Cargo.toml | 2 +- compiler/rustc_expand/Cargo.toml | 2 +- compiler/rustc_hir/Cargo.toml | 2 +- compiler/rustc_infer/Cargo.toml | 2 +- compiler/rustc_middle/Cargo.toml | 2 +- compiler/rustc_parse/Cargo.toml | 2 +- compiler/rustc_resolve/Cargo.toml | 2 +- compiler/rustc_serialize/Cargo.toml | 2 +- compiler/rustc_trait_selection/Cargo.toml | 2 +- compiler/rustc_type_ir/Cargo.toml | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b17c0d309cba..2a452170f3f7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5554,9 +5554,9 @@ dependencies = [ [[package]] name = "thin-vec" -version = "0.2.15" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da322882471314edc77fa5232c587bcb87c9df52bfd0d7d4826f8868ead61899" +checksum = "b0f7e269b48f0a7dd0146680fa24b50cc67fc0373f086a5b2f99bd084639b482" [[package]] name = "thiserror" diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index 97256963118f3..a09c36efe01f6 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -15,6 +15,6 @@ rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.15" +thin-vec = "0.2.18" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index f9c08de02512f..0fefc0d9220a3 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -22,6 +22,6 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.15" +thin-vec = "0.2.18" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml index 42cbd7b3d3620..da9b4633fdae9 100644 --- a/compiler/rustc_ast_passes/Cargo.toml +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -18,5 +18,5 @@ rustc_macros = { path = "../rustc_macros" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } -thin-vec = "0.2.15" +thin-vec = "0.2.18" # tidy-alphabetical-end diff --git a/compiler/rustc_ast_pretty/Cargo.toml b/compiler/rustc_ast_pretty/Cargo.toml index 957fc1297c58e..70da6ba0591ce 100644 --- a/compiler/rustc_ast_pretty/Cargo.toml +++ b/compiler/rustc_ast_pretty/Cargo.toml @@ -13,5 +13,5 @@ rustc_span = { path = "../rustc_span" } [dev-dependencies] # tidy-alphabetical-start -thin-vec = "0.2.15" +thin-vec = "0.2.18" # tidy-alphabetical-end diff --git a/compiler/rustc_attr_parsing/Cargo.toml b/compiler/rustc_attr_parsing/Cargo.toml index fccc36a128057..2e8c912609b2e 100644 --- a/compiler/rustc_attr_parsing/Cargo.toml +++ b/compiler/rustc_attr_parsing/Cargo.toml @@ -20,5 +20,5 @@ rustc_parse_format = { path = "../rustc_parse_format" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } -thin-vec = "0.2.15" +thin-vec = "0.2.18" # tidy-alphabetical-end diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index ebf25d68314db..f5dbc4a0d7cbe 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -29,7 +29,7 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.15" +thin-vec = "0.2.18" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index c428810e54117..6db3a624500a9 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -30,7 +30,7 @@ smallvec = { version = "1.8.1", features = [ ] } stacker = "0.1.17" tempfile = "3.2" -thin-vec = "0.2.15" +thin-vec = "0.2.18" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml index 0154d05266fd7..068c84da719a3 100644 --- a/compiler/rustc_expand/Cargo.toml +++ b/compiler/rustc_expand/Cargo.toml @@ -30,6 +30,6 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } scoped-tls = "1.0" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.15" +thin-vec = "0.2.18" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index c9e54c9bf71d8..5765163af6e41 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -23,6 +23,6 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.15" +thin-vec = "0.2.18" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index 1896ce10faf2f..33f7e2f38f765 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -17,6 +17,6 @@ rustc_middle = { path = "../rustc_middle" } rustc_span = { path = "../rustc_span" } rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.15" +thin-vec = "0.2.18" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index f0e47e0075ff6..6ead1c5ea46a3 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -33,7 +33,7 @@ rustc_target = { path = "../rustc_target" } rustc_thread_pool = { path = "../rustc_thread_pool" } rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.15" +thin-vec = "0.2.18" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml index 53727efb46501..22ec84231af49 100644 --- a/compiler/rustc_parse/Cargo.toml +++ b/compiler/rustc_parse/Cargo.toml @@ -17,7 +17,7 @@ rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } -thin-vec = "0.2.15" +thin-vec = "0.2.18" tracing = "0.1" unicode-normalization = "0.1.25" unicode-width = "0.2.2" diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index 2fc251e2b525e..cb52c21c87ae9 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -26,6 +26,6 @@ rustc_middle = { path = "../rustc_middle" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.15" +thin-vec = "0.2.18" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml index 193c89a295980..4e11d8726c84f 100644 --- a/compiler/rustc_serialize/Cargo.toml +++ b/compiler/rustc_serialize/Cargo.toml @@ -8,7 +8,7 @@ edition = "2024" indexmap = "2.0.0" rustc_hashes = { path = "../rustc_hashes" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.15" +thin-vec = "0.2.18" # tidy-alphabetical-end [dev-dependencies] diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index 802fdda6f0375..3ce76d78e6c8a 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -19,6 +19,6 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.15" +thin-vec = "0.2.18" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 7b0b4aa899723..97cddd857af18 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -23,7 +23,7 @@ rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } smallvec = { version = "1.8.1", default-features = false, features = [ "const_generics", ] } -thin-vec = "0.2.15" +thin-vec = "0.2.18" tracing = "0.1" # tidy-alphabetical-end From fee82a37e9eabf8afe6db62c0177baaf63356a98 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Thu, 18 Jun 2026 12:36:51 +0200 Subject: [PATCH 19/26] rustdoc-json-types: Replace bincode dev-dependency with postcard bincode is flagged as unmaintained by RUSTSEC-2025-0141, and the advisory covers the entire crate with no patched version available. The only use in this crate was the binary serde roundtrip in the type tests. postcard (https://crates.io/crates/postcard) is a maintained serde-based binary serialization format that covers the same roundtrip testing need. bincode is still pulled in transitively by the miri subtree (via ipc-channel), which needs to be addressed upstream. --- Cargo.lock | 35 ++++++++++++++++++++++++++++++- src/rustdoc-json-types/Cargo.toml | 2 +- src/rustdoc-json-types/tests.rs | 14 ++++++------- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b17c0d309cba..52d5d3fca8524 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -784,6 +784,15 @@ dependencies = [ "cc", ] +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror 2.0.17", +] + [[package]] name = "codespan-reporting" version = "0.13.1" @@ -1330,6 +1339,18 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + [[package]] name = "ena" version = "0.14.3" @@ -3055,6 +3076,18 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "serde", +] + [[package]] name = "potential_utf" version = "0.1.4" @@ -4978,7 +5011,7 @@ dependencies = [ name = "rustdoc-json-types" version = "0.1.0" dependencies = [ - "bincode", + "postcard", "rkyv", "rustc-hash 2.1.1", "serde", diff --git a/src/rustdoc-json-types/Cargo.toml b/src/rustdoc-json-types/Cargo.toml index 7e4e53ccaf0de..9e18691a9605a 100644 --- a/src/rustdoc-json-types/Cargo.toml +++ b/src/rustdoc-json-types/Cargo.toml @@ -18,4 +18,4 @@ rkyv = { version = "0.8", optional = true } [dev-dependencies] serde_json = "1.0" -bincode = "1" +postcard = { version = "1", default-features = false, features = ["alloc"] } diff --git a/src/rustdoc-json-types/tests.rs b/src/rustdoc-json-types/tests.rs index e878350e43b9b..844dc45ecafa1 100644 --- a/src/rustdoc-json-types/tests.rs +++ b/src/rustdoc-json-types/tests.rs @@ -13,9 +13,9 @@ fn test_struct_info_roundtrip() { let de_s = serde_json::from_str(&struct_json).unwrap(); assert_eq!(s, de_s); - // Bincode - let encoded: Vec = bincode::serialize(&s).unwrap(); - let decoded: ItemEnum = bincode::deserialize(&encoded).unwrap(); + // Postcard + let encoded: Vec = postcard::to_allocvec(&s).unwrap(); + let decoded: ItemEnum = postcard::from_bytes(&encoded).unwrap(); assert_eq!(s, decoded); } @@ -33,9 +33,9 @@ fn test_union_info_roundtrip() { let de_u = serde_json::from_str(&union_json).unwrap(); assert_eq!(u, de_u); - // Bincode - let encoded: Vec = bincode::serialize(&u).unwrap(); - let decoded: ItemEnum = bincode::deserialize(&encoded).unwrap(); + // Postcard + let encoded: Vec = postcard::to_allocvec(&u).unwrap(); + let decoded: ItemEnum = postcard::from_bytes(&encoded).unwrap(); assert_eq!(u, decoded); } @@ -59,7 +59,7 @@ mod rkyv { /// A test to exercise the (de)serialization roundtrip for a representative selection of types, /// covering most of the rkyv-specific attributes we had to had. fn test_rkyv_roundtrip() { - // Standard derives: a plain struct and union, mirroring the existing serde/bincode tests. + // Standard derives: a plain struct and union, mirroring the existing serde/postcard tests. let s = ItemEnum::Struct(Struct { generics: Generics { params: vec![], where_predicates: vec![] }, kind: StructKind::Plain { fields: vec![Id(1), Id(2)], has_stripped_fields: false }, From 34d3eed3faa8250cb5ad0aea5e86b9c95eb4e0d9 Mon Sep 17 00:00:00 2001 From: Valentyn Kit Date: Thu, 18 Jun 2026 14:50:54 +0300 Subject: [PATCH 20/26] Document the file-descriptor-limit error from TcpListener::accept --- library/std/src/net/tcp.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs index 53bef0b4de609..4e67903540a65 100644 --- a/library/std/src/net/tcp.rs +++ b/library/std/src/net/tcp.rs @@ -878,16 +878,20 @@ impl TcpListener { /// /// # Errors /// - /// Some errors returned by this function relate to a single incoming - /// connection that failed before it could be accepted, such as one aborted - /// by the peer ([`ConnectionAborted`]). Such an error does not indicate a - /// problem with the listener itself, which remains usable. Code serving a - /// long-lived listener will usually want to log the error and continue - /// accepting connections rather than treat it as fatal. Which errors can - /// occur this way is platform-specific. - /// - /// On Unix, [`Interrupted`] errors are retried internally rather than being - /// returned. + /// Some errors this function returns do not indicate a problem with the + /// listener itself, and a program serving a long-lived listener will + /// usually want to handle them and keep accepting connections rather than + /// treat them as fatal. These include, but are not limited to: + /// + /// - An error specific to a single incoming connection that failed before + /// it could be accepted, such as one aborted by the peer + /// ([`ConnectionAborted`]). A later call may succeed immediately. + /// - An error from reaching the per-process or system-wide open file + /// descriptor limit. The call can be retried once other file descriptors + /// have been closed, typically after a short delay. + /// + /// Which errors can occur is platform-specific. On Unix, [`Interrupted`] + /// errors are retried internally rather than being returned. /// /// [`ConnectionAborted`]: io::ErrorKind::ConnectionAborted /// [`Interrupted`]: io::ErrorKind::Interrupted From 14475190e56c5b7fbf8f5d5c42327b89f65f4480 Mon Sep 17 00:00:00 2001 From: Valentyn Kit Date: Thu, 18 Jun 2026 16:04:05 +0300 Subject: [PATCH 21/26] Document the out-of-memory error from TcpListener::accept --- library/std/src/net/tcp.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs index 4e67903540a65..b673abdff7ba1 100644 --- a/library/std/src/net/tcp.rs +++ b/library/std/src/net/tcp.rs @@ -889,11 +889,14 @@ impl TcpListener { /// - An error from reaching the per-process or system-wide open file /// descriptor limit. The call can be retried once other file descriptors /// have been closed, typically after a short delay. + /// - An error from failing to allocate memory while accepting a connection + /// ([`OutOfMemory`]). /// /// Which errors can occur is platform-specific. On Unix, [`Interrupted`] /// errors are retried internally rather than being returned. /// /// [`ConnectionAborted`]: io::ErrorKind::ConnectionAborted + /// [`OutOfMemory`]: io::ErrorKind::OutOfMemory /// [`Interrupted`]: io::ErrorKind::Interrupted /// /// # Examples From dbf6d75478a36bd654a9e1138ddd03cc8a0384f4 Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Wed, 17 Jun 2026 14:34:53 +0200 Subject: [PATCH 22/26] `RegionValues`: disable unnecessary range check Currently, when adding liveness points to region values in the `RegionValues` struct, the locations of the points are checked for ranges. This is unnecessarily cautious because they always are in range by construction. This adds documentation (including debug assertions) to make this clearer and removes the checks, which should have a strictly positive impact on performance. --- .../rustc_borrowck/src/region_infer/values.rs | 42 +++++++++---------- compiler/rustc_mir_dataflow/src/points.rs | 7 +++- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index 27ee3f6176ee0..e96dc44fab7c4 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -9,7 +9,7 @@ use rustc_middle::bug; use rustc_middle::mir::{BasicBlock, Location}; use rustc_middle::ty::{self, RegionVid}; use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex}; -use tracing::debug; +use tracing::{debug, instrument}; use crate::BorrowIndex; use crate::polonius::LiveLoans; @@ -116,37 +116,43 @@ impl LivenessValues { /// Records `region` as being live at the given `location`. pub(crate) fn add_location(&mut self, region: RegionVid, location: Location) { let point = self.location_map.point_from_location(location); + // This is a debug assert despite being cheap because it drops + // the current `point_in_range()` uses to 0 when debugging is off. + debug_assert!( + self.location_map.point_in_range(point), + "Tried inserting region {region:?} whose location {location:?} does not belong to this body!" + ); debug!("LivenessValues::add_location(region={:?}, location={:?})", region, location); match &mut self.live_regions { LiveRegions::AtPoints(points) => { points.insert(region, point); } - LiveRegions::InBody(live_regions) if self.location_map.point_in_range(point) => { + LiveRegions::InBody(live_regions) => { live_regions.insert(region); } - - LiveRegions::InBody(_) => (), }; } /// Records `region` as being live at all the given `points`. pub(crate) fn add_points(&mut self, region: RegionVid, points: &IntervalSet) { + debug_assert!( + points.iter().all(|point| self.location_map.point_in_range(point)), + "Tried inserting region {region:?} with some points not belonging to this body!" + ); debug!("LivenessValues::add_points(region={:?}, points={:?})", region, points); match &mut self.live_regions { LiveRegions::AtPoints(these_points) => { these_points.union_row(region, points); } - LiveRegions::InBody(live_regions) - if points.iter().any(|point| self.location_map.point_in_range(point)) => - { + LiveRegions::InBody(live_regions) => { live_regions.insert(region); } - LiveRegions::InBody(_) => (), }; } /// Records `region` as being live at all the control-flow points. + #[instrument(skip(self))] pub(crate) fn add_all_points(&mut self, region: RegionVid) { match &mut self.live_regions { LiveRegions::AtPoints(points) => points.insert_all_into_row(region), @@ -172,10 +178,7 @@ impl LivenessValues { /// Returns an iterator of all the points where `region` is live. fn live_points(&self, region: RegionVid) -> impl Iterator { - self.point_liveness(region) - .into_iter() - .flat_map(|set| set.iter()) - .take_while(|&p| self.location_map.point_in_range(p)) + self.point_liveness(region).into_iter().flat_map(|set| set.iter()) } /// For debugging purposes, returns a pretty-printed string of the points where the `region` is @@ -343,11 +346,10 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> { /// Returns the locations contained within a given region `r`. pub(crate) fn locations_outlived_by(&self, r: N) -> impl Iterator { - self.points.row(r).into_iter().flat_map(move |set| { - set.iter() - .take_while(move |&p| self.location_map.point_in_range(p)) - .map(move |p| self.location_map.to_location(p)) - }) + self.points + .row(r) + .into_iter() + .flat_map(move |set| set.iter().map(move |p| self.location_map.to_location(p))) } /// Returns just the universal regions that are contained in a given region's value. @@ -413,11 +415,7 @@ pub(crate) fn pretty_print_points( points: impl IntoIterator, ) -> String { pretty_print_region_elements( - points - .into_iter() - .take_while(|&p| location_map.point_in_range(p)) - .map(|p| location_map.to_location(p)) - .map(RegionElement::Location), + points.into_iter().map(|p| location_map.to_location(p)).map(RegionElement::Location), ) } diff --git a/compiler/rustc_mir_dataflow/src/points.rs b/compiler/rustc_mir_dataflow/src/points.rs index e3d1e04a319ba..8568f325f1306 100644 --- a/compiler/rustc_mir_dataflow/src/points.rs +++ b/compiler/rustc_mir_dataflow/src/points.rs @@ -31,7 +31,8 @@ impl DenseLocationMap { for (bb, bb_data) in body.basic_blocks.iter_enumerated() { basic_blocks.extend((0..=bb_data.statements.len()).map(|_| bb)); } - + // Invariant: no block is preceded by more than all statements. + debug_assert!(*statements_before_block.iter().max().unwrap() < num_points); Self { statements_before_block, basic_blocks, num_points } } @@ -42,10 +43,14 @@ impl DenseLocationMap { } /// Converts a `Location` into a `PointIndex`. O(1). + /// [[`Self::point_in_range()`]] guaranteed for the returned index. #[inline] pub fn point_from_location(&self, location: Location) -> PointIndex { let Location { block, statement_index } = location; let start_index = self.statements_before_block[block]; + // Note the invariant in [`Self::new()`]; if the indexing + // operation above did not panic then this holds by construction. + debug_assert!(start_index < self.num_points); PointIndex::new(start_index + statement_index) } From ebea09f6f8779a189a6b16d026031a6913a398d3 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Thu, 18 Jun 2026 16:50:39 +0200 Subject: [PATCH 23/26] renovate: Skip dashboard approval for GitHub Actions updates --- .github/renovate.json5 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index d6c7455fe14cb..c2df406c9dc18 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -9,6 +9,13 @@ "dependencyDashboard": true, // Require manual approval from the Dependency Dashboard before opening PRs "dependencyDashboardApproval": true, + "packageRules": [ + { + // No dashboard approval necessary for GitHub Actions updates + "matchManagers": ["github-actions"], + "dependencyDashboardApproval": false + } + ], // Don't manage dependencies inside subtrees. They are updated upstream and // synced in. See `src/doc/rustc-dev-guide/src/external-repos.md` for the list. "ignorePaths": [ From cfadf6ee6b0a11d88aa6bf84cf469c6fb6f228a3 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Thu, 18 Jun 2026 16:54:53 +0200 Subject: [PATCH 24/26] renovate: Enable monthly lock file maintenance --- .github/renovate.json5 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index c2df406c9dc18..69fc5216920c8 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,6 +1,9 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ + // Refresh lock files on the first day of each month + // (still gated by dashboard approval for now) + ":maintainLockFilesMonthly", // Pin GitHub Actions to their commit SHA digests, resolving floating tags // (e.g. `v4`) to the full SemVer version (e.g. `v4.1.2`) "helpers:pinGitHubActionDigestsToSemver" From 4e0bcfc4efcd77448aee4002a15cd5d0fc653ac4 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Thu, 18 Jun 2026 17:00:01 +0200 Subject: [PATCH 25/26] renovate: Extend `config:recommended` preset --- .github/renovate.json5 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 69fc5216920c8..a4930160612cb 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,6 +1,7 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ + "config:recommended", // Refresh lock files on the first day of each month // (still gated by dashboard approval for now) ":maintainLockFilesMonthly", @@ -8,8 +9,6 @@ // (e.g. `v4`) to the full SemVer version (e.g. `v4.1.2`) "helpers:pinGitHubActionDigestsToSemver" ], - // Let Renovatebot keep an opened issue that tracks our dependencies - "dependencyDashboard": true, // Require manual approval from the Dependency Dashboard before opening PRs "dependencyDashboardApproval": true, "packageRules": [ From 5db91c4c70cdfc1e3f28532c519c416be2112a63 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Thu, 18 Jun 2026 17:03:13 +0200 Subject: [PATCH 26/26] renovate: Enable config migration PRs --- .github/renovate.json5 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index a4930160612cb..6d45e9a81b2fe 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -2,6 +2,8 @@ "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ "config:recommended", + // Open a PR to migrate the config when Renovate deprecates syntax + ":configMigration", // Refresh lock files on the first day of each month // (still gated by dashboard approval for now) ":maintainLockFilesMonthly",