diff --git a/compiler/rustc_public_bridge/src/lib.rs b/compiler/rustc_public_bridge/src/lib.rs index dec3be70baff4..1c38cb6c4bdfc 100644 --- a/compiler/rustc_public_bridge/src/lib.rs +++ b/compiler/rustc_public_bridge/src/lib.rs @@ -21,6 +21,7 @@ #![doc(rust_logo)] #![feature(rustdoc_internals)] #![feature(sized_hierarchy)] +#![feature(trait_alias)] // tidy-alphabetical-end use std::cell::RefCell; @@ -45,6 +46,9 @@ pub mod context; #[deprecated(note = "please use `rustc_public::rustc_internal` instead")] pub mod rustc_internal {} +/// Trait alias for types that can be cached in [`Tables`]. +pub trait Cacheable = Copy + Debug + PartialEq + IndexedVal; + /// A container which is used for TLS. pub struct Container<'tcx, B: Bridge> { pub tables: RefCell>, @@ -213,14 +217,14 @@ impl<'tcx, B: Bridge> Tables<'tcx, B> { /// A trait defining types that are used to emulate rustc_public components, which is really /// useful when programming in rustc_public-agnostic settings. pub trait Bridge: Sized { - type DefId: Copy + Debug + PartialEq + IndexedVal; - type AllocId: Copy + Debug + PartialEq + IndexedVal; - type Span: Copy + Debug + PartialEq + IndexedVal; - type Ty: Copy + Debug + PartialEq + IndexedVal; - type InstanceDef: Copy + Debug + PartialEq + IndexedVal; - type TyConstId: Copy + Debug + PartialEq + IndexedVal; - type MirConstId: Copy + Debug + PartialEq + IndexedVal; - type Layout: Copy + Debug + PartialEq + IndexedVal; + type DefId: Cacheable; + type AllocId: Cacheable; + type Span: Cacheable; + type Ty: Cacheable; + type InstanceDef: Cacheable; + type TyConstId: Cacheable; + type MirConstId: Cacheable; + type Layout: Cacheable; type Error: Error; type CrateItem: CrateItem; @@ -266,7 +270,7 @@ impl Default for IndexMap { } } -impl IndexMap { +impl IndexMap { pub fn create_or_fetch(&mut self, key: K) -> V { let len = self.index_map.len(); let v = self.index_map.entry(key).or_insert(V::to_val(len)); @@ -274,9 +278,7 @@ impl IndexMa } } -impl Index - for IndexMap -{ +impl Index for IndexMap { type Output = K; fn index(&self, index: V) -> &Self::Output { diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index 3231125f7a13a..f1cae4b207c9a 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -1,4 +1,4 @@ -use super::poison::once::ExclusiveState; +use super::once::OnceExclusiveState; use crate::cell::UnsafeCell; use crate::mem::ManuallyDrop; use crate::ops::{Deref, DerefMut}; @@ -140,14 +140,18 @@ impl T> LazyLock { pub fn into_inner(mut this: Self) -> Result { let state = this.once.state(); match state { - ExclusiveState::Poisoned => panic_poisoned(), + OnceExclusiveState::Poisoned => panic_poisoned(), state => { let this = ManuallyDrop::new(this); let data = unsafe { ptr::read(&this.data) }.into_inner(); match state { - ExclusiveState::Incomplete => Err(ManuallyDrop::into_inner(unsafe { data.f })), - ExclusiveState::Complete => Ok(ManuallyDrop::into_inner(unsafe { data.value })), - ExclusiveState::Poisoned => unreachable!(), + OnceExclusiveState::Incomplete => { + Err(ManuallyDrop::into_inner(unsafe { data.f })) + } + OnceExclusiveState::Complete => { + Ok(ManuallyDrop::into_inner(unsafe { data.value })) + } + OnceExclusiveState::Poisoned => unreachable!(), } } } @@ -189,7 +193,7 @@ impl T> LazyLock { impl Drop for PoisonOnPanic<'_, T, F> { #[inline] fn drop(&mut self) { - self.0.once.set_state(ExclusiveState::Poisoned); + self.0.once.set_state(OnceExclusiveState::Poisoned); } } @@ -200,7 +204,7 @@ impl T> LazyLock { let guard = PoisonOnPanic(this); let data = f(); guard.0.data.get_mut().value = ManuallyDrop::new(data); - guard.0.once.set_state(ExclusiveState::Complete); + guard.0.once.set_state(OnceExclusiveState::Complete); core::mem::forget(guard); // SAFETY: We put the value there above. unsafe { &mut this.data.get_mut().value } @@ -208,11 +212,11 @@ impl T> LazyLock { let state = this.once.state(); match state { - ExclusiveState::Poisoned => panic_poisoned(), + OnceExclusiveState::Poisoned => panic_poisoned(), // SAFETY: The `Once` states we completed the initialization. - ExclusiveState::Complete => unsafe { &mut this.data.get_mut().value }, + OnceExclusiveState::Complete => unsafe { &mut this.data.get_mut().value }, // SAFETY: The state is `Incomplete`. - ExclusiveState::Incomplete => unsafe { really_init_mut(this) }, + OnceExclusiveState::Incomplete => unsafe { really_init_mut(this) }, } } @@ -293,7 +297,7 @@ impl LazyLock { match state { // SAFETY: // The closure has been run successfully, so `value` has been initialized. - ExclusiveState::Complete => Some(unsafe { &mut this.data.get_mut().value }), + OnceExclusiveState::Complete => Some(unsafe { &mut this.data.get_mut().value }), _ => None, } } @@ -332,11 +336,13 @@ impl LazyLock { impl Drop for LazyLock { fn drop(&mut self) { match self.once.state() { - ExclusiveState::Incomplete => unsafe { ManuallyDrop::drop(&mut self.data.get_mut().f) }, - ExclusiveState::Complete => unsafe { + OnceExclusiveState::Incomplete => unsafe { + ManuallyDrop::drop(&mut self.data.get_mut().f) + }, + OnceExclusiveState::Complete => unsafe { ManuallyDrop::drop(&mut self.data.get_mut().value) }, - ExclusiveState::Poisoned => {} + OnceExclusiveState::Poisoned => {} } } } diff --git a/library/std/src/sync/mod.rs b/library/std/src/sync/mod.rs index 97c04d07eaf1d..19b3040dcb279 100644 --- a/library/std/src/sync/mod.rs +++ b/library/std/src/sync/mod.rs @@ -142,7 +142,7 @@ //! most one thread at a time is able to access some data. //! //! - [`Once`]: Used for a thread-safe, one-time global initialization routine. -//! Mostly useful for implementing other types like `OnceLock`. +//! Mostly useful for implementing other types like [`OnceLock`]. //! //! - [`OnceLock`]: Used for thread-safe, one-time initialization of a //! variable, with potentially different initializers based on the caller. @@ -181,7 +181,24 @@ pub use alloc_crate::sync::UniqueArc; #[stable(feature = "rust1", since = "1.0.0")] pub use alloc_crate::sync::{Arc, Weak}; -// FIXME(sync_nonpoison,sync_poison_mod): remove all `#[doc(inline)]` once the modules are stabilized. +#[unstable(feature = "mpmc_channel", issue = "126840")] +pub mod mpmc; +pub mod mpsc; + +pub(crate) mod once; // `pub(crate)` for the `sys::sync::once` implementations and `LazyLock`. + +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::once::{Once, OnceState}; + +#[stable(feature = "rust1", since = "1.0.0")] +#[doc(inline)] +#[expect(deprecated)] +pub use self::once::ONCE_INIT; + +mod barrier; +mod lazy_lock; +mod once_lock; +mod reentrant_lock; // These exist only in one flavor: no poisoning. #[stable(feature = "rust1", since = "1.0.0")] @@ -193,48 +210,37 @@ pub use self::once_lock::OnceLock; #[unstable(feature = "reentrant_lock", issue = "121440")] pub use self::reentrant_lock::{ReentrantLock, ReentrantLockGuard}; -// These make sense and exist only with poisoning. +// Note: in the future we will change the default version in `std::sync` to the non-poisoning +// version over an edition. +// See https://github.com/rust-lang/rust/issues/134645#issuecomment-3324577500 for more details. + +#[unstable(feature = "sync_nonpoison", issue = "134645")] +pub mod nonpoison; +#[unstable(feature = "sync_poison_mod", issue = "134646")] +pub mod poison; + +// FIXME(sync_poison_mod): remove all `#[doc(inline)]` once the modules are stabilized. + +// These exist only with poisoning. #[stable(feature = "rust1", since = "1.0.0")] #[doc(inline)] pub use self::poison::{LockResult, PoisonError}; -// These (should) exist in both flavors: with and without poisoning. -// FIXME(sync_nonpoison): implement nonpoison versions: -// * Mutex (nonpoison_mutex) -// * Condvar (nonpoison_condvar) -// * Once (nonpoison_once) -// * RwLock (nonpoison_rwlock) +// These exist in both flavors: with and without poisoning. // The historical default is the version with poisoning. #[stable(feature = "rust1", since = "1.0.0")] #[doc(inline)] pub use self::poison::{ - Mutex, MutexGuard, TryLockError, TryLockResult, - Condvar, - Once, OnceState, + TryLockError, TryLockResult, + Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard, + Condvar, }; -#[stable(feature = "rust1", since = "1.0.0")] -#[doc(inline)] -#[expect(deprecated)] -pub use self::poison::ONCE_INIT; + #[unstable(feature = "mapped_lock_guards", issue = "117108")] #[doc(inline)] pub use self::poison::{MappedMutexGuard, MappedRwLockReadGuard, MappedRwLockWriteGuard}; -#[unstable(feature = "mpmc_channel", issue = "126840")] -pub mod mpmc; -pub mod mpsc; - -#[unstable(feature = "sync_nonpoison", issue = "134645")] -pub mod nonpoison; -#[unstable(feature = "sync_poison_mod", issue = "134646")] -pub mod poison; - -mod barrier; -mod lazy_lock; -mod once_lock; -mod reentrant_lock; - /// A type indicating whether a timed wait on a condition variable returned /// due to a time out or not. /// diff --git a/library/std/src/sync/poison/once.rs b/library/std/src/sync/once.rs similarity index 97% rename from library/std/src/sync/poison/once.rs rename to library/std/src/sync/once.rs index faf2913c54730..12cc32f381d18 100644 --- a/library/std/src/sync/poison/once.rs +++ b/library/std/src/sync/once.rs @@ -49,7 +49,9 @@ pub struct OnceState { pub(crate) inner: sys::OnceState, } -pub(crate) enum ExclusiveState { +/// Used for the internal implementation of `sys::sync::once` on different platforms and the +/// [`LazyLock`](crate::sync::LazyLock) implementation. +pub(crate) enum OnceExclusiveState { Incomplete, Poisoned, Complete, @@ -310,7 +312,7 @@ impl Once { /// be running, so the state must be either "incomplete", "poisoned" or /// "complete". #[inline] - pub(crate) fn state(&mut self) -> ExclusiveState { + pub(crate) fn state(&mut self) -> OnceExclusiveState { self.inner.state() } @@ -320,7 +322,7 @@ impl Once { /// be running, so the state must be either "incomplete", "poisoned" or /// "complete". #[inline] - pub(crate) fn set_state(&mut self, new_state: ExclusiveState) { + pub(crate) fn set_state(&mut self, new_state: OnceExclusiveState) { self.inner.set_state(new_state); } } diff --git a/library/std/src/sync/poison.rs b/library/std/src/sync/poison.rs index 5517082033380..9f40c01546632 100644 --- a/library/std/src/sync/poison.rs +++ b/library/std/src/sync/poison.rs @@ -13,8 +13,8 @@ //! the panics are recognized reliably or on a best-effort basis depend on the //! primitive. See [Overview](#overview) below. //! -//! For the alternative implementations that do not employ poisoning, -//! see [`std::sync::nonpoison`]. +//! The synchronization objects in this module have alternative implementations that do not employ +//! poisoning in the [`std::sync::nonpoison`] module. //! //! [`std::sync::nonpoison`]: crate::sync::nonpoison //! @@ -42,14 +42,6 @@ //! [`Mutex::lock()`] returns a [`LockResult`], providing a way to deal with //! the poisoned state. See [`Mutex`'s documentation](Mutex#poisoning) for more. //! -//! - [`Once`]: A thread-safe way to run a piece of code only once. -//! Mostly useful for implementing one-time global initialization. -//! -//! [`Once`] is reliably poisoned if the piece of code passed to -//! [`Once::call_once()`] or [`Once::call_once_force()`] panics. -//! When in poisoned state, subsequent calls to [`Once::call_once()`] will panic too. -//! [`Once::call_once_force()`] can be used to clear the poisoned state. -//! //! - [`RwLock`]: Provides a mutual exclusion mechanism which allows //! multiple readers at the same time, while allowing only one //! writer at a time. In some cases, this can be more efficient than @@ -59,6 +51,11 @@ //! Note, however, that an `RwLock` may only be poisoned if a panic occurs //! while it is locked exclusively (write mode). If a panic occurs in any reader, //! then the lock will not be poisoned. +//! +//! Note that the [`Once`] type also employs poisoning, but since it has non-poisoning `force` +//! methods available on it, there is no separate `nonpoison` and `poison` version. +//! +//! [`Once`]: crate::sync::Once // If we are not unwinding, `PoisonError` is uninhabited. #![cfg_attr(not(panic = "unwind"), expect(unreachable_code))] @@ -69,11 +66,6 @@ pub use self::condvar::Condvar; pub use self::mutex::MappedMutexGuard; #[stable(feature = "rust1", since = "1.0.0")] pub use self::mutex::{Mutex, MutexGuard}; -#[stable(feature = "rust1", since = "1.0.0")] -#[expect(deprecated)] -pub use self::once::ONCE_INIT; -#[stable(feature = "rust1", since = "1.0.0")] -pub use self::once::{Once, OnceState}; #[unstable(feature = "mapped_lock_guards", issue = "117108")] pub use self::rwlock::{MappedRwLockReadGuard, MappedRwLockWriteGuard}; #[stable(feature = "rust1", since = "1.0.0")] @@ -88,7 +80,6 @@ use crate::thread; mod condvar; #[stable(feature = "rust1", since = "1.0.0")] mod mutex; -pub(crate) mod once; mod rwlock; pub(crate) struct Flag { diff --git a/library/std/src/sys/sync/once/futex.rs b/library/std/src/sys/sync/once/futex.rs index 407fdcebcf5cc..096f1d879ef26 100644 --- a/library/std/src/sys/sync/once/futex.rs +++ b/library/std/src/sys/sync/once/futex.rs @@ -1,7 +1,7 @@ use crate::cell::Cell; use crate::sync as public; use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release}; -use crate::sync::poison::once::ExclusiveState; +use crate::sync::once::OnceExclusiveState; use crate::sys::futex::{Futex, Primitive, futex_wait, futex_wake_all}; // On some platforms, the OS is very nice and handles the waiter queue for us. @@ -83,21 +83,21 @@ impl Once { } #[inline] - pub(crate) fn state(&mut self) -> ExclusiveState { + pub(crate) fn state(&mut self) -> OnceExclusiveState { match *self.state_and_queued.get_mut() { - INCOMPLETE => ExclusiveState::Incomplete, - POISONED => ExclusiveState::Poisoned, - COMPLETE => ExclusiveState::Complete, + INCOMPLETE => OnceExclusiveState::Incomplete, + POISONED => OnceExclusiveState::Poisoned, + COMPLETE => OnceExclusiveState::Complete, _ => unreachable!("invalid Once state"), } } #[inline] - pub(crate) fn set_state(&mut self, new_state: ExclusiveState) { + pub(crate) fn set_state(&mut self, new_state: OnceExclusiveState) { *self.state_and_queued.get_mut() = match new_state { - ExclusiveState::Incomplete => INCOMPLETE, - ExclusiveState::Poisoned => POISONED, - ExclusiveState::Complete => COMPLETE, + OnceExclusiveState::Incomplete => INCOMPLETE, + OnceExclusiveState::Poisoned => POISONED, + OnceExclusiveState::Complete => COMPLETE, }; } diff --git a/library/std/src/sys/sync/once/no_threads.rs b/library/std/src/sys/sync/once/no_threads.rs index 2568059cfe3a8..576bbf644cbed 100644 --- a/library/std/src/sys/sync/once/no_threads.rs +++ b/library/std/src/sys/sync/once/no_threads.rs @@ -1,6 +1,6 @@ use crate::cell::Cell; use crate::sync as public; -use crate::sync::poison::once::ExclusiveState; +use crate::sync::once::OnceExclusiveState; pub struct Once { state: Cell, @@ -45,21 +45,21 @@ impl Once { } #[inline] - pub(crate) fn state(&mut self) -> ExclusiveState { + pub(crate) fn state(&mut self) -> OnceExclusiveState { match self.state.get() { - State::Incomplete => ExclusiveState::Incomplete, - State::Poisoned => ExclusiveState::Poisoned, - State::Complete => ExclusiveState::Complete, + State::Incomplete => OnceExclusiveState::Incomplete, + State::Poisoned => OnceExclusiveState::Poisoned, + State::Complete => OnceExclusiveState::Complete, _ => unreachable!("invalid Once state"), } } #[inline] - pub(crate) fn set_state(&mut self, new_state: ExclusiveState) { + pub(crate) fn set_state(&mut self, new_state: OnceExclusiveState) { self.state.set(match new_state { - ExclusiveState::Incomplete => State::Incomplete, - ExclusiveState::Poisoned => State::Poisoned, - ExclusiveState::Complete => State::Complete, + OnceExclusiveState::Incomplete => State::Incomplete, + OnceExclusiveState::Poisoned => State::Poisoned, + OnceExclusiveState::Complete => State::Complete, }); } diff --git a/library/std/src/sys/sync/once/queue.rs b/library/std/src/sys/sync/once/queue.rs index 17d99cdb38595..d7219a7361cff 100644 --- a/library/std/src/sys/sync/once/queue.rs +++ b/library/std/src/sys/sync/once/queue.rs @@ -58,7 +58,7 @@ use crate::cell::Cell; use crate::sync::atomic::Ordering::{AcqRel, Acquire, Release}; use crate::sync::atomic::{Atomic, AtomicBool, AtomicPtr}; -use crate::sync::poison::once::ExclusiveState; +use crate::sync::once::OnceExclusiveState; use crate::thread::{self, Thread}; use crate::{fmt, ptr, sync as public}; @@ -131,21 +131,21 @@ impl Once { } #[inline] - pub(crate) fn state(&mut self) -> ExclusiveState { + pub(crate) fn state(&mut self) -> OnceExclusiveState { match self.state_and_queue.get_mut().addr() { - INCOMPLETE => ExclusiveState::Incomplete, - POISONED => ExclusiveState::Poisoned, - COMPLETE => ExclusiveState::Complete, + INCOMPLETE => OnceExclusiveState::Incomplete, + POISONED => OnceExclusiveState::Poisoned, + COMPLETE => OnceExclusiveState::Complete, _ => unreachable!("invalid Once state"), } } #[inline] - pub(crate) fn set_state(&mut self, new_state: ExclusiveState) { + pub(crate) fn set_state(&mut self, new_state: OnceExclusiveState) { *self.state_and_queue.get_mut() = match new_state { - ExclusiveState::Incomplete => ptr::without_provenance_mut(INCOMPLETE), - ExclusiveState::Poisoned => ptr::without_provenance_mut(POISONED), - ExclusiveState::Complete => ptr::without_provenance_mut(COMPLETE), + OnceExclusiveState::Incomplete => ptr::without_provenance_mut(INCOMPLETE), + OnceExclusiveState::Poisoned => ptr::without_provenance_mut(POISONED), + OnceExclusiveState::Complete => ptr::without_provenance_mut(COMPLETE), }; } diff --git a/src/doc/book b/src/doc/book index 1d7c3e6abec2d..af415fc6c8a68 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 1d7c3e6abec2d5a9bfac798b29b7855b95025426 +Subproject commit af415fc6c8a6823dfb4595074f27d5a3e9e2fe49 diff --git a/src/doc/nomicon b/src/doc/nomicon index 23fc2682f8fcb..60f0b30d8ec1c 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 23fc2682f8fcb887f77d0eaabba708809f834c11 +Subproject commit 60f0b30d8ec1c9eb5c2582f2ec55f1094b0f8c42 diff --git a/src/doc/reference b/src/doc/reference index 8efb980568672..752eab01cebdd 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 8efb9805686722dba511b7b27281bb6b77d32130 +Subproject commit 752eab01cebdd6a2d90b53087298844c251859a1 diff --git a/src/doc/rustc-dev-guide/src/backend/debugging.md b/src/doc/rustc-dev-guide/src/backend/debugging.md index 3dc95f25d4ae9..84efa72f4c46d 100644 --- a/src/doc/rustc-dev-guide/src/backend/debugging.md +++ b/src/doc/rustc-dev-guide/src/backend/debugging.md @@ -77,7 +77,7 @@ llvm-ir`). `--build-type=debug` emits code for debug builds. There are also other useful options. Also, debug info in LLVM IR can clutter the output a lot: `RUSTFLAGS="-C debuginfo=0"` is really useful. -`RUSTFLAGS="-C save-temps"` outputs LLVM bitcode (not the same as IR) at +`RUSTFLAGS="-C save-temps"` outputs LLVM bitcode at different stages during compilation, which is sometimes useful. The output LLVM bitcode will be in `.bc` files in the compiler's output directory, set via the `--out-dir DIR` argument to `rustc`. diff --git a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md index 2e5f0e43df1e5..ace834a55b71f 100644 --- a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md +++ b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md @@ -227,15 +227,18 @@ Once you've created a `bootstrap.toml`, you are now ready to run probably the best "go to" command for building a local compiler: ```console -./x build rustc +./x build library ``` -What this command does is build `rustc` using the stage0 compiler and stage0 `std`. +What this command does is: +- Build `rustc` using the stage0 compiler and stage0 `std`. +- Build `library` (the standard libraries) with the stage1 compiler that was just built. +- Assemble a working stage1 sysroot, containing the stage1 compiler and stage1 standard libraries. To build `rustc` with the in-tree `std`, use this command instead: ```console -./x build rustc --stage 2 +./x build library --stage 2 ``` This final product (stage1 compiler + libs built using that compiler) @@ -246,7 +249,7 @@ You will probably find that building the stage1 `std` is a bottleneck for you, but fear not, there is a (hacky) workaround... see [the section on avoiding rebuilds for std][keep-stage]. -[keep-stage]: ./suggested.md#faster-builds-with---keep-stage +[keep-stage]: ./suggested.md#faster-rebuilds-with---keep-stage-std Sometimes you don't need a full build. When doing some kind of "type-based refactoring", like renaming a method, or changing the diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md index 35c7e935b5688..6d3590eef64a3 100644 --- a/src/doc/rustc-dev-guide/src/building/suggested.md +++ b/src/doc/rustc-dev-guide/src/building/suggested.md @@ -306,6 +306,40 @@ steps, meaning it will have two precompiled compilers: stage0 compiler and `down for `stage > 0` steps. This way, it will never need to build the in-tree compiler. As a result, your build time will be significantly reduced by not building the in-tree compiler. +## Faster rebuilds with `--keep-stage-std` + +Sometimes just checking whether the compiler builds is not enough. A common +example is that you need to add a `debug!` statement to inspect the value of +some state or better understand the problem. In that case, you don't really need +a full build. By bypassing bootstrap's cache invalidation, you can often get +these builds to complete very fast (e.g., around 30 seconds). The only catch is +this requires a bit of fudging and may produce compilers that don't work (but +that is easily detected and fixed). + +The sequence of commands you want is as follows: + +- Initial build: `./x build library` +- Subsequent builds: `./x build library --keep-stage-std=1` + - Note that we added the `--keep-stage-std=1` flag here + +As mentioned, the effect of `--keep-stage-std=1` is that we just _assume_ that the +old standard library can be re-used. If you are editing the compiler, this is +often true: you haven't changed the standard library, after all. But +sometimes, it's not true: for example, if you are editing the "metadata" part of +the compiler, which controls how the compiler encodes types and other states +into the `rlib` files, or if you are editing things that wind up in the metadata +(such as the definition of the MIR). + +**The TL;DR is that you might get weird behavior from a compile when using +`--keep-stage-std=1`** -- for example, strange [ICEs](../appendix/glossary.html#ice) +or other panics. In that case, you should simply remove the `--keep-stage-std=1` +from the command and rebuild. That ought to fix the problem. + +You can also use `--keep-stage-std=1` when running tests. Something like this: + +- Initial test run: `./x test tests/ui` +- Subsequent test run: `./x test tests/ui --keep-stage-std=1` + ## Using incremental compilation You can further enable the `--incremental` flag to save additional time in diff --git a/src/doc/rustc-dev-guide/src/compiler-team.md b/src/doc/rustc-dev-guide/src/compiler-team.md index 8c0481f6ea8f5..9556811e842c2 100644 --- a/src/doc/rustc-dev-guide/src/compiler-team.md +++ b/src/doc/rustc-dev-guide/src/compiler-team.md @@ -54,8 +54,8 @@ They are held on [Zulip][zulip-meetings]. It works roughly as follows: those that are sufficiently important for us to actively track progress. P-critical and P-high bugs should ideally always have an assignee. -- **Check S-waiting-on-team and I-nominated issues:** These are issues where feedback from - the team is desired. +- **Check `S-waiting-on-t-compiler` and `I-compiler-nominated` issues:** These are issues where + feedback from the team is desired. - **Look over the performance triage report:** We check for PRs that made the performance worse and try to decide if it's worth reverting the performance regression or if the regression can be addressed in a future PR. diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 3d196ae2308f0..b4c8f9e9a58c0 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -461,7 +461,7 @@ Please see . [S-tracking-]: https://github.com/rust-lang/rust/labels?q=s-tracking [the rustc-dev-guide working group documentation]: https://forge.rust-lang.org/wg-rustc-dev-guide/index.html#where-to-contribute-rustc-dev-guide-changes -### Rfcbot labels +### rfcbot labels [rfcbot] uses its own labels for tracking the process of coordinating asynchronous decisions, such as approving or rejecting a change. diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md index 87e26d3796881..685b97329bb0c 100644 --- a/src/doc/rustc-dev-guide/src/getting-started.md +++ b/src/doc/rustc-dev-guide/src/getting-started.md @@ -98,7 +98,7 @@ Some work is too large to be done by a single person. In this case, it's common issues" to co-ordinate the work between contributors. Here are some example tracking issues where it's easy to pick up work without a large time commitment: -- [Move UI tests to subdirectories](https://github.com/rust-lang/rust/issues/73494) +- *Add recurring work items here.* If you find more recurring work, please feel free to add it here! diff --git a/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md index aa337754186d6..6bd6007c8969e 100644 --- a/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md +++ b/src/doc/rustc-dev-guide/src/tests/codegen-backend-tests/cg_gcc.md @@ -1,13 +1,33 @@ # GCC codegen backend -If you ran into an error related to tests executed with the GCC codegen backend on CI, -you can use the following command to run tests locally using the GCC backend: +We run a subset of the compiler test suite with the GCC codegen backend on our CI, to help find changes that could break the integration of this backend with the compiler. + +If you encounter any bugs or problems with the GCC codegen backend in general, don't hesitate to open issues on the +[`rustc_codegen_gcc` repository](https://github.com/rust-lang/rustc_codegen_gcc). + +Note that the backend currently only supports the `x86_64-unknown-linux-gnu` target. + +## Running into GCC backend CI errors + +If you ran into an error related to tests executed with the GCC codegen backend on CI in the `x86_64-gnu-gcc` job, +you can use the following command to run UI tests locally using the GCC backend, which reproduces what happens on CI: ```bash -./x test tests/ui --set 'rust.codegen-backends = ["llvm", "gcc"]' --test-codegen-backend gcc +./x test tests/ui \ + --set 'rust.codegen-backends = ["llvm", "gcc"]' \ + --set 'rust.debug-assertions = false' \ + --test-codegen-backend gcc ``` -Below, you can find more information about how to configure the GCC backend in bootstrap. +If a different test suite has failed on CI, you will have to modify the `tests/ui` part. + +To reproduce the whole CI job locally, you can run `cargo run --manifest-path src/ci/citool/Cargo.toml run-local x86_64-gnu-gcc`. See [Testing with Docker](../docker.md) for more information. + +### What to do in case of a GCC job failure? + +If the GCC job test fails and it seems like the failure could be caused by the GCC backend, you can ping the [cg-gcc working group](https://github.com/orgs/rust-lang/teams/wg-gcc-backend) using `@rust-lang/wg-gcc-backend` + +If fixing a compiler test that fails with the GCC backend is non-trivial, you can ignore that test when executed with `cg_gcc` using the `//@ ignore-backends: gcc` [compiletest directive](../directives.md). ## Choosing which codegen backends are built @@ -44,8 +64,7 @@ To run compiler tests with the GCC codegen backend being used to build the test ./x test tests/ui --test-codegen-backend gcc ``` -Note that in order for this to work, the tested compiler must have the GCC codegen backend available in its sysroot -directory. You can achieve that using the [instructions above](#choosing-which-codegen-backends-are-built). +Note that in order for this to work, the tested compiler must have the GCC codegen backend [available](#choosing-which-codegen-backends-are-built) in its sysroot directory. ## Downloading GCC from CI @@ -53,4 +72,14 @@ The `gcc.download-ci-gcc` bootstrap option controls if GCC (which is a dependenc will be downloaded from CI or built locally. The default value is `true`, which will download GCC from CI if there are no local changes to the GCC sources and the given host target is available on CI. -Note that GCC can currently only be downloaded from CI for the `x86_64-unknown-linux-gnu` target. +## Running tests of the backend itself + +In addition to running the compiler's test suites using the GCC codegen backend, you can also run the test suite of the backend itself. + +Now you do that using the following command: + +```text +./x test rustc_codegen_gcc +``` + +The backend needs to be [enabled](#choosing-which-codegen-backends-are-built) for this to work. diff --git a/src/doc/rustc-dev-guide/src/tests/running.md b/src/doc/rustc-dev-guide/src/tests/running.md index 482f3c42578ae..5c1d667685cec 100644 --- a/src/doc/rustc-dev-guide/src/tests/running.md +++ b/src/doc/rustc-dev-guide/src/tests/running.md @@ -396,39 +396,4 @@ Now, tests should just run, you don't have to set up anything else. [wasm32-wasip1 target support page]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/platform-support/wasm32-wasip1.md#building-the-target. -## Running rustc_codegen_gcc tests - -First thing to know is that it only supports linux x86_64 at the moment. We will -extend its support later on. - -You need to update `codegen-backends` value in your `bootstrap.toml` file in the -`[rust]` section and add "gcc" in the array: - -```toml -codegen-backends = ["llvm", "gcc"] -``` - -Then you need to install libgccjit 12. For example with `apt`: - -```text -apt install libgccjit-12-dev -``` - -Now you can run the following command: - -```text -./x test compiler/rustc_codegen_gcc/ -``` - -If it cannot find the `.so` library (if you installed it with `apt` for example), you -need to pass the library file path with `LIBRARY_PATH`: - -```text -LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12/ ./x test compiler/rustc_codegen_gcc/ -``` - -If you encounter bugs or problems, don't hesitate to open issues on the -[`rustc_codegen_gcc` -repository](https://github.com/rust-lang/rustc_codegen_gcc/). - [`tests/ui`]: https://github.com/rust-lang/rust/tree/master/tests/ui diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 0929d351463cc..337c973a2c84f 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -149,7 +149,10 @@ const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../"; const UNBOXING_LIMIT = 5; // used for search query verification -const REGEX_IDENT = /\p{ID_Start}\p{ID_Continue}*|_\p{ID_Continue}+/uy; +// because searches are often performed using substrings of identifiers, +// and not just full identiferes, we allow them to start with chars that otherwise +// can only appear in the middle of identifiers +const REGEX_IDENT = /\p{ID_Continue}+/uy; const REGEX_INVALID_TYPE_FILTER = /[^a-z]/ui; const MAX_RESULTS = 200; diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js index 6e11dda8532fa..612118607b5cc 100644 --- a/tests/rustdoc-js-std/parser-errors.js +++ b/tests/rustdoc-js-std/parser-errors.js @@ -165,7 +165,7 @@ const PARSED = [ foundElems: 0, userQuery: "_:", returned: [], - error: "Unexpected `_` (not a valid identifier)", + error: "Unexpected `_` in type filter (before `:`)", }, { query: "ab:", diff --git a/tests/rustdoc-js-std/search-by-number.js b/tests/rustdoc-js-std/search-by-number.js new file mode 100644 index 0000000000000..9d1cb5314dcaa --- /dev/null +++ b/tests/rustdoc-js-std/search-by-number.js @@ -0,0 +1,19 @@ +// regression test for https://github.com/rust-lang/rust/issues/147763 +// +// identifiers in search queries should not be required to follow the +// same strict rules around ID_Start that identifers in rust code follow, +// as searches frequently use substrings of identifers. +// +// for example, identifiers cannot start with digits, +// but they can contain them, so we allow search idents to start with digits. + +const EXPECTED = { + 'query': '8', + 'others': [ + { + 'path': 'std', + 'name': 'i8', + 'href': '../std/primitive.i8.html', + }, + ] +};