Skip to content

Commit d427ddf

Browse files
committed
Auto merge of #149717 - matthiaskrgr:rollup-spntobh, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #149659 (Look for typos when reporting an unknown nightly feature) - #149699 (Implement `Vec::from_fn`) - #149700 (rustdoc: fix bugs with search aliases and merging) - #149713 (Update windows-gnullvm platform support doc) - #149716 (miri subtree update) r? `@ghost` `@rustbot` modify labels: rollup
2 parents ba86c04 + 874b7c2 commit d427ddf

File tree

99 files changed

+2643
-869
lines changed

Some content is hidden

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

99 files changed

+2643
-869
lines changed

compiler/rustc_parse/src/parser/diagnostics.rs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use rustc_errors::{
1616
pluralize,
1717
};
1818
use rustc_session::errors::ExprParenthesesNeeded;
19-
use rustc_span::edit_distance::find_best_match_for_name;
2019
use rustc_span::source_map::Spanned;
2120
use rustc_span::symbol::used_keywords;
2221
use rustc_span::{BytePos, DUMMY_SP, Ident, Span, SpanSnippetError, Symbol, kw, sym};
@@ -222,27 +221,24 @@ impl std::fmt::Display for UnaryFixity {
222221
style = "verbose"
223222
)]
224223
struct MisspelledKw {
224+
// We use a String here because `Symbol::into_diag_arg` calls `Symbol::to_ident_string`, which
225+
// prefix the keyword with a `r#` because it aims to print the symbol as an identifier.
225226
similar_kw: String,
226227
#[primary_span]
227228
span: Span,
228229
is_incorrect_case: bool,
229230
}
230231

231232
/// Checks if the given `lookup` identifier is similar to any keyword symbol in `candidates`.
233+
///
234+
/// This is a specialized version of [`Symbol::find_similar`] that constructs an error when a
235+
/// candidate is found.
232236
fn find_similar_kw(lookup: Ident, candidates: &[Symbol]) -> Option<MisspelledKw> {
233-
let lowercase = lookup.name.as_str().to_lowercase();
234-
let lowercase_sym = Symbol::intern(&lowercase);
235-
if candidates.contains(&lowercase_sym) {
236-
Some(MisspelledKw { similar_kw: lowercase, span: lookup.span, is_incorrect_case: true })
237-
} else if let Some(similar_sym) = find_best_match_for_name(candidates, lookup.name, None) {
238-
Some(MisspelledKw {
239-
similar_kw: similar_sym.to_string(),
240-
span: lookup.span,
241-
is_incorrect_case: false,
242-
})
243-
} else {
244-
None
245-
}
237+
lookup.name.find_similar(candidates).map(|(similar_kw, is_incorrect_case)| MisspelledKw {
238+
similar_kw: similar_kw.to_string(),
239+
is_incorrect_case,
240+
span: lookup.span,
241+
})
246242
}
247243

248244
struct MultiSugg {

compiler/rustc_passes/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,8 @@ passes_missing_panic_handler =
421421
passes_missing_stability_attr =
422422
{$descr} has missing stability attribute
423423
424+
passes_misspelled_feature = there is a feature with a similar name: `{$actual_name}`
425+
424426
passes_mixed_export_name_and_no_mangle = `{$no_mangle_attr}` attribute may not be used in combination with `{$export_name_attr}`
425427
.label = `{$no_mangle_attr}` is ignored
426428
.note = `{$export_name_attr}` takes precedence

compiler/rustc_passes/src/errors.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,21 @@ pub(crate) struct UnknownFeature {
11831183
#[primary_span]
11841184
pub span: Span,
11851185
pub feature: Symbol,
1186+
#[subdiagnostic]
1187+
pub suggestion: Option<MisspelledFeature>,
1188+
}
1189+
1190+
#[derive(Subdiagnostic)]
1191+
#[suggestion(
1192+
passes_misspelled_feature,
1193+
style = "verbose",
1194+
code = "{actual_name}",
1195+
applicability = "maybe-incorrect"
1196+
)]
1197+
pub(crate) struct MisspelledFeature {
1198+
#[primary_span]
1199+
pub span: Span,
1200+
pub actual_name: Symbol,
11861201
}
11871202

11881203
#[derive(Diagnostic)]

compiler/rustc_passes/src/stability.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::num::NonZero;
66
use rustc_ast_lowering::stability::extern_abi_stability;
77
use rustc_data_structures::fx::FxIndexMap;
88
use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
9-
use rustc_feature::{EnabledLangFeature, EnabledLibFeature};
9+
use rustc_feature::{EnabledLangFeature, EnabledLibFeature, UNSTABLE_LANG_FEATURES};
1010
use rustc_hir::attrs::{AttributeKind, DeprecatedSince};
1111
use rustc_hir::def::{DefKind, Res};
1212
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalModDefId};
@@ -1062,11 +1062,13 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
10621062
// no unknown features, because the collection also does feature attribute validation.
10631063
let local_defined_features = tcx.lib_features(LOCAL_CRATE);
10641064
if !remaining_lib_features.is_empty() || !remaining_implications.is_empty() {
1065+
let crates = tcx.crates(());
1066+
10651067
// Loading the implications of all crates is unavoidable to be able to emit the partial
10661068
// stabilization diagnostic, but it can be avoided when there are no
10671069
// `remaining_lib_features`.
10681070
let mut all_implications = remaining_implications.clone();
1069-
for &cnum in tcx.crates(()) {
1071+
for &cnum in crates {
10701072
all_implications
10711073
.extend_unord(tcx.stability_implications(cnum).items().map(|(k, v)| (*k, *v)));
10721074
}
@@ -1079,7 +1081,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
10791081
&all_implications,
10801082
);
10811083

1082-
for &cnum in tcx.crates(()) {
1084+
for &cnum in crates {
10831085
if remaining_lib_features.is_empty() && remaining_implications.is_empty() {
10841086
break;
10851087
}
@@ -1091,10 +1093,26 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
10911093
&all_implications,
10921094
);
10931095
}
1094-
}
10951096

1096-
for (feature, span) in remaining_lib_features {
1097-
tcx.dcx().emit_err(errors::UnknownFeature { span, feature });
1097+
if !remaining_lib_features.is_empty() {
1098+
let lang_features =
1099+
UNSTABLE_LANG_FEATURES.iter().map(|feature| feature.name).collect::<Vec<_>>();
1100+
let lib_features = crates
1101+
.into_iter()
1102+
.flat_map(|&cnum| {
1103+
tcx.lib_features(cnum).stability.keys().copied().into_sorted_stable_ord()
1104+
})
1105+
.collect::<Vec<_>>();
1106+
1107+
let valid_feature_names = [lang_features, lib_features].concat();
1108+
1109+
for (feature, span) in remaining_lib_features {
1110+
let suggestion = feature
1111+
.find_similar(&valid_feature_names)
1112+
.map(|(actual_name, _)| errors::MisspelledFeature { span, actual_name });
1113+
tcx.dcx().emit_err(errors::UnknownFeature { span, feature, suggestion });
1114+
}
1115+
}
10981116
}
10991117

11001118
for (&implied_by, &feature) in remaining_implications.to_sorted_stable_ord() {

compiler/rustc_span/src/symbol.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_data_structures::stable_hasher::{
1414
use rustc_data_structures::sync::Lock;
1515
use rustc_macros::{Decodable, Encodable, HashStable_Generic, symbols};
1616

17+
use crate::edit_distance::find_best_match_for_name;
1718
use crate::{DUMMY_SP, Edition, Span, with_session_globals};
1819

1920
#[cfg(test)]
@@ -2843,6 +2844,27 @@ impl Symbol {
28432844
// Avoid creating an empty identifier, because that asserts in debug builds.
28442845
if self == sym::empty { String::new() } else { Ident::with_dummy_span(self).to_string() }
28452846
}
2847+
2848+
/// Checks if `self` is similar to any symbol in `candidates`.
2849+
///
2850+
/// The returned boolean represents whether the candidate is the same symbol with a different
2851+
/// casing.
2852+
///
2853+
/// All the candidates are assumed to be lowercase.
2854+
pub fn find_similar(
2855+
self,
2856+
candidates: &[Symbol],
2857+
) -> Option<(Symbol, /* is incorrect case */ bool)> {
2858+
let lowercase = self.as_str().to_lowercase();
2859+
let lowercase_sym = Symbol::intern(&lowercase);
2860+
if candidates.contains(&lowercase_sym) {
2861+
Some((lowercase_sym, true))
2862+
} else if let Some(similar_sym) = find_best_match_for_name(candidates, self, None) {
2863+
Some((similar_sym, false))
2864+
} else {
2865+
None
2866+
}
2867+
}
28462868
}
28472869

28482870
impl fmt::Debug for Symbol {

library/alloc/src/vec/mod.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,59 @@ impl<T> Vec<T> {
745745
unsafe { Self::from_parts_in(ptr, length, capacity, Global) }
746746
}
747747

748+
/// Creates a `Vec<T>` where each element is produced by calling `f` with
749+
/// that element's index while walking forward through the `Vec<T>`.
750+
///
751+
/// This is essentially the same as writing
752+
///
753+
/// ```text
754+
/// vec![f(0), f(1), f(2), …, f(length - 2), f(length - 1)]
755+
/// ```
756+
/// and is similar to `(0..i).map(f)`, just for `Vec<T>`s not iterators.
757+
///
758+
/// If `length == 0`, this produces an empty `Vec<T>` without ever calling `f`.
759+
///
760+
/// # Example
761+
///
762+
/// ```rust
763+
/// #![feature(vec_from_fn)]
764+
///
765+
/// let vec = Vec::from_fn(5, |i| i);
766+
///
767+
/// // indexes are: 0 1 2 3 4
768+
/// assert_eq!(vec, [0, 1, 2, 3, 4]);
769+
///
770+
/// let vec2 = Vec::from_fn(8, |i| i * 2);
771+
///
772+
/// // indexes are: 0 1 2 3 4 5 6 7
773+
/// assert_eq!(vec2, [0, 2, 4, 6, 8, 10, 12, 14]);
774+
///
775+
/// let bool_vec = Vec::from_fn(5, |i| i % 2 == 0);
776+
///
777+
/// // indexes are: 0 1 2 3 4
778+
/// assert_eq!(bool_vec, [true, false, true, false, true]);
779+
/// ```
780+
///
781+
/// The `Vec<T>` is generated in ascending index order, starting from the front
782+
/// and going towards the back, so you can use closures with mutable state:
783+
/// ```
784+
/// #![feature(vec_from_fn)]
785+
///
786+
/// let mut state = 1;
787+
/// let a = Vec::from_fn(6, |_| { let x = state; state *= 2; x });
788+
///
789+
/// assert_eq!(a, [1, 2, 4, 8, 16, 32]);
790+
/// ```
791+
#[cfg(not(no_global_oom_handling))]
792+
#[inline]
793+
#[unstable(feature = "vec_from_fn", reason = "new API", issue = "149698")]
794+
pub fn from_fn<F>(length: usize, f: F) -> Self
795+
where
796+
F: FnMut(usize) -> T,
797+
{
798+
(0..length).map(f).collect()
799+
}
800+
748801
/// Decomposes a `Vec<T>` into its raw components: `(pointer, length, capacity)`.
749802
///
750803
/// Returns the raw pointer to the underlying data, the length of

src/doc/rustc/src/platform-support/windows-gnullvm.md

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

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

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

78
Target triples available so far:
9+
810
- `aarch64-pc-windows-gnullvm`
911
- `i686-pc-windows-gnullvm`
1012
- `x86_64-pc-windows-gnullvm`
@@ -16,48 +18,44 @@ Target triples available so far:
1618

1719
## Requirements
1820

19-
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.
20-
Std support is expected to be on par with `*-windows-gnu`.
21+
Building those targets requires an LLVM-based C toolchain, for example, [llvm-mingw][1] or [MSYS2][2] with CLANG*
22+
environment.
2123

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

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

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

2831
## Building the target
2932

30-
These targets can be easily cross-compiled
31-
using [llvm-mingw](https://github.com/mstorsjo/llvm-mingw) toolchain or [MSYS2 CLANG*](https://www.msys2.org/docs/environments/) environments.
32-
Just fill `[target.*]` sections for both build and resulting compiler and set installation prefix in `bootstrap.toml`.
33-
Then run `./x.py install`.
34-
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
35-
so `x86_64-pc-windows-gnu` was my build toolchain.
36-
37-
Native bootstrapping is doable in two ways:
38-
- cross-compile gnullvm host toolchain and use it as build toolchain for the next build,
39-
- 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.
40-
41-
The second option might stop working anytime, so it's not recommended.
33+
Both native and cross-compilation builds are supported and function similarly to other Rust targets.
4234

4335
## Building Rust programs
4436

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

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

5044
## Testing
5145

52-
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.
53-
Most of x86_64 testsuite does pass when cross-compiling,
54-
with exception for `rustdoc` and `ui-fulldeps` that fail with and error regarding a missing library,
55-
they do pass in native builds though.
56-
The only failing test is std's `process::tests::test_proc_thread_attributes` for unknown reason.
46+
Created binaries work fine on Windows and Linux with Wine using native hardware.
47+
Testing AArch64 on x86_64 is problematic, though, and requires launching a whole AArch64 system with QEMU.
48+
49+
Most of the x86_64 testsuite does pass, but because it isn't run on CI, different failures are expected over time.
5750

5851
## Cross-compilation toolchains and C code
5952

60-
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.
61-
Those include:
62-
- [llvm-mingw](https://github.com/mstorsjo/llvm-mingw)
63-
- [MSYS2 with CLANG* environment](https://www.msys2.org/docs/environments)
53+
Compatible C code can be built with Clang's `aarch64-pc-windows-gnu`, `i686-pc-windows-gnullvm` and
54+
`x86_64-pc-windows-gnu` targets as long as LLVM-based C toolchains are used. Those include:
55+
56+
- [llvm-mingw][1]
57+
- [MSYS2][2] with CLANG* environment
58+
59+
[1]: https://github.com/mstorsjo/llvm-mingw
60+
61+
[2]: https://www.msys2.org/docs/environments

src/librustdoc/html/render/search_index.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use tracing::instrument;
2424

2525
use crate::clean::types::{Function, Generics, ItemId, Type, WherePredicate};
2626
use crate::clean::{self, utils};
27+
use crate::config::ShouldMerge;
2728
use crate::error::Error;
2829
use crate::formats::cache::{Cache, OrphanImplItem};
2930
use crate::formats::item_type::ItemType;
@@ -721,7 +722,9 @@ impl SerializedSearchIndex {
721722
}
722723
},
723724
),
724-
self.alias_pointers[id].and_then(|alias| map.get(&alias).copied()),
725+
self.alias_pointers[id].and_then(|alias| {
726+
if self.names[alias].is_empty() { None } else { map.get(&alias).copied() }
727+
}),
725728
);
726729
}
727730
new.generic_inverted_index = self
@@ -1248,6 +1251,7 @@ pub(crate) fn build_index(
12481251
tcx: TyCtxt<'_>,
12491252
doc_root: &Path,
12501253
resource_suffix: &str,
1254+
should_merge: &ShouldMerge,
12511255
) -> Result<SerializedSearchIndex, Error> {
12521256
let mut search_index = std::mem::take(&mut cache.search_index);
12531257

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

13031311
// The crate always goes first in this list
13041312
let crate_name = krate.name(tcx);

src/librustdoc/html/render/write_shared.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,14 @@ pub(crate) fn write_shared(
6666
// Write shared runs within a flock; disable thread dispatching of IO temporarily.
6767
let _lock = try_err!(flock::Lock::new(&lock_file, true, true, true), &lock_file);
6868

69-
let search_index =
70-
build_index(krate, &mut cx.shared.cache, tcx, &cx.dst, &cx.shared.resource_suffix)?;
69+
let search_index = build_index(
70+
krate,
71+
&mut cx.shared.cache,
72+
tcx,
73+
&cx.dst,
74+
&cx.shared.resource_suffix,
75+
&opt.should_merge,
76+
)?;
7177

7278
let crate_name = krate.name(cx.tcx());
7379
let crate_name = crate_name.as_str(); // rand

src/tools/miri/.github/workflows/ci.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ jobs:
3131
os: ubuntu-24.04-arm
3232
multiarch: armhf
3333
gcc_cross: arm-linux-gnueabihf
34-
- host_target: riscv64gc-unknown-linux-gnu
35-
os: ubuntu-latest
36-
multiarch: riscv64
37-
gcc_cross: riscv64-linux-gnu
38-
qemu: true
3934
# Ubuntu mirrors are not reliable enough for these architectures
4035
# (see <https://bugs.launchpad.net/ubuntu/+bug/2130309>).
36+
# - host_target: riscv64gc-unknown-linux-gnu
37+
# os: ubuntu-latest
38+
# multiarch: riscv64
39+
# gcc_cross: riscv64-linux-gnu
40+
# qemu: true
4141
# - host_target: s390x-unknown-linux-gnu
4242
# os: ubuntu-latest
4343
# multiarch: s390x

0 commit comments

Comments
 (0)