Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
3d7c9bd
const validation: remove check for mutable refs in final value of const
RalfJung Nov 9, 2025
97e6819
resolve: Use `ControlFlow` in `fn visit_scopes` callback
petrochenkov Nov 27, 2025
6ca6302
resolve: Move one iteration of `resolve_ident_in_scope_set` into a se…
petrochenkov Nov 27, 2025
47edfd3
resolve: Move ambiguity detection in `resolve_ident_in_scope_set` int…
petrochenkov Nov 27, 2025
621d870
resolve: Tweak top level logic and comments in `resolve_ident_in_scop…
petrochenkov Nov 27, 2025
b7f6c95
resolve: Move `resolve_ident_in_module_unadjusted` for real modules t…
petrochenkov Nov 28, 2025
56e1e24
resolve: Remove some function parameters and return values that are n…
petrochenkov Nov 28, 2025
674d287
resolve: Replace `enum Weak` with `ops::ControlFlow`
petrochenkov Nov 29, 2025
9761db0
resolve: Correctly mark break and continue for determinate errors
petrochenkov Nov 29, 2025
e57df92
std: split up the `thread` module (preparation)
joboet Nov 29, 2025
c91b6ca
resolve: Split `resolve_ident_in_module_unadjusted` into two parts - …
petrochenkov Nov 29, 2025
8b08da2
std: split up the `thread` module
joboet Nov 9, 2025
912f7f9
update references to thread implementation in tests
joboet Nov 9, 2025
9c6e0f6
std: update broken links in `thread` module
joboet Nov 9, 2025
c22b819
update type names in debuginfo tests
joboet Nov 28, 2025
8e4c70f
Rollup merge of #148746 - RalfJung:mutable-ref-in-const, r=davidtwco
matthiaskrgr Nov 29, 2025
c93801c
Rollup merge of #148765 - joboet:split-up-thread, r=ChrisDenton
matthiaskrgr Nov 29, 2025
b35b187
Rollup merge of #149454 - petrochenkov:openapi0, r=eholk
matthiaskrgr Nov 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion compiler/rustc_const_eval/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,6 @@ const_eval_validation_invalid_ref_meta = {$front_matter}: encountered invalid re
const_eval_validation_invalid_ref_slice_meta = {$front_matter}: encountered invalid reference metadata: slice is bigger than largest supported object
const_eval_validation_invalid_vtable_ptr = {$front_matter}: encountered {$value}, but expected a vtable pointer
const_eval_validation_invalid_vtable_trait = {$front_matter}: wrong trait in wide pointer vtable: expected `{$expected_dyn_type}`, but encountered `{$vtable_dyn_type}`
const_eval_validation_mutable_ref_in_const = {$front_matter}: encountered mutable reference in `const` value
const_eval_validation_mutable_ref_to_immutable = {$front_matter}: encountered mutable reference or box pointing to read-only memory
const_eval_validation_never_val = {$front_matter}: encountered a value of the never type `!`
const_eval_validation_nonnull_ptr_out_of_range = {$front_matter}: encountered a maybe-null pointer, but expected something that is definitely non-zero
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_const_eval/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,6 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
PointerAsInt { .. } => const_eval_validation_pointer_as_int,
PartialPointer => const_eval_validation_partial_pointer,
MutableRefToImmutable => const_eval_validation_mutable_ref_to_immutable,
MutableRefInConst => const_eval_validation_mutable_ref_in_const,
NullFnPtr { .. } => const_eval_validation_null_fn_ptr,
NeverVal => const_eval_validation_never_val,
NonnullPtrMaybeNull { .. } => const_eval_validation_nonnull_ptr_out_of_range,
Expand Down Expand Up @@ -824,7 +823,6 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
err.arg("maybe", maybe);
}
MutableRefToImmutable
| MutableRefInConst
| NonnullPtrMaybeNull
| NeverVal
| UnsafeCellInImmutable
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,12 +639,6 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
// This can actually occur with transmutes.
throw_validation_failure!(self.path, MutableRefToImmutable);
}
// In a const, any kind of mutable reference is not good.
if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { .. })) {
if ptr_expected_mutbl == Mutability::Mut {
throw_validation_failure!(self.path, MutableRefInConst);
}
}
}
}
// Potentially skip recursive check.
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_middle/src/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,6 @@ pub enum ValidationErrorKind<'tcx> {
},
MutableRefToImmutable,
UnsafeCellInImmutable,
MutableRefInConst,
NullFnPtr {
/// Records whether this pointer is definitely null or just may be null.
maybe: bool,
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::ops::ControlFlow;

use itertools::Itertools as _;
use rustc_ast::visit::{self, Visitor};
use rustc_ast::{
Expand Down Expand Up @@ -1261,7 +1263,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
}

None::<()>
ControlFlow::<()>::Continue(())
});
}

Expand Down
932 changes: 535 additions & 397 deletions compiler/rustc_resolve/src/ident.rs

Large diffs are not rendered by default.

11 changes: 4 additions & 7 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#![feature(arbitrary_self_types)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(control_flow_into_value)]
#![feature(decl_macro)]
#![feature(default_field_values)]
#![feature(if_let_guard)]
Expand All @@ -26,6 +27,7 @@
use std::cell::Ref;
use std::collections::BTreeSet;
use std::fmt::{self};
use std::ops::ControlFlow;
use std::sync::Arc;

use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
Expand Down Expand Up @@ -98,12 +100,6 @@ use crate::ref_mut::{CmCell, CmRefCell};

rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

#[derive(Debug)]
enum Weak {
Yes,
No,
}

#[derive(Copy, Clone, PartialEq, Debug)]
enum Determinacy {
Determined,
Expand Down Expand Up @@ -1917,7 +1913,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
| Scope::BuiltinTypes => {}
_ => unreachable!(),
}
None::<()>
ControlFlow::<()>::Continue(())
});

found_traits
Expand Down Expand Up @@ -2489,6 +2485,7 @@ enum Stage {
Late,
}

/// Invariant: if `Finalize` is used, expansion and import resolution must be complete.
#[derive(Copy, Clone, Debug)]
struct Finalize {
/// Node ID for linting.
Expand Down
267 changes: 267 additions & 0 deletions library/std/src/thread/builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
use super::join_handle::JoinHandle;
use super::lifecycle::spawn_unchecked;
use crate::io;

/// Thread factory, which can be used in order to configure the properties of
/// a new thread.
///
/// Methods can be chained on it in order to configure it.
///
/// The two configurations available are:
///
/// - [`name`]: specifies an [associated name for the thread][naming-threads]
/// - [`stack_size`]: specifies the [desired stack size for the thread][stack-size]
///
/// The [`spawn`] method will take ownership of the builder and create an
/// [`io::Result`] to the thread handle with the given configuration.
///
/// The [`thread::spawn`] free function uses a `Builder` with default
/// configuration and [`unwrap`]s its return value.
///
/// You may want to use [`spawn`] instead of [`thread::spawn`], when you want
/// to recover from a failure to launch a thread, indeed the free function will
/// panic where the `Builder` method will return a [`io::Result`].
///
/// # Examples
///
/// ```
/// use std::thread;
///
/// let builder = thread::Builder::new();
///
/// let handler = builder.spawn(|| {
/// // thread code
/// }).unwrap();
///
/// handler.join().unwrap();
/// ```
///
/// [`stack_size`]: Builder::stack_size
/// [`name`]: Builder::name
/// [`spawn`]: Builder::spawn
/// [`thread::spawn`]: super::spawn
/// [`io::Result`]: crate::io::Result
/// [`unwrap`]: crate::result::Result::unwrap
/// [naming-threads]: ./index.html#naming-threads
/// [stack-size]: ./index.html#stack-size
#[must_use = "must eventually spawn the thread"]
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Debug)]
pub struct Builder {
/// A name for the thread-to-be, for identification in panic messages
pub(super) name: Option<String>,
/// The size of the stack for the spawned thread in bytes
pub(super) stack_size: Option<usize>,
/// Skip running and inheriting the thread spawn hooks
pub(super) no_hooks: bool,
}

impl Builder {
/// Generates the base configuration for spawning a thread, from which
/// configuration methods can be chained.
///
/// # Examples
///
/// ```
/// use std::thread;
///
/// let builder = thread::Builder::new()
/// .name("foo".into())
/// .stack_size(32 * 1024);
///
/// let handler = builder.spawn(|| {
/// // thread code
/// }).unwrap();
///
/// handler.join().unwrap();
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new() -> Builder {
Builder { name: None, stack_size: None, no_hooks: false }
}

/// Names the thread-to-be. Currently the name is used for identification
/// only in panic messages.
///
/// The name must not contain null bytes (`\0`).
///
/// For more information about named threads, see
/// [this module-level documentation][naming-threads].
///
/// # Examples
///
/// ```
/// use std::thread;
///
/// let builder = thread::Builder::new()
/// .name("foo".into());
///
/// let handler = builder.spawn(|| {
/// assert_eq!(thread::current().name(), Some("foo"))
/// }).unwrap();
///
/// handler.join().unwrap();
/// ```
///
/// [naming-threads]: ./index.html#naming-threads
#[stable(feature = "rust1", since = "1.0.0")]
pub fn name(mut self, name: String) -> Builder {
self.name = Some(name);
self
}

/// Sets the size of the stack (in bytes) for the new thread.
///
/// The actual stack size may be greater than this value if
/// the platform specifies a minimal stack size.
///
/// For more information about the stack size for threads, see
/// [this module-level documentation][stack-size].
///
/// # Examples
///
/// ```
/// use std::thread;
///
/// let builder = thread::Builder::new().stack_size(32 * 1024);
/// ```
///
/// [stack-size]: ./index.html#stack-size
#[stable(feature = "rust1", since = "1.0.0")]
pub fn stack_size(mut self, size: usize) -> Builder {
self.stack_size = Some(size);
self
}

/// Disables running and inheriting [spawn hooks].
///
/// Use this if the parent thread is in no way relevant for the child thread.
/// For example, when lazily spawning threads for a thread pool.
///
/// [spawn hooks]: super::add_spawn_hook
#[unstable(feature = "thread_spawn_hook", issue = "132951")]
pub fn no_hooks(mut self) -> Builder {
self.no_hooks = true;
self
}

/// Spawns a new thread by taking ownership of the `Builder`, and returns an
/// [`io::Result`] to its [`JoinHandle`].
///
/// The spawned thread may outlive the caller (unless the caller thread
/// is the main thread; the whole process is terminated when the main
/// thread finishes). The join handle can be used to block on
/// termination of the spawned thread, including recovering its panics.
///
/// For a more complete documentation see [`thread::spawn`].
///
/// # Errors
///
/// Unlike the [`spawn`] free function, this method yields an
/// [`io::Result`] to capture any failure to create the thread at
/// the OS level.
///
/// [`io::Result`]: crate::io::Result
///
/// # Panics
///
/// Panics if a thread name was set and it contained null bytes.
///
/// # Examples
///
/// ```
/// use std::thread;
///
/// let builder = thread::Builder::new();
///
/// let handler = builder.spawn(|| {
/// // thread code
/// }).unwrap();
///
/// handler.join().unwrap();
/// ```
///
/// [`thread::spawn`]: super::spawn
/// [`spawn`]: super::spawn
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>>
where
F: FnOnce() -> T,
F: Send + 'static,
T: Send + 'static,
{
unsafe { self.spawn_unchecked(f) }
}

/// Spawns a new thread without any lifetime restrictions by taking ownership
/// of the `Builder`, and returns an [`io::Result`] to its [`JoinHandle`].
///
/// The spawned thread may outlive the caller (unless the caller thread
/// is the main thread; the whole process is terminated when the main
/// thread finishes). The join handle can be used to block on
/// termination of the spawned thread, including recovering its panics.
///
/// This method is identical to [`thread::Builder::spawn`][`Builder::spawn`],
/// except for the relaxed lifetime bounds, which render it unsafe.
/// For a more complete documentation see [`thread::spawn`].
///
/// # Errors
///
/// Unlike the [`spawn`] free function, this method yields an
/// [`io::Result`] to capture any failure to create the thread at
/// the OS level.
///
/// # Panics
///
/// Panics if a thread name was set and it contained null bytes.
///
/// # Safety
///
/// The caller has to ensure that the spawned thread does not outlive any
/// references in the supplied thread closure and its return type.
/// This can be guaranteed in two ways:
///
/// - ensure that [`join`][`JoinHandle::join`] is called before any referenced
/// data is dropped
/// - use only types with `'static` lifetime bounds, i.e., those with no or only
/// `'static` references (both [`thread::Builder::spawn`][`Builder::spawn`]
/// and [`thread::spawn`] enforce this property statically)
///
/// # Examples
///
/// ```
/// use std::thread;
///
/// let builder = thread::Builder::new();
///
/// let x = 1;
/// let thread_x = &x;
///
/// let handler = unsafe {
/// builder.spawn_unchecked(move || {
/// println!("x = {}", *thread_x);
/// }).unwrap()
/// };
///
/// // caller has to ensure `join()` is called, otherwise
/// // it is possible to access freed memory if `x` gets
/// // dropped before the thread closure is executed!
/// handler.join().unwrap();
/// ```
///
/// [`io::Result`]: crate::io::Result
/// [`thread::spawn`]: super::spawn
/// [`spawn`]: super::spawn
#[stable(feature = "thread_spawn_unchecked", since = "1.82.0")]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub unsafe fn spawn_unchecked<F, T>(self, f: F) -> io::Result<JoinHandle<T>>
where
F: FnOnce() -> T,
F: Send,
T: Send,
{
let Builder { name, stack_size, no_hooks } = self;
Ok(JoinHandle(unsafe { spawn_unchecked(name, stack_size, no_hooks, None, f) }?))
}
}
Loading
Loading