Skip to content

Commit 3ff30e7

Browse files
committed
Auto merge of #149462 - matthiaskrgr:rollup-vfwin7f, r=matthiaskrgr
Rollup of 3 pull requests Successful merges: - #148746 (const validation: remove check for mutable refs in final value of const) - #148765 (std: split up the `thread` module) - #149454 (resolve: Identifier resolution refactorings) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 8a3a6bd + b35b187 commit 3ff30e7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2645
-2501
lines changed

compiler/rustc_const_eval/messages.ftl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,6 @@ const_eval_validation_invalid_ref_meta = {$front_matter}: encountered invalid re
473473
const_eval_validation_invalid_ref_slice_meta = {$front_matter}: encountered invalid reference metadata: slice is bigger than largest supported object
474474
const_eval_validation_invalid_vtable_ptr = {$front_matter}: encountered {$value}, but expected a vtable pointer
475475
const_eval_validation_invalid_vtable_trait = {$front_matter}: wrong trait in wide pointer vtable: expected `{$expected_dyn_type}`, but encountered `{$vtable_dyn_type}`
476-
const_eval_validation_mutable_ref_in_const = {$front_matter}: encountered mutable reference in `const` value
477476
const_eval_validation_mutable_ref_to_immutable = {$front_matter}: encountered mutable reference or box pointing to read-only memory
478477
const_eval_validation_never_val = {$front_matter}: encountered a value of the never type `!`
479478
const_eval_validation_nonnull_ptr_out_of_range = {$front_matter}: encountered a maybe-null pointer, but expected something that is definitely non-zero

compiler/rustc_const_eval/src/errors.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,6 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
665665
PointerAsInt { .. } => const_eval_validation_pointer_as_int,
666666
PartialPointer => const_eval_validation_partial_pointer,
667667
MutableRefToImmutable => const_eval_validation_mutable_ref_to_immutable,
668-
MutableRefInConst => const_eval_validation_mutable_ref_in_const,
669668
NullFnPtr { .. } => const_eval_validation_null_fn_ptr,
670669
NeverVal => const_eval_validation_never_val,
671670
NonnullPtrMaybeNull { .. } => const_eval_validation_nonnull_ptr_out_of_range,
@@ -824,7 +823,6 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
824823
err.arg("maybe", maybe);
825824
}
826825
MutableRefToImmutable
827-
| MutableRefInConst
828826
| NonnullPtrMaybeNull
829827
| NeverVal
830828
| UnsafeCellInImmutable

compiler/rustc_const_eval/src/interpret/validity.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -639,12 +639,6 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
639639
// This can actually occur with transmutes.
640640
throw_validation_failure!(self.path, MutableRefToImmutable);
641641
}
642-
// In a const, any kind of mutable reference is not good.
643-
if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { .. })) {
644-
if ptr_expected_mutbl == Mutability::Mut {
645-
throw_validation_failure!(self.path, MutableRefInConst);
646-
}
647-
}
648642
}
649643
}
650644
// Potentially skip recursive check.

compiler/rustc_middle/src/mir/interpret/error.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,6 @@ pub enum ValidationErrorKind<'tcx> {
496496
},
497497
MutableRefToImmutable,
498498
UnsafeCellInImmutable,
499-
MutableRefInConst,
500499
NullFnPtr {
501500
/// Records whether this pointer is definitely null or just may be null.
502501
maybe: bool,

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::ops::ControlFlow;
2+
13
use itertools::Itertools as _;
24
use rustc_ast::visit::{self, Visitor};
35
use rustc_ast::{
@@ -1261,7 +1263,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
12611263
}
12621264
}
12631265

1264-
None::<()>
1266+
ControlFlow::<()>::Continue(())
12651267
});
12661268
}
12671269

compiler/rustc_resolve/src/ident.rs

Lines changed: 535 additions & 397 deletions
Large diffs are not rendered by default.

compiler/rustc_resolve/src/lib.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#![feature(arbitrary_self_types)]
1414
#![feature(assert_matches)]
1515
#![feature(box_patterns)]
16+
#![feature(control_flow_into_value)]
1617
#![feature(decl_macro)]
1718
#![feature(default_field_values)]
1819
#![feature(if_let_guard)]
@@ -26,6 +27,7 @@
2627
use std::cell::Ref;
2728
use std::collections::BTreeSet;
2829
use std::fmt::{self};
30+
use std::ops::ControlFlow;
2931
use std::sync::Arc;
3032

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

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

101-
#[derive(Debug)]
102-
enum Weak {
103-
Yes,
104-
No,
105-
}
106-
107103
#[derive(Copy, Clone, PartialEq, Debug)]
108104
enum Determinacy {
109105
Determined,
@@ -1917,7 +1913,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
19171913
| Scope::BuiltinTypes => {}
19181914
_ => unreachable!(),
19191915
}
1920-
None::<()>
1916+
ControlFlow::<()>::Continue(())
19211917
});
19221918

19231919
found_traits
@@ -2489,6 +2485,7 @@ enum Stage {
24892485
Late,
24902486
}
24912487

2488+
/// Invariant: if `Finalize` is used, expansion and import resolution must be complete.
24922489
#[derive(Copy, Clone, Debug)]
24932490
struct Finalize {
24942491
/// Node ID for linting.

library/std/src/thread/builder.rs

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
use super::join_handle::JoinHandle;
2+
use super::lifecycle::spawn_unchecked;
3+
use crate::io;
4+
5+
/// Thread factory, which can be used in order to configure the properties of
6+
/// a new thread.
7+
///
8+
/// Methods can be chained on it in order to configure it.
9+
///
10+
/// The two configurations available are:
11+
///
12+
/// - [`name`]: specifies an [associated name for the thread][naming-threads]
13+
/// - [`stack_size`]: specifies the [desired stack size for the thread][stack-size]
14+
///
15+
/// The [`spawn`] method will take ownership of the builder and create an
16+
/// [`io::Result`] to the thread handle with the given configuration.
17+
///
18+
/// The [`thread::spawn`] free function uses a `Builder` with default
19+
/// configuration and [`unwrap`]s its return value.
20+
///
21+
/// You may want to use [`spawn`] instead of [`thread::spawn`], when you want
22+
/// to recover from a failure to launch a thread, indeed the free function will
23+
/// panic where the `Builder` method will return a [`io::Result`].
24+
///
25+
/// # Examples
26+
///
27+
/// ```
28+
/// use std::thread;
29+
///
30+
/// let builder = thread::Builder::new();
31+
///
32+
/// let handler = builder.spawn(|| {
33+
/// // thread code
34+
/// }).unwrap();
35+
///
36+
/// handler.join().unwrap();
37+
/// ```
38+
///
39+
/// [`stack_size`]: Builder::stack_size
40+
/// [`name`]: Builder::name
41+
/// [`spawn`]: Builder::spawn
42+
/// [`thread::spawn`]: super::spawn
43+
/// [`io::Result`]: crate::io::Result
44+
/// [`unwrap`]: crate::result::Result::unwrap
45+
/// [naming-threads]: ./index.html#naming-threads
46+
/// [stack-size]: ./index.html#stack-size
47+
#[must_use = "must eventually spawn the thread"]
48+
#[stable(feature = "rust1", since = "1.0.0")]
49+
#[derive(Debug)]
50+
pub struct Builder {
51+
/// A name for the thread-to-be, for identification in panic messages
52+
pub(super) name: Option<String>,
53+
/// The size of the stack for the spawned thread in bytes
54+
pub(super) stack_size: Option<usize>,
55+
/// Skip running and inheriting the thread spawn hooks
56+
pub(super) no_hooks: bool,
57+
}
58+
59+
impl Builder {
60+
/// Generates the base configuration for spawning a thread, from which
61+
/// configuration methods can be chained.
62+
///
63+
/// # Examples
64+
///
65+
/// ```
66+
/// use std::thread;
67+
///
68+
/// let builder = thread::Builder::new()
69+
/// .name("foo".into())
70+
/// .stack_size(32 * 1024);
71+
///
72+
/// let handler = builder.spawn(|| {
73+
/// // thread code
74+
/// }).unwrap();
75+
///
76+
/// handler.join().unwrap();
77+
/// ```
78+
#[stable(feature = "rust1", since = "1.0.0")]
79+
pub fn new() -> Builder {
80+
Builder { name: None, stack_size: None, no_hooks: false }
81+
}
82+
83+
/// Names the thread-to-be. Currently the name is used for identification
84+
/// only in panic messages.
85+
///
86+
/// The name must not contain null bytes (`\0`).
87+
///
88+
/// For more information about named threads, see
89+
/// [this module-level documentation][naming-threads].
90+
///
91+
/// # Examples
92+
///
93+
/// ```
94+
/// use std::thread;
95+
///
96+
/// let builder = thread::Builder::new()
97+
/// .name("foo".into());
98+
///
99+
/// let handler = builder.spawn(|| {
100+
/// assert_eq!(thread::current().name(), Some("foo"))
101+
/// }).unwrap();
102+
///
103+
/// handler.join().unwrap();
104+
/// ```
105+
///
106+
/// [naming-threads]: ./index.html#naming-threads
107+
#[stable(feature = "rust1", since = "1.0.0")]
108+
pub fn name(mut self, name: String) -> Builder {
109+
self.name = Some(name);
110+
self
111+
}
112+
113+
/// Sets the size of the stack (in bytes) for the new thread.
114+
///
115+
/// The actual stack size may be greater than this value if
116+
/// the platform specifies a minimal stack size.
117+
///
118+
/// For more information about the stack size for threads, see
119+
/// [this module-level documentation][stack-size].
120+
///
121+
/// # Examples
122+
///
123+
/// ```
124+
/// use std::thread;
125+
///
126+
/// let builder = thread::Builder::new().stack_size(32 * 1024);
127+
/// ```
128+
///
129+
/// [stack-size]: ./index.html#stack-size
130+
#[stable(feature = "rust1", since = "1.0.0")]
131+
pub fn stack_size(mut self, size: usize) -> Builder {
132+
self.stack_size = Some(size);
133+
self
134+
}
135+
136+
/// Disables running and inheriting [spawn hooks].
137+
///
138+
/// Use this if the parent thread is in no way relevant for the child thread.
139+
/// For example, when lazily spawning threads for a thread pool.
140+
///
141+
/// [spawn hooks]: super::add_spawn_hook
142+
#[unstable(feature = "thread_spawn_hook", issue = "132951")]
143+
pub fn no_hooks(mut self) -> Builder {
144+
self.no_hooks = true;
145+
self
146+
}
147+
148+
/// Spawns a new thread by taking ownership of the `Builder`, and returns an
149+
/// [`io::Result`] to its [`JoinHandle`].
150+
///
151+
/// The spawned thread may outlive the caller (unless the caller thread
152+
/// is the main thread; the whole process is terminated when the main
153+
/// thread finishes). The join handle can be used to block on
154+
/// termination of the spawned thread, including recovering its panics.
155+
///
156+
/// For a more complete documentation see [`thread::spawn`].
157+
///
158+
/// # Errors
159+
///
160+
/// Unlike the [`spawn`] free function, this method yields an
161+
/// [`io::Result`] to capture any failure to create the thread at
162+
/// the OS level.
163+
///
164+
/// [`io::Result`]: crate::io::Result
165+
///
166+
/// # Panics
167+
///
168+
/// Panics if a thread name was set and it contained null bytes.
169+
///
170+
/// # Examples
171+
///
172+
/// ```
173+
/// use std::thread;
174+
///
175+
/// let builder = thread::Builder::new();
176+
///
177+
/// let handler = builder.spawn(|| {
178+
/// // thread code
179+
/// }).unwrap();
180+
///
181+
/// handler.join().unwrap();
182+
/// ```
183+
///
184+
/// [`thread::spawn`]: super::spawn
185+
/// [`spawn`]: super::spawn
186+
#[stable(feature = "rust1", since = "1.0.0")]
187+
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
188+
pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>>
189+
where
190+
F: FnOnce() -> T,
191+
F: Send + 'static,
192+
T: Send + 'static,
193+
{
194+
unsafe { self.spawn_unchecked(f) }
195+
}
196+
197+
/// Spawns a new thread without any lifetime restrictions by taking ownership
198+
/// of the `Builder`, and returns an [`io::Result`] to its [`JoinHandle`].
199+
///
200+
/// The spawned thread may outlive the caller (unless the caller thread
201+
/// is the main thread; the whole process is terminated when the main
202+
/// thread finishes). The join handle can be used to block on
203+
/// termination of the spawned thread, including recovering its panics.
204+
///
205+
/// This method is identical to [`thread::Builder::spawn`][`Builder::spawn`],
206+
/// except for the relaxed lifetime bounds, which render it unsafe.
207+
/// For a more complete documentation see [`thread::spawn`].
208+
///
209+
/// # Errors
210+
///
211+
/// Unlike the [`spawn`] free function, this method yields an
212+
/// [`io::Result`] to capture any failure to create the thread at
213+
/// the OS level.
214+
///
215+
/// # Panics
216+
///
217+
/// Panics if a thread name was set and it contained null bytes.
218+
///
219+
/// # Safety
220+
///
221+
/// The caller has to ensure that the spawned thread does not outlive any
222+
/// references in the supplied thread closure and its return type.
223+
/// This can be guaranteed in two ways:
224+
///
225+
/// - ensure that [`join`][`JoinHandle::join`] is called before any referenced
226+
/// data is dropped
227+
/// - use only types with `'static` lifetime bounds, i.e., those with no or only
228+
/// `'static` references (both [`thread::Builder::spawn`][`Builder::spawn`]
229+
/// and [`thread::spawn`] enforce this property statically)
230+
///
231+
/// # Examples
232+
///
233+
/// ```
234+
/// use std::thread;
235+
///
236+
/// let builder = thread::Builder::new();
237+
///
238+
/// let x = 1;
239+
/// let thread_x = &x;
240+
///
241+
/// let handler = unsafe {
242+
/// builder.spawn_unchecked(move || {
243+
/// println!("x = {}", *thread_x);
244+
/// }).unwrap()
245+
/// };
246+
///
247+
/// // caller has to ensure `join()` is called, otherwise
248+
/// // it is possible to access freed memory if `x` gets
249+
/// // dropped before the thread closure is executed!
250+
/// handler.join().unwrap();
251+
/// ```
252+
///
253+
/// [`io::Result`]: crate::io::Result
254+
/// [`thread::spawn`]: super::spawn
255+
/// [`spawn`]: super::spawn
256+
#[stable(feature = "thread_spawn_unchecked", since = "1.82.0")]
257+
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
258+
pub unsafe fn spawn_unchecked<F, T>(self, f: F) -> io::Result<JoinHandle<T>>
259+
where
260+
F: FnOnce() -> T,
261+
F: Send,
262+
T: Send,
263+
{
264+
let Builder { name, stack_size, no_hooks } = self;
265+
Ok(JoinHandle(unsafe { spawn_unchecked(name, stack_size, no_hooks, None, f) }?))
266+
}
267+
}

0 commit comments

Comments
 (0)