Skip to content

Commit dcb3761

Browse files
committed
Auto merge of #103322 - matthiaskrgr:rollup-m9zgpft, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #103221 (Fix `SelfVisitor::is_self_ty` ICE) - #103230 (Clarify startup) - #103281 (Adjust `transmute{,_copy}` to be clearer about which of `T` and `U` is input vs output) - #103288 (Fixed docs typo in `library/std/src/time.rs`) - #103296 (+/- shortcut now only expand/collapse, not both) - #103297 (fix typo) - #103313 (Don't label `src/test` tests as `A-testsuite`) - #103315 (interpret: remove an incorrect assertion) - #103319 (Improve "`~const` is not allowed here" message) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 5ffa67d + f9944a9 commit dcb3761

File tree

22 files changed

+235
-130
lines changed

22 files changed

+235
-130
lines changed

compiler/rustc_ast_passes/src/ast_validation.rs

+43-20
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ enum SelfSemantic {
3838
No,
3939
}
4040

41+
/// What is the context that prevents using `~const`?
42+
enum DisallowTildeConstContext<'a> {
43+
TraitObject,
44+
ImplTrait,
45+
Fn(FnKind<'a>),
46+
}
47+
4148
struct AstValidator<'a> {
4249
session: &'a Session,
4350

@@ -56,7 +63,7 @@ struct AstValidator<'a> {
5663
/// e.g., `impl Iterator<Item = impl Debug>`.
5764
outer_impl_trait: Option<Span>,
5865

59-
is_tilde_const_allowed: bool,
66+
disallow_tilde_const: Option<DisallowTildeConstContext<'a>>,
6067

6168
/// Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
6269
/// or `Foo::Bar<impl Trait>`
@@ -93,18 +100,26 @@ impl<'a> AstValidator<'a> {
93100
self.is_impl_trait_banned = old;
94101
}
95102

96-
fn with_tilde_const(&mut self, allowed: bool, f: impl FnOnce(&mut Self)) {
97-
let old = mem::replace(&mut self.is_tilde_const_allowed, allowed);
103+
fn with_tilde_const(
104+
&mut self,
105+
disallowed: Option<DisallowTildeConstContext<'a>>,
106+
f: impl FnOnce(&mut Self),
107+
) {
108+
let old = mem::replace(&mut self.disallow_tilde_const, disallowed);
98109
f(self);
99-
self.is_tilde_const_allowed = old;
110+
self.disallow_tilde_const = old;
100111
}
101112

102113
fn with_tilde_const_allowed(&mut self, f: impl FnOnce(&mut Self)) {
103-
self.with_tilde_const(true, f)
114+
self.with_tilde_const(None, f)
104115
}
105116

106-
fn with_banned_tilde_const(&mut self, f: impl FnOnce(&mut Self)) {
107-
self.with_tilde_const(false, f)
117+
fn with_banned_tilde_const(
118+
&mut self,
119+
ctx: DisallowTildeConstContext<'a>,
120+
f: impl FnOnce(&mut Self),
121+
) {
122+
self.with_tilde_const(Some(ctx), f)
108123
}
109124

110125
fn with_let_management(
@@ -172,7 +187,7 @@ impl<'a> AstValidator<'a> {
172187
fn with_impl_trait(&mut self, outer: Option<Span>, f: impl FnOnce(&mut Self)) {
173188
let old = mem::replace(&mut self.outer_impl_trait, outer);
174189
if outer.is_some() {
175-
self.with_banned_tilde_const(f);
190+
self.with_banned_tilde_const(DisallowTildeConstContext::ImplTrait, f);
176191
} else {
177192
f(self);
178193
}
@@ -197,7 +212,10 @@ impl<'a> AstValidator<'a> {
197212
TyKind::ImplTrait(..) => {
198213
self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t))
199214
}
200-
TyKind::TraitObject(..) => self.with_banned_tilde_const(|this| visit::walk_ty(this, t)),
215+
TyKind::TraitObject(..) => self
216+
.with_banned_tilde_const(DisallowTildeConstContext::TraitObject, |this| {
217+
visit::walk_ty(this, t)
218+
}),
201219
TyKind::Path(ref qself, ref path) => {
202220
// We allow these:
203221
// - `Option<impl Trait>`
@@ -1411,13 +1429,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
14111429
);
14121430
err.emit();
14131431
}
1414-
(_, TraitBoundModifier::MaybeConst) => {
1415-
if !self.is_tilde_const_allowed {
1416-
self.err_handler()
1417-
.struct_span_err(bound.span(), "`~const` is not allowed here")
1418-
.note("only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions")
1419-
.emit();
1420-
}
1432+
(_, TraitBoundModifier::MaybeConst) if let Some(reason) = &self.disallow_tilde_const => {
1433+
let mut err = self.err_handler().struct_span_err(bound.span(), "`~const` is not allowed here");
1434+
match reason {
1435+
DisallowTildeConstContext::TraitObject => err.note("trait objects cannot have `~const` trait bounds"),
1436+
DisallowTildeConstContext::ImplTrait => err.note("`impl Trait`s cannot have `~const` trait bounds"),
1437+
DisallowTildeConstContext::Fn(FnKind::Closure(..)) => err.note("closures cannot have `~const` trait bounds"),
1438+
DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => err.span_note(ident.span, "this function is not `const`, so it cannot have `~const` trait bounds"),
1439+
};
1440+
err.emit();
14211441
}
14221442
(_, TraitBoundModifier::MaybeConstMaybe) => {
14231443
self.err_handler()
@@ -1523,10 +1543,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
15231543
});
15241544
}
15251545

1526-
let tilde_const_allowed = matches!(fk.header(), Some(FnHeader { .. }))
1527-
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)));
1546+
let tilde_const_allowed =
1547+
matches!(fk.header(), Some(FnHeader { constness: ast::Const::Yes(_), .. }))
1548+
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)));
1549+
1550+
let disallowed = (!tilde_const_allowed).then(|| DisallowTildeConstContext::Fn(fk));
15281551

1529-
self.with_tilde_const(tilde_const_allowed, |this| visit::walk_fn(this, fk));
1552+
self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
15301553
}
15311554

15321555
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
@@ -1770,7 +1793,7 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) ->
17701793
in_const_trait_impl: false,
17711794
has_proc_macro_decls: false,
17721795
outer_impl_trait: None,
1773-
is_tilde_const_allowed: false,
1796+
disallow_tilde_const: None,
17741797
is_impl_trait_banned: false,
17751798
is_assoc_ty_bound_banned: false,
17761799
forbidden_let_reason: Some(ForbiddenLetReason::GenericForbidden),

compiler/rustc_const_eval/src/interpret/terminator.rs

-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
3535
assert_eq!(discr.layout.ty, switch_ty);
3636

3737
// Branch to the `otherwise` case by default, if no match is found.
38-
assert!(!targets.iter().is_empty());
3938
let mut target_block = targets.otherwise();
4039

4140
for (const_int, target) in targets.iter() {

compiler/rustc_driver/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ impl<'a, 'b> RunCompiler<'a, 'b> {
190190
run_compiler(self.at_args, self.callbacks, self.file_loader, self.make_codegen_backend)
191191
}
192192
}
193+
193194
fn run_compiler(
194195
at_args: &[String],
195196
callbacks: &mut (dyn Callbacks + Send),

compiler/rustc_interface/src/interface.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ use std::result;
2525

2626
pub type Result<T> = result::Result<T, ErrorGuaranteed>;
2727

28-
/// Represents a compiler session.
28+
/// Represents a compiler session. Note that every `Compiler` contains a
29+
/// `Session`, but `Compiler` also contains some things that cannot be in
30+
/// `Session`, due to `Session` being in a crate that has many fewer
31+
/// dependencies than this crate.
2932
///
3033
/// Can be used to run `rustc_interface` queries.
3134
/// Created by passing [`Config`] to [`run_compiler`].

compiler/rustc_interface/src/util.rs

+45-44
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,8 @@ use libloading::Library;
33
use rustc_ast as ast;
44
use rustc_codegen_ssa::traits::CodegenBackend;
55
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
6-
#[cfg(parallel_compiler)]
7-
use rustc_data_structures::jobserver;
86
use rustc_errors::registry::Registry;
9-
#[cfg(parallel_compiler)]
10-
use rustc_middle::ty::tls;
117
use rustc_parse::validate_attr;
12-
#[cfg(parallel_compiler)]
13-
use rustc_query_impl::{QueryContext, QueryCtxt};
148
use rustc_session as session;
159
use rustc_session::config::CheckCfg;
1610
use rustc_session::config::{self, CrateType};
@@ -25,8 +19,6 @@ use rustc_span::symbol::{sym, Symbol};
2519
use std::env;
2620
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
2721
use std::mem;
28-
#[cfg(not(parallel_compiler))]
29-
use std::panic;
3022
use std::path::{Path, PathBuf};
3123
use std::sync::atomic::{AtomicBool, Ordering};
3224
use std::sync::OnceLock;
@@ -135,13 +127,20 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
135127
_threads: usize,
136128
f: F,
137129
) -> R {
138-
// The thread pool is a single thread in the non-parallel compiler.
139-
thread::scope(|s| {
140-
let mut builder = thread::Builder::new().name("rustc".to_string());
141-
if let Some(size) = get_stack_size() {
142-
builder = builder.stack_size(size);
143-
}
130+
// The "thread pool" is a single spawned thread in the non-parallel
131+
// compiler. We run on a spawned thread instead of the main thread (a) to
132+
// provide control over the stack size, and (b) to increase similarity with
133+
// the parallel compiler, in particular to ensure there is no accidental
134+
// sharing of data between the main thread and the compilation thread
135+
// (which might cause problems for the parallel compiler).
136+
let mut builder = thread::Builder::new().name("rustc".to_string());
137+
if let Some(size) = get_stack_size() {
138+
builder = builder.stack_size(size);
139+
}
144140

141+
// We build the session globals and run `f` on the spawned thread, because
142+
// `SessionGlobals` does not impl `Send` in the non-parallel compiler.
143+
thread::scope(|s| {
145144
// `unwrap` is ok here because `spawn_scoped` only panics if the thread
146145
// name contains null bytes.
147146
let r = builder
@@ -151,55 +150,57 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
151150

152151
match r {
153152
Ok(v) => v,
154-
Err(e) => panic::resume_unwind(e),
153+
Err(e) => std::panic::resume_unwind(e),
155154
}
156155
})
157156
}
158157

159-
/// Creates a new thread and forwards information in thread locals to it.
160-
/// The new thread runs the deadlock handler.
161-
/// Must only be called when a deadlock is about to happen.
162-
#[cfg(parallel_compiler)]
163-
unsafe fn handle_deadlock() {
164-
let registry = rustc_rayon_core::Registry::current();
165-
166-
let query_map = tls::with(|tcx| {
167-
QueryCtxt::from_tcx(tcx)
168-
.try_collect_active_jobs()
169-
.expect("active jobs shouldn't be locked in deadlock handler")
170-
});
171-
thread::spawn(move || rustc_query_impl::deadlock(query_map, &registry));
172-
}
173-
174158
#[cfg(parallel_compiler)]
175159
pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
176160
edition: Edition,
177161
threads: usize,
178162
f: F,
179163
) -> R {
180-
let mut config = rayon::ThreadPoolBuilder::new()
164+
use rustc_data_structures::jobserver;
165+
use rustc_middle::ty::tls;
166+
use rustc_query_impl::{deadlock, QueryContext, QueryCtxt};
167+
168+
let mut builder = rayon::ThreadPoolBuilder::new()
181169
.thread_name(|_| "rustc".to_string())
182170
.acquire_thread_handler(jobserver::acquire_thread)
183171
.release_thread_handler(jobserver::release_thread)
184172
.num_threads(threads)
185-
.deadlock_handler(|| unsafe { handle_deadlock() });
186-
173+
.deadlock_handler(|| {
174+
// On deadlock, creates a new thread and forwards information in thread
175+
// locals to it. The new thread runs the deadlock handler.
176+
let query_map = tls::with(|tcx| {
177+
QueryCtxt::from_tcx(tcx)
178+
.try_collect_active_jobs()
179+
.expect("active jobs shouldn't be locked in deadlock handler")
180+
});
181+
let registry = rustc_rayon_core::Registry::current();
182+
thread::spawn(move || deadlock(query_map, &registry));
183+
});
187184
if let Some(size) = get_stack_size() {
188-
config = config.stack_size(size);
185+
builder = builder.stack_size(size);
189186
}
190187

191-
let with_pool = move |pool: &rayon::ThreadPool| pool.install(f);
192-
188+
// We create the session globals on the main thread, then create the thread
189+
// pool. Upon creation, each worker thread created gets a copy of the
190+
// session globals in TLS. This is possible because `SessionGlobals` impls
191+
// `Send` in the parallel compiler.
193192
rustc_span::create_session_globals_then(edition, || {
194193
rustc_span::with_session_globals(|session_globals| {
195-
// The main handler runs for each Rayon worker thread and sets up
196-
// the thread local rustc uses. `session_globals` is captured and set
197-
// on the new threads.
198-
let main_handler = move |thread: rayon::ThreadBuilder| {
199-
rustc_span::set_session_globals_then(session_globals, || thread.run())
200-
};
201-
202-
config.build_scoped(main_handler, with_pool).unwrap()
194+
builder
195+
.build_scoped(
196+
// Initialize each new worker thread when created.
197+
move |thread: rayon::ThreadBuilder| {
198+
rustc_span::set_session_globals_then(session_globals, || thread.run())
199+
},
200+
// Run `f` on the first thread in the thread pool.
201+
move |pool: &rayon::ThreadPool| pool.install(f),
202+
)
203+
.unwrap()
203204
})
204205
})
205206
}

compiler/rustc_resolve/src/late.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1939,11 +1939,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
19391939
match ty.kind {
19401940
TyKind::ImplicitSelf => true,
19411941
TyKind::Path(None, _) => {
1942-
let path_res = self.r.partial_res_map[&ty.id].expect_full_res();
1943-
if let Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } = path_res {
1942+
let path_res = self.r.partial_res_map[&ty.id].full_res();
1943+
if let Some(Res::SelfTyParam { .. } | Res::SelfTyAlias { .. }) = path_res {
19441944
return true;
19451945
}
1946-
Some(path_res) == self.impl_self
1946+
self.impl_self.is_some() && path_res == self.impl_self
19471947
}
19481948
_ => false,
19491949
}

library/core/src/intrinsics.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -994,14 +994,14 @@ extern "rust-intrinsic" {
994994
/// `transmute` is semantically equivalent to a bitwise move of one type
995995
/// into another. It copies the bits from the source value into the
996996
/// destination value, then forgets the original. Note that source and destination
997-
/// are passed by-value, which means if `T` or `U` contain padding, that padding
997+
/// are passed by-value, which means if `Src` or `Dst` contain padding, that padding
998998
/// is *not* guaranteed to be preserved by `transmute`.
999999
///
10001000
/// Both the argument and the result must be [valid](../../nomicon/what-unsafe-does.html) at
10011001
/// their given type. Violating this condition leads to [undefined behavior][ub]. The compiler
10021002
/// will generate code *assuming that you, the programmer, ensure that there will never be
10031003
/// undefined behavior*. It is therefore your responsibility to guarantee that every value
1004-
/// passed to `transmute` is valid at both types `T` and `U`. Failing to uphold this condition
1004+
/// passed to `transmute` is valid at both types `Src` and `Dst`. Failing to uphold this condition
10051005
/// may lead to unexpected and unstable compilation results. This makes `transmute` **incredibly
10061006
/// unsafe**. `transmute` should be the absolute last resort.
10071007
///
@@ -1012,7 +1012,7 @@ extern "rust-intrinsic" {
10121012
///
10131013
/// Because `transmute` is a by-value operation, alignment of the *transmuted values
10141014
/// themselves* is not a concern. As with any other function, the compiler already ensures
1015-
/// both `T` and `U` are properly aligned. However, when transmuting values that *point
1015+
/// both `Src` and `Dst` are properly aligned. However, when transmuting values that *point
10161016
/// elsewhere* (such as pointers, references, boxes…), the caller has to ensure proper
10171017
/// alignment of the pointed-to values.
10181018
///
@@ -1248,7 +1248,7 @@ extern "rust-intrinsic" {
12481248
#[rustc_allowed_through_unstable_modules]
12491249
#[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
12501250
#[rustc_diagnostic_item = "transmute"]
1251-
pub fn transmute<T, U>(e: T) -> U;
1251+
pub fn transmute<Src, Dst>(src: Src) -> Dst;
12521252

12531253
/// Returns `true` if the actual type given as `T` requires drop
12541254
/// glue; returns `false` if the actual type provided for `T`

0 commit comments

Comments
 (0)