Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
daf5929
Prepare for merging from rust-lang/rust
Nov 30, 2025
ce49398
Merge ref '3ff30e7eafc1' from rust-lang/rust
Nov 30, 2025
ad7ba50
bless genmc tests
RalfJung Nov 30, 2025
8eb411b
use fully deterministic concurrency for while-queued tests
RalfJung Nov 30, 2025
e8f57f8
Merge pull request #4736 from rust-lang/rustup-2025-11-30
RalfJung Nov 30, 2025
8d01e72
Call rustc_driver::main() for MIRI_BE_RUSTC=host
bjorn3 Nov 4, 2025
f9d8a18
Merge pull request #4731 from bjorn3/simplify_driver
RalfJung Dec 2, 2025
ccde7d4
Support retagging of wildcard references in tree borrows
royAmmerschuber Nov 10, 2025
fb5eb59
Merge pull request #4707 from royAmmerschuber/feature/wildcard-root
RalfJung Dec 3, 2025
f04ad99
rust-analyzer settings: use --compile-time-deps
RalfJung Dec 3, 2025
12b9ce2
Merge pull request #4738 from RalfJung/ra
RalfJung Dec 3, 2025
88c2c81
factor out tree_visitor into own file
royAmmerschuber Dec 3, 2025
9622840
make tree_visitor generic
royAmmerschuber Dec 3, 2025
66e9c33
Prepare for merging from rust-lang/rust
Dec 5, 2025
6661762
Merge ref '864339abf952' from rust-lang/rust
Dec 5, 2025
6cf7bd5
Merge pull request #4742 from rust-lang/rustup-2025-12-05
oli-obk Dec 5, 2025
dfee0da
Add test for misspelled feature name
scrabsha Dec 5, 2025
a57470f
Look for typos when reporting an unknown nightly feature
scrabsha Dec 4, 2025
cf83387
rustdoc: add test case for alias bug
notriddle Dec 6, 2025
fb3a089
rustdoc: avoid dangling alias pointers after merge
notriddle Dec 6, 2025
38a2a3d
rustdoc: test for loading index when user said no
notriddle Dec 6, 2025
6fb8d9f
rustdoc: avoid loading index when user says no
notriddle Dec 6, 2025
de3100e
Prepare for merging from rust-lang/rust
Dec 6, 2025
c5113ca
Implement `Vec::from_fn`
EFanZh Dec 6, 2025
741862c
Merge ref '36b2369c91d3' from rust-lang/rust
Dec 6, 2025
77825a2
ubuntu riscv64 is broken even with extensive retries
RalfJung Dec 6, 2025
c9d097d
Merge pull request #4743 from rust-lang/rustup-2025-12-06
RalfJung Dec 6, 2025
1647f44
feat: Support fstat in linux
hulxv Nov 21, 2025
8b9d1d7
use correct stat type and fix some redundancy
RalfJung Dec 6, 2025
e7650fd
Merge pull request #4714 from hulxv/feat/support-fstat-in-linux
RalfJung Dec 6, 2025
44aaae3
remove readdir_r on FreeBSD: it is deprecated, unused, and untested
RalfJung Dec 6, 2025
a26b26a
cleanup: the *64 functions are Linux-specific
RalfJung Dec 6, 2025
a2910ce
Update windows-gnullvm platform support doc
mati865 Dec 5, 2025
ccefb74
Merge pull request #4745 from RalfJung/fs-shim-cleanup
RalfJung Dec 6, 2025
73f124e
Merge pull request #4739 from royAmmerschuber/feature/refactor-tree-v…
RalfJung Dec 6, 2025
7ad3301
show span when there is an error invoking a global ctor/dtor or the t…
RalfJung Dec 6, 2025
5339794
Merge pull request #4747 from RalfJung/empty-stack-error
RalfJung Dec 6, 2025
183283f
Rollup merge of #149659 - scrabsha:push-vtrtnooqlvvv, r=jdonszelmann
matthiaskrgr Dec 6, 2025
e126ad1
Rollup merge of #149699 - EFanZh:vec-from-fn, r=joboet
matthiaskrgr Dec 6, 2025
d0bcc42
Rollup merge of #149700 - notriddle:alias-loading, r=GuillaumeGomez
matthiaskrgr Dec 6, 2025
1dcaef9
Rollup merge of #149713 - mati865:gnullvm-doc, r=petrochenkov
matthiaskrgr Dec 6, 2025
874b7c2
Rollup merge of #149716 - RalfJung:miri, r=RalfJung
matthiaskrgr Dec 6, 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
24 changes: 10 additions & 14 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use rustc_errors::{
pluralize,
};
use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::used_keywords;
use rustc_span::{BytePos, DUMMY_SP, Ident, Span, SpanSnippetError, Symbol, kw, sym};
Expand Down Expand Up @@ -222,27 +221,24 @@ impl std::fmt::Display for UnaryFixity {
style = "verbose"
)]
struct MisspelledKw {
// We use a String here because `Symbol::into_diag_arg` calls `Symbol::to_ident_string`, which
// prefix the keyword with a `r#` because it aims to print the symbol as an identifier.
similar_kw: String,
#[primary_span]
span: Span,
is_incorrect_case: bool,
}

/// Checks if the given `lookup` identifier is similar to any keyword symbol in `candidates`.
///
/// This is a specialized version of [`Symbol::find_similar`] that constructs an error when a
/// candidate is found.
fn find_similar_kw(lookup: Ident, candidates: &[Symbol]) -> Option<MisspelledKw> {
let lowercase = lookup.name.as_str().to_lowercase();
let lowercase_sym = Symbol::intern(&lowercase);
if candidates.contains(&lowercase_sym) {
Some(MisspelledKw { similar_kw: lowercase, span: lookup.span, is_incorrect_case: true })
} else if let Some(similar_sym) = find_best_match_for_name(candidates, lookup.name, None) {
Some(MisspelledKw {
similar_kw: similar_sym.to_string(),
span: lookup.span,
is_incorrect_case: false,
})
} else {
None
}
lookup.name.find_similar(candidates).map(|(similar_kw, is_incorrect_case)| MisspelledKw {
similar_kw: similar_kw.to_string(),
is_incorrect_case,
span: lookup.span,
})
}

struct MultiSugg {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,8 @@ passes_missing_panic_handler =
passes_missing_stability_attr =
{$descr} has missing stability attribute
passes_misspelled_feature = there is a feature with a similar name: `{$actual_name}`
passes_mixed_export_name_and_no_mangle = `{$no_mangle_attr}` attribute may not be used in combination with `{$export_name_attr}`
.label = `{$no_mangle_attr}` is ignored
.note = `{$export_name_attr}` takes precedence
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,21 @@ pub(crate) struct UnknownFeature {
#[primary_span]
pub span: Span,
pub feature: Symbol,
#[subdiagnostic]
pub suggestion: Option<MisspelledFeature>,
}

#[derive(Subdiagnostic)]
#[suggestion(
passes_misspelled_feature,
style = "verbose",
code = "{actual_name}",
applicability = "maybe-incorrect"
)]
pub(crate) struct MisspelledFeature {
#[primary_span]
pub span: Span,
pub actual_name: Symbol,
}

#[derive(Diagnostic)]
Expand Down
30 changes: 24 additions & 6 deletions compiler/rustc_passes/src/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::num::NonZero;
use rustc_ast_lowering::stability::extern_abi_stability;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
use rustc_feature::{EnabledLangFeature, EnabledLibFeature};
use rustc_feature::{EnabledLangFeature, EnabledLibFeature, UNSTABLE_LANG_FEATURES};
use rustc_hir::attrs::{AttributeKind, DeprecatedSince};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalModDefId};
Expand Down Expand Up @@ -1062,11 +1062,13 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
// no unknown features, because the collection also does feature attribute validation.
let local_defined_features = tcx.lib_features(LOCAL_CRATE);
if !remaining_lib_features.is_empty() || !remaining_implications.is_empty() {
let crates = tcx.crates(());

// Loading the implications of all crates is unavoidable to be able to emit the partial
// stabilization diagnostic, but it can be avoided when there are no
// `remaining_lib_features`.
let mut all_implications = remaining_implications.clone();
for &cnum in tcx.crates(()) {
for &cnum in crates {
all_implications
.extend_unord(tcx.stability_implications(cnum).items().map(|(k, v)| (*k, *v)));
}
Expand All @@ -1079,7 +1081,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
&all_implications,
);

for &cnum in tcx.crates(()) {
for &cnum in crates {
if remaining_lib_features.is_empty() && remaining_implications.is_empty() {
break;
}
Expand All @@ -1091,10 +1093,26 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
&all_implications,
);
}
}

for (feature, span) in remaining_lib_features {
tcx.dcx().emit_err(errors::UnknownFeature { span, feature });
if !remaining_lib_features.is_empty() {
let lang_features =
UNSTABLE_LANG_FEATURES.iter().map(|feature| feature.name).collect::<Vec<_>>();
let lib_features = crates
.into_iter()
.flat_map(|&cnum| {
tcx.lib_features(cnum).stability.keys().copied().into_sorted_stable_ord()
})
.collect::<Vec<_>>();

let valid_feature_names = [lang_features, lib_features].concat();

for (feature, span) in remaining_lib_features {
let suggestion = feature
.find_similar(&valid_feature_names)
.map(|(actual_name, _)| errors::MisspelledFeature { span, actual_name });
tcx.dcx().emit_err(errors::UnknownFeature { span, feature, suggestion });
}
}
}

for (&implied_by, &feature) in remaining_implications.to_sorted_stable_ord() {
Expand Down
22 changes: 22 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use rustc_data_structures::stable_hasher::{
use rustc_data_structures::sync::Lock;
use rustc_macros::{Decodable, Encodable, HashStable_Generic, symbols};

use crate::edit_distance::find_best_match_for_name;
use crate::{DUMMY_SP, Edition, Span, with_session_globals};

#[cfg(test)]
Expand Down Expand Up @@ -2843,6 +2844,27 @@ impl Symbol {
// Avoid creating an empty identifier, because that asserts in debug builds.
if self == sym::empty { String::new() } else { Ident::with_dummy_span(self).to_string() }
}

/// Checks if `self` is similar to any symbol in `candidates`.
///
/// The returned boolean represents whether the candidate is the same symbol with a different
/// casing.
///
/// All the candidates are assumed to be lowercase.
pub fn find_similar(
self,
candidates: &[Symbol],
) -> Option<(Symbol, /* is incorrect case */ bool)> {
let lowercase = self.as_str().to_lowercase();
let lowercase_sym = Symbol::intern(&lowercase);
if candidates.contains(&lowercase_sym) {
Some((lowercase_sym, true))
} else if let Some(similar_sym) = find_best_match_for_name(candidates, self, None) {
Some((similar_sym, false))
} else {
None
}
}
}

impl fmt::Debug for Symbol {
Expand Down
53 changes: 53 additions & 0 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,59 @@ impl<T> Vec<T> {
unsafe { Self::from_parts_in(ptr, length, capacity, Global) }
}

/// Creates a `Vec<T>` where each element is produced by calling `f` with
/// that element's index while walking forward through the `Vec<T>`.
///
/// This is essentially the same as writing
///
/// ```text
/// vec![f(0), f(1), f(2), …, f(length - 2), f(length - 1)]
/// ```
/// and is similar to `(0..i).map(f)`, just for `Vec<T>`s not iterators.
///
/// If `length == 0`, this produces an empty `Vec<T>` without ever calling `f`.
///
/// # Example
///
/// ```rust
/// #![feature(vec_from_fn)]
///
/// let vec = Vec::from_fn(5, |i| i);
///
/// // indexes are: 0 1 2 3 4
/// assert_eq!(vec, [0, 1, 2, 3, 4]);
///
/// let vec2 = Vec::from_fn(8, |i| i * 2);
///
/// // indexes are: 0 1 2 3 4 5 6 7
/// assert_eq!(vec2, [0, 2, 4, 6, 8, 10, 12, 14]);
///
/// let bool_vec = Vec::from_fn(5, |i| i % 2 == 0);
///
/// // indexes are: 0 1 2 3 4
/// assert_eq!(bool_vec, [true, false, true, false, true]);
/// ```
///
/// The `Vec<T>` is generated in ascending index order, starting from the front
/// and going towards the back, so you can use closures with mutable state:
/// ```
/// #![feature(vec_from_fn)]
///
/// let mut state = 1;
/// let a = Vec::from_fn(6, |_| { let x = state; state *= 2; x });
///
/// assert_eq!(a, [1, 2, 4, 8, 16, 32]);
/// ```
#[cfg(not(no_global_oom_handling))]
#[inline]
#[unstable(feature = "vec_from_fn", reason = "new API", issue = "149698")]
pub fn from_fn<F>(length: usize, f: F) -> Self
where
F: FnMut(usize) -> T,
{
(0..length).map(f).collect()
}

/// Decomposes a `Vec<T>` into its raw components: `(pointer, length, capacity)`.
///
/// Returns the raw pointer to the underlying data, the length of
Expand Down
54 changes: 26 additions & 28 deletions src/doc/rustc/src/platform-support/windows-gnullvm.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

**Tier: 2 (with host tools)**

Windows targets similar to `*-windows-gnu` but using UCRT as the runtime and various LLVM tools/libraries instead of GCC/Binutils.
Windows targets similar to `*-windows-gnu` but using UCRT as the runtime and various LLVM tools/libraries instead of
GCC/Binutils.

Target triples available so far:

- `aarch64-pc-windows-gnullvm`
- `i686-pc-windows-gnullvm`
- `x86_64-pc-windows-gnullvm`
Expand All @@ -16,48 +18,44 @@ Target triples available so far:

## Requirements

The easiest way to obtain these targets is cross-compilation, but native build from `x86_64-pc-windows-gnu` is possible with few hacks which I don't recommend.
Std support is expected to be on par with `*-windows-gnu`.
Building those targets requires an LLVM-based C toolchain, for example, [llvm-mingw][1] or [MSYS2][2] with CLANG*
environment.

Binaries for this target should be at least on par with `*-windows-gnu` in terms of requirements and functionality.
Binaries for this target should be at least on par with `*-windows-gnu` in terms of requirements and functionality,
except for implicit self-contained mode (explained in [the section below](#building-rust-programs)).

Those targets follow Windows calling convention for `extern "C"`.

Like with any other Windows target, created binaries are in PE format.

## Building the target

These targets can be easily cross-compiled
using [llvm-mingw](https://github.com/mstorsjo/llvm-mingw) toolchain or [MSYS2 CLANG*](https://www.msys2.org/docs/environments/) environments.
Just fill `[target.*]` sections for both build and resulting compiler and set installation prefix in `bootstrap.toml`.
Then run `./x.py install`.
In my case I had ran `./x.py install --host x86_64-pc-windows-gnullvm --target x86_64-pc-windows-gnullvm` inside MSYS2 MINGW64 shell
so `x86_64-pc-windows-gnu` was my build toolchain.

Native bootstrapping is doable in two ways:
- cross-compile gnullvm host toolchain and use it as build toolchain for the next build,
- copy libunwind libraries and rename them to mimic libgcc like here: https://github.com/msys2/MINGW-packages/blob/68e640756df2df6df6afa60f025e3f936e7b977c/mingw-w64-rust/PKGBUILD#L108-L109, stage0 compiler will be mostly broken but good enough to build the next stage.

The second option might stop working anytime, so it's not recommended.
Both native and cross-compilation builds are supported and function similarly to other Rust targets.

## Building Rust programs

Rust does ship a pre-compiled std library for those targets.
That means one can easily cross-compile for those targets from other hosts if C proper toolchain is installed.
Rust ships both std and host tools for those targets. That allows using them as both the host and the target.

Alternatively full toolchain can be built as described in the previous section.
When used as the host and building pure Rust programs, no additional C toolchain is required.
The only requirements are to install `rust-mingw` component and to set `rust-lld` as the linker.
Otherwise, you will need to install the C toolchain mentioned previously.
There is no automatic fallback to `rust-lld` when the C toolchain is missing yet, but it may be added in the future.

## Testing

Created binaries work fine on Windows or Wine using native hardware. Testing AArch64 on x86_64 is problematic though and requires spending some time with QEMU.
Most of x86_64 testsuite does pass when cross-compiling,
with exception for `rustdoc` and `ui-fulldeps` that fail with and error regarding a missing library,
they do pass in native builds though.
The only failing test is std's `process::tests::test_proc_thread_attributes` for unknown reason.
Created binaries work fine on Windows and Linux with Wine using native hardware.
Testing AArch64 on x86_64 is problematic, though, and requires launching a whole AArch64 system with QEMU.

Most of the x86_64 testsuite does pass, but because it isn't run on CI, different failures are expected over time.

## Cross-compilation toolchains and C code

Compatible C code can be built with Clang's `aarch64-pc-windows-gnu`, `i686-pc-windows-gnullvm` and `x86_64-pc-windows-gnu` targets as long as LLVM-based C toolchains are used.
Those include:
- [llvm-mingw](https://github.com/mstorsjo/llvm-mingw)
- [MSYS2 with CLANG* environment](https://www.msys2.org/docs/environments)
Compatible C code can be built with Clang's `aarch64-pc-windows-gnu`, `i686-pc-windows-gnullvm` and
`x86_64-pc-windows-gnu` targets as long as LLVM-based C toolchains are used. Those include:

- [llvm-mingw][1]
- [MSYS2][2] with CLANG* environment

[1]: https://github.com/mstorsjo/llvm-mingw

[2]: https://www.msys2.org/docs/environments
12 changes: 10 additions & 2 deletions src/librustdoc/html/render/search_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use tracing::instrument;

use crate::clean::types::{Function, Generics, ItemId, Type, WherePredicate};
use crate::clean::{self, utils};
use crate::config::ShouldMerge;
use crate::error::Error;
use crate::formats::cache::{Cache, OrphanImplItem};
use crate::formats::item_type::ItemType;
Expand Down Expand Up @@ -721,7 +722,9 @@ impl SerializedSearchIndex {
}
},
),
self.alias_pointers[id].and_then(|alias| map.get(&alias).copied()),
self.alias_pointers[id].and_then(|alias| {
if self.names[alias].is_empty() { None } else { map.get(&alias).copied() }
}),
);
}
new.generic_inverted_index = self
Expand Down Expand Up @@ -1248,6 +1251,7 @@ pub(crate) fn build_index(
tcx: TyCtxt<'_>,
doc_root: &Path,
resource_suffix: &str,
should_merge: &ShouldMerge,
) -> Result<SerializedSearchIndex, Error> {
let mut search_index = std::mem::take(&mut cache.search_index);

Expand Down Expand Up @@ -1298,7 +1302,11 @@ pub(crate) fn build_index(
//
// if there's already a search index, load it into memory and add the new entries to it
// otherwise, do nothing
let mut serialized_index = SerializedSearchIndex::load(doc_root, resource_suffix)?;
let mut serialized_index = if should_merge.read_rendered_cci {
SerializedSearchIndex::load(doc_root, resource_suffix)?
} else {
SerializedSearchIndex::default()
};

// The crate always goes first in this list
let crate_name = krate.name(tcx);
Expand Down
10 changes: 8 additions & 2 deletions src/librustdoc/html/render/write_shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,14 @@ pub(crate) fn write_shared(
// Write shared runs within a flock; disable thread dispatching of IO temporarily.
let _lock = try_err!(flock::Lock::new(&lock_file, true, true, true), &lock_file);

let search_index =
build_index(krate, &mut cx.shared.cache, tcx, &cx.dst, &cx.shared.resource_suffix)?;
let search_index = build_index(
krate,
&mut cx.shared.cache,
tcx,
&cx.dst,
&cx.shared.resource_suffix,
&opt.should_merge,
)?;

let crate_name = krate.name(cx.tcx());
let crate_name = crate_name.as_str(); // rand
Expand Down
10 changes: 5 additions & 5 deletions src/tools/miri/.github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ jobs:
os: ubuntu-24.04-arm
multiarch: armhf
gcc_cross: arm-linux-gnueabihf
- host_target: riscv64gc-unknown-linux-gnu
os: ubuntu-latest
multiarch: riscv64
gcc_cross: riscv64-linux-gnu
qemu: true
# Ubuntu mirrors are not reliable enough for these architectures
# (see <https://bugs.launchpad.net/ubuntu/+bug/2130309>).
# - host_target: riscv64gc-unknown-linux-gnu
# os: ubuntu-latest
# multiarch: riscv64
# gcc_cross: riscv64-linux-gnu
# qemu: true
# - host_target: s390x-unknown-linux-gnu
# os: ubuntu-latest
# multiarch: s390x
Expand Down
Loading
Loading