diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e6a00bb42785..4409d4f33afc 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -165,9 +165,6 @@ jobs:
- name: install sccache
run: src/ci/scripts/install-sccache.sh
- - name: select Xcode
- run: src/ci/scripts/select-xcode.sh
-
- name: install clang
run: src/ci/scripts/install-clang.sh
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2b5699dcd098..3f052eca48e6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -10,7 +10,7 @@ the Zulip stream is the best place to *ask* for help.
Documentation for contributing to the compiler or tooling is located in the [Guide to Rustc
Development][rustc-dev-guide], commonly known as the [rustc-dev-guide]. Documentation for the
-standard library in the [Standard library developers Guide][std-dev-guide], commonly known as the [std-dev-guide].
+standard library is in the [Standard library developers Guide][std-dev-guide], commonly known as the [std-dev-guide].
## Making changes to subtrees and submodules
diff --git a/Cargo.lock b/Cargo.lock
index 63c7d97bce43..4307639a5099 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -184,9 +184,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "askama"
-version = "0.15.2"
+version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03341eae1125472b0672fbf35cc9aa7b74cd8e0c3d02f02c28a04678f12aaa7a"
+checksum = "08e1676b346cadfec169374f949d7490fd80a24193d37d2afce0c047cf695e57"
dependencies = [
"askama_macros",
"itoa",
@@ -197,9 +197,9 @@ dependencies = [
[[package]]
name = "askama_derive"
-version = "0.15.2"
+version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "461bd78f3da90b5e44eee4272cfb1c4832aa3dcdb6c370aedd3eb253d2b9e3ca"
+checksum = "7661ff56517787343f376f75db037426facd7c8d3049cef8911f1e75016f3a37"
dependencies = [
"askama_parser",
"basic-toml",
@@ -214,18 +214,18 @@ dependencies = [
[[package]]
name = "askama_macros"
-version = "0.15.2"
+version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba49fb22ee3074574b8510abd9495d4f0bb9b8f87e8e45ee31e2cee508f7a8e5"
+checksum = "713ee4dbfd1eb719c2dab859465b01fa1d21cb566684614a713a6b7a99a4e47b"
dependencies = [
"askama_derive",
]
[[package]]
name = "askama_parser"
-version = "0.15.2"
+version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e33eb7484958aaa1f27e9adb556f5d557331cd891bdbb33781bc1f9550b6f6e"
+checksum = "1d62d674238a526418b30c0def480d5beadb9d8964e7f38d635b03bf639c704c"
dependencies = [
"rustc-hash 2.1.1",
"serde",
@@ -580,9 +580,9 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.5.51"
+version = "4.5.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5"
+checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394"
dependencies = [
"clap_builder",
"clap_derive",
@@ -600,9 +600,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.5.51"
+version = "4.5.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a"
+checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00"
dependencies = [
"anstream",
"anstyle",
@@ -1298,9 +1298,9 @@ dependencies = [
[[package]]
name = "ena"
-version = "0.14.3"
+version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5"
+checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1"
dependencies = [
"log",
]
@@ -3490,7 +3490,6 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_macros",
@@ -3515,7 +3514,6 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
- "rustc_fluent_macro",
"rustc_macros",
"rustc_session",
"rustc_span",
@@ -3541,9 +3539,9 @@ dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_ast_pretty",
+ "rustc_data_structures",
"rustc_errors",
"rustc_feature",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_lexer",
"rustc_macros",
@@ -3574,7 +3572,6 @@ dependencies = [
"rustc_abi",
"rustc_data_structures",
"rustc_errors",
- "rustc_fluent_macro",
"rustc_graphviz",
"rustc_hir",
"rustc_index",
@@ -3602,7 +3599,6 @@ dependencies = [
"rustc_errors",
"rustc_expand",
"rustc_feature",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_lexer",
@@ -3636,7 +3632,6 @@ dependencies = [
"rustc_codegen_ssa",
"rustc_data_structures",
"rustc_errors",
- "rustc_fluent_macro",
"rustc_fs_util",
"rustc_hashes",
"rustc_hir",
@@ -3674,7 +3669,6 @@ dependencies = [
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
- "rustc_fluent_macro",
"rustc_fs_util",
"rustc_hashes",
"rustc_hir",
@@ -3684,7 +3678,6 @@ dependencies = [
"rustc_macros",
"rustc_metadata",
"rustc_middle",
- "rustc_query_system",
"rustc_serialize",
"rustc_session",
"rustc_span",
@@ -3694,7 +3687,6 @@ dependencies = [
"serde_json",
"smallvec",
"tempfile",
- "thin-vec",
"thorin-dwp",
"tracing",
"wasm-encoder 0.219.2",
@@ -3711,7 +3703,6 @@ dependencies = [
"rustc_ast",
"rustc_data_structures",
"rustc_errors",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_infer",
@@ -3777,25 +3768,16 @@ dependencies = [
"libc",
"rustc_abi",
"rustc_ast",
- "rustc_ast_lowering",
- "rustc_ast_passes",
"rustc_ast_pretty",
- "rustc_attr_parsing",
- "rustc_borrowck",
- "rustc_builtin_macros",
"rustc_codegen_ssa",
"rustc_const_eval",
"rustc_data_structures",
"rustc_errors",
"rustc_expand",
"rustc_feature",
- "rustc_fluent_macro",
"rustc_hir_analysis",
"rustc_hir_pretty",
- "rustc_hir_typeck",
- "rustc_incremental",
"rustc_index",
- "rustc_infer",
"rustc_interface",
"rustc_lexer",
"rustc_lint",
@@ -3804,21 +3786,13 @@ dependencies = [
"rustc_metadata",
"rustc_middle",
"rustc_mir_build",
- "rustc_mir_dataflow",
"rustc_mir_transform",
- "rustc_monomorphize",
"rustc_parse",
- "rustc_passes",
- "rustc_pattern_analysis",
- "rustc_privacy",
"rustc_public",
- "rustc_query_system",
"rustc_resolve",
"rustc_session",
"rustc_span",
"rustc_target",
- "rustc_trait_selection",
- "rustc_ty_utils",
"serde_json",
"shlex",
"tracing",
@@ -3862,7 +3836,6 @@ dependencies = [
"rustc_data_structures",
"rustc_error_codes",
"rustc_error_messages",
- "rustc_fluent_macro",
"rustc_hashes",
"rustc_index",
"rustc_lint_defs",
@@ -3887,7 +3860,6 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_lexer",
"rustc_lint_defs",
@@ -3915,19 +3887,6 @@ dependencies = [
"serde_json",
]
-[[package]]
-name = "rustc_fluent_macro"
-version = "0.0.0"
-dependencies = [
- "annotate-snippets 0.11.5",
- "fluent-bundle",
- "fluent-syntax",
- "proc-macro2",
- "quote",
- "syn 2.0.110",
- "unic-langid",
-]
-
[[package]]
name = "rustc_fs_util"
version = "0.0.0"
@@ -3982,7 +3941,6 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_infer",
@@ -4029,7 +3987,6 @@ dependencies = [
"rustc_ast",
"rustc_data_structures",
"rustc_errors",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_hir_analysis",
"rustc_hir_pretty",
@@ -4051,10 +4008,8 @@ name = "rustc_incremental"
version = "0.0.0"
dependencies = [
"rand 0.9.2",
- "rustc_ast",
"rustc_data_structures",
"rustc_errors",
- "rustc_fluent_macro",
"rustc_fs_util",
"rustc_graphviz",
"rustc_hashes",
@@ -4064,7 +4019,6 @@ dependencies = [
"rustc_serialize",
"rustc_session",
"rustc_span",
- "thin-vec",
"tracing",
]
@@ -4093,7 +4047,6 @@ version = "0.0.0"
dependencies = [
"rustc_data_structures",
"rustc_errors",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_macros",
@@ -4124,7 +4077,6 @@ dependencies = [
"rustc_errors",
"rustc_expand",
"rustc_feature",
- "rustc_fluent_macro",
"rustc_fs_util",
"rustc_hir",
"rustc_hir_analysis",
@@ -4141,7 +4093,6 @@ dependencies = [
"rustc_passes",
"rustc_privacy",
"rustc_query_impl",
- "rustc_query_system",
"rustc_resolve",
"rustc_session",
"rustc_span",
@@ -4177,7 +4128,6 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_infer",
@@ -4229,6 +4179,8 @@ dependencies = [
name = "rustc_macros"
version = "0.0.0"
dependencies = [
+ "fluent-bundle",
+ "fluent-syntax",
"proc-macro2",
"quote",
"syn 2.0.110",
@@ -4250,7 +4202,6 @@ dependencies = [
"rustc_errors",
"rustc_expand",
"rustc_feature",
- "rustc_fluent_macro",
"rustc_fs_util",
"rustc_hir",
"rustc_hir_pretty",
@@ -4274,6 +4225,7 @@ dependencies = [
"bitflags",
"either",
"gsgdt",
+ "parking_lot",
"polonius-engine",
"rustc_abi",
"rustc_apfloat",
@@ -4284,7 +4236,6 @@ dependencies = [
"rustc_error_messages",
"rustc_errors",
"rustc_feature",
- "rustc_fluent_macro",
"rustc_graphviz",
"rustc_hashes",
"rustc_hir",
@@ -4315,7 +4266,6 @@ dependencies = [
"rustc_ast",
"rustc_data_structures",
"rustc_errors",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_infer",
@@ -4336,11 +4286,10 @@ dependencies = [
"polonius-engine",
"regex",
"rustc_abi",
- "rustc_ast",
"rustc_data_structures",
"rustc_errors",
- "rustc_fluent_macro",
"rustc_graphviz",
+ "rustc_hir",
"rustc_index",
"rustc_macros",
"rustc_middle",
@@ -4354,7 +4303,6 @@ name = "rustc_mir_transform"
version = "0.0.0"
dependencies = [
"either",
- "hashbrown 0.16.1",
"itertools",
"rustc_abi",
"rustc_arena",
@@ -4362,7 +4310,6 @@ dependencies = [
"rustc_const_eval",
"rustc_data_structures",
"rustc_errors",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_infer",
@@ -4384,7 +4331,6 @@ dependencies = [
"rustc_abi",
"rustc_data_structures",
"rustc_errors",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_macros",
@@ -4421,7 +4367,6 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
- "rustc_fluent_macro",
"rustc_index",
"rustc_lexer",
"rustc_macros",
@@ -4454,7 +4399,6 @@ dependencies = [
"rustc_errors",
"rustc_expand",
"rustc_feature",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_macros",
@@ -4477,7 +4421,6 @@ dependencies = [
"rustc_arena",
"rustc_data_structures",
"rustc_errors",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_macros",
@@ -4497,7 +4440,6 @@ dependencies = [
"rustc_ast",
"rustc_data_structures",
"rustc_errors",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_macros",
"rustc_middle",
@@ -4550,14 +4492,19 @@ name = "rustc_query_impl"
version = "0.0.0"
dependencies = [
"measureme",
+ "rustc_abi",
"rustc_data_structures",
+ "rustc_errors",
"rustc_hashes",
"rustc_hir",
"rustc_index",
+ "rustc_macros",
"rustc_middle",
"rustc_query_system",
"rustc_serialize",
+ "rustc_session",
"rustc_span",
+ "rustc_thread_pool",
"tracing",
]
@@ -4565,24 +4512,17 @@ dependencies = [
name = "rustc_query_system"
version = "0.0.0"
dependencies = [
- "hashbrown 0.16.1",
- "parking_lot",
"rustc_abi",
"rustc_ast",
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
- "rustc_fluent_macro",
- "rustc_hashes",
"rustc_hir",
- "rustc_index",
"rustc_macros",
"rustc_serialize",
"rustc_session",
"rustc_span",
- "rustc_thread_pool",
"smallvec",
- "tracing",
]
[[package]]
@@ -4600,13 +4540,11 @@ dependencies = [
"rustc_errors",
"rustc_expand",
"rustc_feature",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_macros",
"rustc_metadata",
"rustc_middle",
- "rustc_query_system",
"rustc_session",
"rustc_span",
"smallvec",
@@ -4654,7 +4592,6 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
- "rustc_fluent_macro",
"rustc_fs_util",
"rustc_hashes",
"rustc_hir",
@@ -4761,7 +4698,6 @@ dependencies = [
"rustc_ast",
"rustc_data_structures",
"rustc_errors",
- "rustc_fluent_macro",
"rustc_hir",
"rustc_infer",
"rustc_macros",
@@ -4810,7 +4746,6 @@ dependencies = [
"rustc_abi",
"rustc_data_structures",
"rustc_errors",
- "rustc_fluent_macro",
"rustc_hashes",
"rustc_hir",
"rustc_index",
@@ -5623,7 +5558,7 @@ version = "0.1.0"
dependencies = [
"build_helper",
"cargo_metadata 0.21.0",
- "fluent-syntax",
+ "clap",
"globset",
"ignore",
"miropt-test-tools",
diff --git a/INSTALL.md b/INSTALL.md
index dd6c64b3df5f..0e998101fcd1 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -233,7 +233,7 @@ itself back on after some time).
### MSVC
-MSVC builds of Rust additionally requires an installation of:
+MSVC builds of Rust additionally require an installation of:
- Visual Studio 2022 (or later) build tools so `rustc` can use its linker. Older
Visual Studio versions such as 2019 *may* work but aren't actively tested.
diff --git a/RELEASES.md b/RELEASES.md
index 424e12ceec05..29c787f4e14c 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,12 @@
+Version 1.93.1 (2026-02-12)
+===========================
+
+
+
+- [Don't try to recover keyword as non-keyword identifier](https://github.com/rust-lang/rust/pull/150590), fixing an ICE that especially [affected rustfmt](https://github.com/rust-lang/rustfmt/issues/6739).
+- [Fix `clippy::panicking_unwrap` false-positive on field access with implicit deref](https://github.com/rust-lang/rust-clippy/pull/16196).
+- [Revert "Update wasm-related dependencies in CI"](https://github.com/rust-lang/rust/pull/152259), fixing file descriptor leaks on the `wasm32-wasip2` target.
+
Version 1.93.0 (2026-01-22)
==========================
@@ -1546,7 +1555,7 @@ Compatibility Notes
- [Check well-formedness of the source type's signature in fn pointer casts.](https://github.com/rust-lang/rust/pull/129021) This partly closes a soundness hole that comes when casting a function item to function pointer
- [Use equality instead of subtyping when resolving type dependent paths.](https://github.com/rust-lang/rust/pull/129073)
- Linking on macOS now correctly includes Rust's default deployment target. Due to a linker bug, you might have to pass `MACOSX_DEPLOYMENT_TARGET` or fix your `#[link]` attributes to point to the correct frameworks. See .
-- [Rust will now correctly raise an error for `repr(Rust)` written on non-`struct`/`enum`/`union` items, since it previous did not have any effect.](https://github.com/rust-lang/rust/pull/129422)
+- [Rust will now correctly raise an error for `repr(Rust)` written on non-`struct`/`enum`/`union` items, since it previously did not have any effect.](https://github.com/rust-lang/rust/pull/129422)
- The future incompatibility lint `deprecated_cfg_attr_crate_type_name` [has been made into a hard error](https://github.com/rust-lang/rust/pull/129670). It was used to deny usage of `#![crate_type]` and `#![crate_name]` attributes in `#![cfg_attr]`, which required a hack in the compiler to be able to change the used crate type and crate name after cfg expansion.
Users can use `--crate-type` instead of `#![cfg_attr(..., crate_type = "...")]` and `--crate-name` instead of `#![cfg_attr(..., crate_name = "...")]` when running `rustc`/`cargo rustc` on the command line.
Use of those two attributes outside of `#![cfg_attr]` continue to be fully supported.
@@ -1722,7 +1731,7 @@ Cargo
Compatibility Notes
-------------------
- We now [disallow setting some built-in cfgs via the command-line](https://github.com/rust-lang/rust/pull/126158) with the newly added [`explicit_builtin_cfgs_in_flags`](https://doc.rust-lang.org/rustc/lints/listing/deny-by-default.html#explicit-builtin-cfgs-in-flags) lint in order to prevent incoherent state, eg. `windows` cfg active but target is Linux based. The appropriate [`rustc` flag](https://doc.rust-lang.org/rustc/command-line-arguments.html) should be used instead.
-- The standard library has a new implementation of `binary_search` which is significantly improves performance ([#128254](https://github.com/rust-lang/rust/pull/128254)). However when a sorted slice has multiple values which compare equal, the new implementation may select a different value among the equal ones than the old implementation.
+- The standard library has a new implementation of `binary_search` which significantly improves performance ([#128254](https://github.com/rust-lang/rust/pull/128254)). However when a sorted slice has multiple values which compare equal, the new implementation may select a different value among the equal ones than the old implementation.
- [illumos/Solaris now sets `MSG_NOSIGNAL` when writing to sockets](https://github.com/rust-lang/rust/pull/128259). This avoids killing the process with SIGPIPE when writing to a closed socket, which matches the existing behavior on other UNIX targets.
- [Removes a problematic hack that always passed the --whole-archive linker flag for tests, which may cause linker errors for code accidentally relying on it.](https://github.com/rust-lang/rust/pull/128400)
- The WebAssembly target features `multivalue` and `reference-types` are now
@@ -1872,7 +1881,7 @@ These changes do not affect any public interfaces of Rust, but they represent
significant improvements to the performance or internals of rustc and related
tools.
-- [Add a Rust-for Linux `auto` CI job to check kernel builds.](https://github.com/rust-lang/rust/pull/125209/)
+- [Add a Rust-for-Linux `auto` CI job to check kernel builds.](https://github.com/rust-lang/rust/pull/125209/)
Version 1.80.1 (2024-08-08)
===========================
@@ -4510,7 +4519,7 @@ Compatibility Notes
saturating to `0` instead][89926]. In the real world the panic happened mostly
on platforms with buggy monotonic clock implementations rather than catching
programming errors like reversing the start and end times. Such programming
- errors will now results in `0` rather than a panic.
+ errors will now result in `0` rather than a panic.
- In a future release we're planning to increase the baseline requirements for
the Linux kernel to version 3.2, and for glibc to version 2.17. We'd love
your feedback in [PR #95026][95026].
diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs
index 89c61cdf00a5..30d64b05cfde 100644
--- a/compiler/rustc/src/main.rs
+++ b/compiler/rustc/src/main.rs
@@ -3,6 +3,8 @@
// Several crates are depended upon but unused so that they are present in the sysroot
#![expect(unused_crate_dependencies)]
+use std::process::ExitCode;
+
// A note about jemalloc: rustc uses jemalloc when built for CI and
// distribution. The obvious way to do this is with the `#[global_allocator]`
// mechanism. However, for complicated reasons (see
@@ -38,6 +40,6 @@
#[cfg(feature = "jemalloc")]
use tikv_jemalloc_sys as _;
-fn main() {
+fn main() -> ExitCode {
rustc_driver::main()
}
diff --git a/compiler/rustc_abi/src/callconv/reg.rs b/compiler/rustc_abi/src/callconv/reg.rs
index 66c8056d0c2a..66d4dca00726 100644
--- a/compiler/rustc_abi/src/callconv/reg.rs
+++ b/compiler/rustc_abi/src/callconv/reg.rs
@@ -35,6 +35,7 @@ impl Reg {
reg_ctor!(f32, Float, 32);
reg_ctor!(f64, Float, 64);
+ reg_ctor!(f128, Float, 128);
}
impl Reg {
diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs
index 41ad14f550ab..aafb124986e1 100644
--- a/compiler/rustc_abi/src/layout/ty.rs
+++ b/compiler/rustc_abi/src/layout/ty.rs
@@ -290,7 +290,19 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
/// function call isn't allowed (a.k.a. `va_list`).
///
/// This function handles transparent types automatically.
- pub fn pass_indirectly_in_non_rustic_abis(mut self, cx: &C) -> bool
+ pub fn pass_indirectly_in_non_rustic_abis(self, cx: &C) -> bool
+ where
+ Ty: TyAbiInterface<'a, C> + Copy,
+ {
+ let base = self.peel_transparent_wrappers(cx);
+ Ty::is_pass_indirectly_in_non_rustic_abis_flag_set(base)
+ }
+
+ /// Recursively peel away transparent wrappers, returning the inner value.
+ ///
+ /// The return value is not `repr(transparent)` and/or does
+ /// not have a non-1zst field.
+ pub fn peel_transparent_wrappers(mut self, cx: &C) -> Self
where
Ty: TyAbiInterface<'a, C> + Copy,
{
@@ -300,7 +312,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
self = field;
}
- Ty::is_pass_indirectly_in_non_rustic_abis_flag_set(self)
+ self
}
/// Finds the one field that is not a 1-ZST.
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 061ad8617893..88f8b7cc5170 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -1,6 +1,6 @@
// tidy-alphabetical-start
+#![cfg_attr(all(feature = "nightly", bootstrap, test), feature(assert_matches))]
#![cfg_attr(feature = "nightly", allow(internal_features))]
-#![cfg_attr(feature = "nightly", feature(assert_matches))]
#![cfg_attr(feature = "nightly", feature(rustc_attrs))]
#![cfg_attr(feature = "nightly", feature(step_trait))]
// tidy-alphabetical-end
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs
index 5e81ec28ee35..97dd21db07e7 100644
--- a/compiler/rustc_arena/src/lib.rs
+++ b/compiler/rustc_arena/src/lib.rs
@@ -13,7 +13,6 @@
#![cfg_attr(test, feature(test))]
#![deny(unsafe_op_in_unsafe_fn)]
#![doc(test(no_crate_inject, attr(deny(warnings), allow(internal_features))))]
-#![feature(core_intrinsics)]
#![feature(decl_macro)]
#![feature(dropck_eyepatch)]
#![feature(never_type)]
@@ -26,7 +25,7 @@ use std::cell::{Cell, RefCell};
use std::marker::PhantomData;
use std::mem::{self, MaybeUninit};
use std::ptr::{self, NonNull};
-use std::{cmp, intrinsics, slice};
+use std::{cmp, hint, slice};
use smallvec::SmallVec;
@@ -172,8 +171,22 @@ impl TypedArena {
available_bytes >= additional_bytes
}
+ /// Allocates storage for `len >= 1` values in this arena, and returns a
+ /// raw pointer to the first value's storage.
+ ///
+ /// # Safety
+ ///
+ /// Caller must initialize each of the `len` slots to a droppable value
+ /// before the arena is dropped.
+ ///
+ /// In practice, this typically means that the caller must be able to
+ /// raw-copy `len` already-initialized values into the slice without any
+ /// possibility of panicking.
+ ///
+ /// FIXME(Zalathar): This is *very* fragile; perhaps we need a different
+ /// approach to arena-allocating slices of droppable values.
#[inline]
- fn alloc_raw_slice(&self, len: usize) -> *mut T {
+ unsafe fn alloc_raw_slice(&self, len: usize) -> *mut T {
assert!(size_of::() != 0);
assert!(len != 0);
@@ -208,7 +221,7 @@ impl TypedArena {
&self,
iter: impl IntoIterator- >,
) -> Result<&mut [T], E> {
- // Despite the similarlty with `DroplessArena`, we cannot reuse their fast case. The reason
+ // Despite the similarity with `DroplessArena`, we cannot reuse their fast case. The reason
// is subtle: these arenas are reentrant. In other words, `iter` may very well be holding a
// reference to `self` and adding elements to the arena during iteration.
//
@@ -229,9 +242,15 @@ impl
TypedArena {
}
// Move the content to the arena by copying and then forgetting it.
let len = vec.len();
- let start_ptr = self.alloc_raw_slice(len);
+
+ // SAFETY: After allocating raw storage for exactly `len` values, we
+ // must fully initialize the storage without panicking, and we must
+ // also prevent the stale values in the vec from being dropped.
Ok(unsafe {
+ let start_ptr = self.alloc_raw_slice(len);
+ // Initialize the newly-allocated storage without panicking.
vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
+ // Prevent the stale values in the vec from being dropped.
vec.set_len(0);
slice::from_raw_parts_mut(start_ptr, len)
})
@@ -432,7 +451,7 @@ impl DroplessArena {
let bytes = align_up(layout.size(), DROPLESS_ALIGNMENT);
// Tell LLVM that `end` is aligned to DROPLESS_ALIGNMENT.
- unsafe { intrinsics::assume(end == align_down(end, DROPLESS_ALIGNMENT)) };
+ unsafe { hint::assert_unchecked(end == align_down(end, DROPLESS_ALIGNMENT)) };
if let Some(sub) = end.checked_sub(bytes) {
let new_end = align_down(sub, layout.align());
@@ -490,19 +509,6 @@ impl DroplessArena {
}
}
- /// Used by `Lift` to check whether this slice is allocated
- /// in this arena.
- #[inline]
- pub fn contains_slice(&self, slice: &[T]) -> bool {
- for chunk in self.chunks.borrow_mut().iter_mut() {
- let ptr = slice.as_ptr().cast::().cast_mut();
- if chunk.start() <= ptr && chunk.end() >= ptr {
- return true;
- }
- }
- false
- }
-
/// Allocates a string slice that is copied into the `DroplessArena`, returning a
/// reference to it. Will panic if passed an empty string.
///
@@ -584,7 +590,7 @@ impl DroplessArena {
&self,
iter: impl IntoIterator- >,
) -> Result<&mut [T], E> {
- // Despite the similarlty with `alloc_from_iter`, we cannot reuse their fast case, as we
+ // Despite the similarity with `alloc_from_iter`, we cannot reuse their fast case, as we
// cannot know the minimum length of the iterator in this case.
assert!(size_of::
() != 0);
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 591abdaa2683..fa323b7cf581 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -656,11 +656,7 @@ impl Pat {
// A tuple pattern `(P0, .., Pn)` can be reparsed as `(T0, .., Tn)`
// assuming `T0` to `Tn` are all syntactically valid as types.
PatKind::Tuple(pats) => {
- let mut tys = ThinVec::with_capacity(pats.len());
- // FIXME(#48994) - could just be collected into an Option
- for pat in pats {
- tys.push(pat.to_ty()?);
- }
+ let tys = pats.iter().map(|pat| pat.to_ty()).collect::>>()?;
TyKind::Tup(tys)
}
_ => return None,
@@ -3873,27 +3869,44 @@ pub struct ConstItem {
pub ident: Ident,
pub generics: Generics,
pub ty: Box,
- pub rhs: Option,
+ pub rhs_kind: ConstItemRhsKind,
pub define_opaque: Option>,
}
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
-pub enum ConstItemRhs {
- TypeConst(AnonConst),
- Body(Box),
+pub enum ConstItemRhsKind {
+ Body { rhs: Option> },
+ TypeConst { rhs: Option },
}
-impl ConstItemRhs {
- pub fn span(&self) -> Span {
- self.expr().span
+impl ConstItemRhsKind {
+ pub fn new_body(rhs: Box) -> Self {
+ Self::Body { rhs: Some(rhs) }
}
- pub fn expr(&self) -> &Expr {
+ pub fn span(&self) -> Option {
+ Some(self.expr()?.span)
+ }
+
+ pub fn expr(&self) -> Option<&Expr> {
match self {
- ConstItemRhs::TypeConst(anon_const) => &anon_const.value,
- ConstItemRhs::Body(expr) => expr,
+ Self::Body { rhs: Some(body) } => Some(&body),
+ Self::TypeConst { rhs: Some(anon) } => Some(&anon.value),
+ _ => None,
}
}
+
+ pub fn has_expr(&self) -> bool {
+ match self {
+ Self::Body { rhs: Some(_) } => true,
+ Self::TypeConst { rhs: Some(_) } => true,
+ _ => false,
+ }
+ }
+
+ pub fn is_type_const(&self) -> bool {
+ matches!(self, &Self::TypeConst { .. })
+ }
}
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index e346a56bcf40..8d8e8ffc562f 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -354,7 +354,13 @@ fn make_attr_token_stream(
FrameData { open_delim_sp: Some((delim, span, spacing)), inner: vec![] },
));
} else if let Some(delim) = kind.close_delim() {
- let frame_data = mem::replace(&mut stack_top, stack_rest.pop().unwrap());
+ // If there's no matching opening delimiter, the token stream is malformed,
+ // likely due to a improper delimiter positions in the source code.
+ // It's not delimiter mismatch, and lexer can not detect it, so we just ignore it here.
+ let Some(frame) = stack_rest.pop() else {
+ return AttrTokenStream::new(stack_top.inner);
+ };
+ let frame_data = mem::replace(&mut stack_top, frame);
let (open_delim, open_sp, open_spacing) = frame_data.open_delim_sp.unwrap();
assert!(
open_delim.eq_ignoring_invisible_origin(&delim),
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 51614460d3c4..8556e8288670 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -427,7 +427,7 @@ macro_rules! common_visitor_and_walkers {
Const,
ConstBlockItem,
ConstItem,
- ConstItemRhs,
+ ConstItemRhsKind,
Defaultness,
Delegation,
DelegationMac,
diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml
index 6ac258155fe9..c00bac5d3c5a 100644
--- a/compiler/rustc_ast_lowering/Cargo.toml
+++ b/compiler/rustc_ast_lowering/Cargo.toml
@@ -15,7 +15,6 @@ rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
-rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }
diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl
deleted file mode 100644
index 0cd5c4f303de..000000000000
--- a/compiler/rustc_ast_lowering/messages.ftl
+++ /dev/null
@@ -1,191 +0,0 @@
-ast_lowering_abi_specified_multiple_times =
- `{$prev_name}` ABI specified multiple times
- .label = previously specified here
- .note = these ABIs are equivalent on the current target
-
-ast_lowering_arbitrary_expression_in_pattern =
- arbitrary expressions aren't allowed in patterns
- .pattern_from_macro_note = the `expr` fragment specifier forces the metavariable's content to be an expression
- .const_block_in_pattern_help = use a named `const`-item or an `if`-guard (`x if x == const {"{ ... }"}`) instead
-
-ast_lowering_argument = argument
-
-ast_lowering_assoc_ty_binding_in_dyn =
- associated type bounds are not allowed in `dyn` types
- .suggestion = use `impl Trait` to introduce a type instead
-
-ast_lowering_assoc_ty_parentheses =
- parenthesized generic arguments cannot be used in associated type constraints
-
-ast_lowering_async_bound_not_on_trait =
- `async` bound modifier only allowed on trait, not `{$descr}`
-
-ast_lowering_async_bound_only_for_fn_traits =
- `async` bound modifier only allowed on `Fn`/`FnMut`/`FnOnce` traits
-
-ast_lowering_async_coroutines_not_supported =
- `async` coroutines are not yet supported
-
-ast_lowering_att_syntax_only_x86 =
- the `att_syntax` option is only supported on x86
-
-ast_lowering_await_only_in_async_fn_and_blocks =
- `await` is only allowed inside `async` functions and blocks
- .label = only allowed inside `async` functions and blocks
-
-ast_lowering_bad_return_type_notation_inputs =
- argument types not allowed with return type notation
- .suggestion = remove the input types
-
-ast_lowering_bad_return_type_notation_needs_dots = return type notation arguments must be elided with `..`
- .suggestion = use the correct syntax by adding `..` to the arguments
-
-ast_lowering_bad_return_type_notation_output =
- return type not allowed with return type notation
-ast_lowering_bad_return_type_notation_output_suggestion = use the right argument notation and remove the return type
-
-ast_lowering_bad_return_type_notation_position = return type notation not allowed in this position yet
-
-ast_lowering_clobber_abi_not_supported =
- `clobber_abi` is not supported on this target
-
-ast_lowering_closure_cannot_be_static = closures cannot be static
-
-ast_lowering_coroutine_too_many_parameters =
- too many parameters for a coroutine (expected 0 or 1 parameters)
-
-ast_lowering_default_field_in_tuple = default fields are not supported in tuple structs
- .label = default fields are only supported on structs
-
-ast_lowering_delegation_cycle_in_signature_resolution = encountered a cycle during delegation signature resolution
-ast_lowering_delegation_unresolved_callee = failed to resolve delegation callee
-ast_lowering_does_not_support_modifiers =
- the `{$class_name}` register class does not support template modifiers
-
-ast_lowering_extra_double_dot =
- `..` can only be used once per {$ctx} pattern
- .label = can only be used once per {$ctx} pattern
-
-ast_lowering_functional_record_update_destructuring_assignment =
- functional record updates are not allowed in destructuring assignments
- .suggestion = consider removing the trailing pattern
-
-ast_lowering_generic_param_default_in_binder =
- defaults for generic parameters are not allowed in `for<...>` binders
-
-ast_lowering_generic_type_with_parentheses =
- parenthesized type parameters may only be used with a `Fn` trait
- .label = only `Fn` traits may use parentheses
-
-ast_lowering_inclusive_range_with_no_end = inclusive range with no end
-
-ast_lowering_inline_asm_unsupported_target =
- inline assembly is unsupported on this target
-
-ast_lowering_invalid_abi =
- invalid ABI: found `{$abi}`
- .label = invalid ABI
- .note = invoke `{$command}` for a full list of supported calling conventions
-
-ast_lowering_invalid_abi_clobber_abi =
- invalid ABI for `clobber_abi`
- .note = the following ABIs are supported on this target: {$supported_abis}
-
-ast_lowering_invalid_abi_suggestion = there's a similarly named valid ABI `{$suggestion}`
-
-ast_lowering_invalid_asm_template_modifier_const =
- asm template modifiers are not allowed for `const` arguments
-
-ast_lowering_invalid_asm_template_modifier_label =
- asm template modifiers are not allowed for `label` arguments
-
-ast_lowering_invalid_asm_template_modifier_reg_class =
- invalid asm template modifier for this register class
-
-ast_lowering_invalid_asm_template_modifier_sym =
- asm template modifiers are not allowed for `sym` arguments
-
-ast_lowering_invalid_legacy_const_generic_arg =
- invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
-
-ast_lowering_invalid_legacy_const_generic_arg_suggestion =
- try using a const generic argument instead
-
-ast_lowering_invalid_register =
- invalid register `{$reg}`: {$error}
-
-ast_lowering_invalid_register_class =
- invalid register class `{$reg_class}`: unknown register class
- .note = the following register classes are supported on this target: {$supported_register_classes}
-
-ast_lowering_match_arm_with_no_body =
- `match` arm with no body
- .suggestion = add a body after the pattern
-
-ast_lowering_misplaced_double_dot =
- `..` patterns are not allowed here
- .note = only allowed in tuple, tuple struct, and slice patterns
-
-ast_lowering_misplaced_impl_trait =
- `impl Trait` is not allowed in {$position}
- .note = `impl Trait` is only allowed in arguments and return types of functions and methods
-
-ast_lowering_never_pattern_with_body =
- a never pattern is always unreachable
- .label = this will never be executed
- .suggestion = remove this expression
-
-ast_lowering_never_pattern_with_guard =
- a guard on a never pattern will never be run
- .suggestion = remove this guard
-
-ast_lowering_no_precise_captures_on_apit = `use<...>` precise capturing syntax not allowed in argument-position `impl Trait`
-
-ast_lowering_previously_used_here = previously used here
-
-ast_lowering_register1 = register `{$reg1_name}`
-
-ast_lowering_register2 = register `{$reg2_name}`
-
-ast_lowering_register_class_only_clobber =
- register class `{$reg_class_name}` can only be used as a clobber, not as an input or output
-ast_lowering_register_class_only_clobber_stable =
- register class `{$reg_class_name}` can only be used as a clobber in stable
-
-ast_lowering_register_conflict =
- register `{$reg1_name}` conflicts with register `{$reg2_name}`
- .help = use `lateout` instead of `out` to avoid conflict
-
-ast_lowering_remove_parentheses = remove these parentheses
-
-ast_lowering_sub_tuple_binding =
- `{$ident_name} @` is not allowed in a {$ctx}
- .label = this is only allowed in slice patterns
- .help = remove this and bind each tuple field independently
-
-ast_lowering_sub_tuple_binding_suggestion = if you don't need to use the contents of {$ident}, discard the tuple's remaining fields
-
-ast_lowering_support_modifiers =
- the `{$class_name}` register class supports the following template modifiers: {$modifiers}
-
-ast_lowering_template_modifier = template modifier
-
-ast_lowering_this_not_async = this is not `async`
-
-ast_lowering_underscore_expr_lhs_assign =
- in expressions, `_` can only be used on the left-hand side of an assignment
- .label = `_` not allowed here
-
-ast_lowering_union_default_field_values = unions cannot have default field values
-
-ast_lowering_unstable_inline_assembly = inline assembly is not stable yet on this architecture
-ast_lowering_unstable_inline_assembly_label_operand_with_outputs =
- using both label and output operands for inline assembly is unstable
-ast_lowering_unstable_may_unwind = the `may_unwind` option is unstable
-
-ast_lowering_use_angle_brackets = use angle brackets instead
-
-ast_lowering_yield = yield syntax is experimental
-ast_lowering_yield_in_closure =
- `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
- .suggestion = use `#[coroutine]` to make this closure a coroutine
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 36fcd4b924c8..a7bf1c99a7e2 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -3,6 +3,7 @@ use std::fmt::Write;
use rustc_ast::*;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
+use rustc_errors::msg;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_session::parse::feature_err;
@@ -19,8 +20,7 @@ use super::errors::{
RegisterConflict,
};
use crate::{
- AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, ParamMode,
- ResolverAstLoweringExt, fluent_generated as fluent,
+ AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, ParamMode, ResolverAstLoweringExt,
};
impl<'a, 'hir> LoweringContext<'a, 'hir> {
@@ -67,7 +67,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&self.tcx.sess,
sym::asm_experimental_arch,
sp,
- fluent::ast_lowering_unstable_inline_assembly,
+ msg!("inline assembly is not stable yet on this architecture"),
)
.emit();
}
@@ -84,7 +84,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&self.tcx.sess,
sym::asm_unwind,
sp,
- fluent::ast_lowering_unstable_may_unwind,
+ msg!("the `may_unwind` option is unstable"),
)
.emit();
}
@@ -499,7 +499,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
sess,
sym::asm_goto_with_outputs,
*op_sp,
- fluent::ast_lowering_unstable_inline_assembly_label_operand_with_outputs,
+ msg!("using both label and output operands for inline assembly is unstable"),
)
.emit();
}
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index 88e69e67d8a5..1eb72727df66 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -4,17 +4,17 @@ use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{Ident, Span, Symbol};
#[derive(Diagnostic)]
-#[diag(ast_lowering_generic_type_with_parentheses, code = E0214)]
+#[diag("parenthesized type parameters may only be used with a `Fn` trait", code = E0214)]
pub(crate) struct GenericTypeWithParentheses {
#[primary_span]
- #[label]
+ #[label("only `Fn` traits may use parentheses")]
pub span: Span,
#[subdiagnostic]
pub sub: Option,
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(ast_lowering_use_angle_brackets, applicability = "maybe-incorrect")]
+#[multipart_suggestion("use angle brackets instead", applicability = "maybe-incorrect")]
pub(crate) struct UseAngleBrackets {
#[suggestion_part(code = "<")]
pub open_param: Span,
@@ -23,11 +23,11 @@ pub(crate) struct UseAngleBrackets {
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_invalid_abi, code = E0703)]
-#[note]
+#[diag("invalid ABI: found `{$abi}`", code = E0703)]
+#[note("invoke `{$command}` for a full list of supported calling conventions")]
pub(crate) struct InvalidAbi {
#[primary_span]
- #[label]
+ #[label("invalid ABI")]
pub span: Span,
pub abi: Symbol,
pub command: String,
@@ -36,16 +36,16 @@ pub(crate) struct InvalidAbi {
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_default_field_in_tuple)]
+#[diag("default fields are not supported in tuple structs")]
pub(crate) struct TupleStructWithDefault {
#[primary_span]
- #[label]
+ #[label("default fields are only supported on structs")]
pub span: Span,
}
#[derive(Subdiagnostic)]
#[suggestion(
- ast_lowering_invalid_abi_suggestion,
+ "there's a similarly named valid ABI `{$suggestion}`",
code = "\"{suggestion}\"",
applicability = "maybe-incorrect",
style = "verbose"
@@ -57,7 +57,7 @@ pub(crate) struct InvalidAbiSuggestion {
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_assoc_ty_parentheses)]
+#[diag("parenthesized generic arguments cannot be used in associated type constraints")]
pub(crate) struct AssocTyParentheses {
#[primary_span]
pub span: Span,
@@ -67,12 +67,12 @@ pub(crate) struct AssocTyParentheses {
#[derive(Subdiagnostic)]
pub(crate) enum AssocTyParenthesesSub {
- #[multipart_suggestion(ast_lowering_remove_parentheses)]
+ #[multipart_suggestion("remove these parentheses")]
Empty {
#[suggestion_part(code = "")]
parentheses_span: Span,
},
- #[multipart_suggestion(ast_lowering_use_angle_brackets)]
+ #[multipart_suggestion("use angle brackets instead")]
NotEmpty {
#[suggestion_part(code = "<")]
open_param: Span,
@@ -82,8 +82,8 @@ pub(crate) enum AssocTyParenthesesSub {
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_misplaced_impl_trait, code = E0562)]
-#[note]
+#[diag("`impl Trait` is not allowed in {$position}", code = E0562)]
+#[note("`impl Trait` is only allowed in arguments and return types of functions and methods")]
pub(crate) struct MisplacedImplTrait<'a> {
#[primary_span]
pub span: Span,
@@ -91,97 +91,106 @@ pub(crate) struct MisplacedImplTrait<'a> {
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_assoc_ty_binding_in_dyn)]
+#[diag("associated type bounds are not allowed in `dyn` types")]
pub(crate) struct MisplacedAssocTyBinding {
#[primary_span]
pub span: Span,
- #[suggestion(code = " = impl", applicability = "maybe-incorrect", style = "verbose")]
+ #[suggestion(
+ "use `impl Trait` to introduce a type instead",
+ code = " = impl",
+ applicability = "maybe-incorrect",
+ style = "verbose"
+ )]
pub suggestion: Option,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_underscore_expr_lhs_assign)]
+#[diag("in expressions, `_` can only be used on the left-hand side of an assignment")]
pub(crate) struct UnderscoreExprLhsAssign {
#[primary_span]
- #[label]
+ #[label("`_` not allowed here")]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_await_only_in_async_fn_and_blocks, code = E0728)]
+#[diag("`await` is only allowed inside `async` functions and blocks", code = E0728)]
pub(crate) struct AwaitOnlyInAsyncFnAndBlocks {
#[primary_span]
- #[label]
+ #[label("only allowed inside `async` functions and blocks")]
pub await_kw_span: Span,
- #[label(ast_lowering_this_not_async)]
+ #[label("this is not `async`")]
pub item_span: Option,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_coroutine_too_many_parameters, code = E0628)]
+#[diag("too many parameters for a coroutine (expected 0 or 1 parameters)", code = E0628)]
pub(crate) struct CoroutineTooManyParameters {
#[primary_span]
pub fn_decl_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_closure_cannot_be_static, code = E0697)]
+#[diag("closures cannot be static", code = E0697)]
pub(crate) struct ClosureCannotBeStatic {
#[primary_span]
pub fn_decl_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_functional_record_update_destructuring_assignment)]
+#[diag("functional record updates are not allowed in destructuring assignments")]
pub(crate) struct FunctionalRecordUpdateDestructuringAssignment {
#[primary_span]
- #[suggestion(code = "", applicability = "machine-applicable")]
+ #[suggestion(
+ "consider removing the trailing pattern",
+ code = "",
+ applicability = "machine-applicable"
+ )]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_async_coroutines_not_supported, code = E0727)]
+#[diag("`async` coroutines are not yet supported", code = E0727)]
pub(crate) struct AsyncCoroutinesNotSupported {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_inline_asm_unsupported_target, code = E0472)]
+#[diag("inline assembly is unsupported on this target", code = E0472)]
pub(crate) struct InlineAsmUnsupportedTarget {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_att_syntax_only_x86)]
+#[diag("the `att_syntax` option is only supported on x86")]
pub(crate) struct AttSyntaxOnlyX86 {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_abi_specified_multiple_times)]
+#[diag("`{$prev_name}` ABI specified multiple times")]
pub(crate) struct AbiSpecifiedMultipleTimes {
#[primary_span]
pub abi_span: Span,
pub prev_name: Symbol,
- #[label]
+ #[label("previously specified here")]
pub prev_span: Span,
- #[note]
+ #[note("these ABIs are equivalent on the current target")]
pub equivalent: bool,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_clobber_abi_not_supported)]
+#[diag("`clobber_abi` is not supported on this target")]
pub(crate) struct ClobberAbiNotSupported {
#[primary_span]
pub abi_span: Span,
}
#[derive(Diagnostic)]
-#[note]
-#[diag(ast_lowering_invalid_abi_clobber_abi)]
+#[note("the following ABIs are supported on this target: {$supported_abis}")]
+#[diag("invalid ABI for `clobber_abi`")]
pub(crate) struct InvalidAbiClobberAbi {
#[primary_span]
pub abi_span: Span,
@@ -189,7 +198,7 @@ pub(crate) struct InvalidAbiClobberAbi {
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_invalid_register)]
+#[diag("invalid register `{$reg}`: {$error}")]
pub(crate) struct InvalidRegister<'a> {
#[primary_span]
pub op_span: Span,
@@ -198,8 +207,10 @@ pub(crate) struct InvalidRegister<'a> {
}
#[derive(Diagnostic)]
-#[note]
-#[diag(ast_lowering_invalid_register_class)]
+#[note(
+ "the following register classes are supported on this target: {$supported_register_classes}"
+)]
+#[diag("invalid register class `{$reg_class}`: unknown register class")]
pub(crate) struct InvalidRegisterClass {
#[primary_span]
pub op_span: Span,
@@ -208,12 +219,12 @@ pub(crate) struct InvalidRegisterClass {
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_invalid_asm_template_modifier_reg_class)]
+#[diag("invalid asm template modifier for this register class")]
pub(crate) struct InvalidAsmTemplateModifierRegClass {
#[primary_span]
- #[label(ast_lowering_template_modifier)]
+ #[label("template modifier")]
pub placeholder_span: Span,
- #[label(ast_lowering_argument)]
+ #[label("argument")]
pub op_span: Span,
#[subdiagnostic]
pub sub: InvalidAsmTemplateModifierRegClassSub,
@@ -221,44 +232,48 @@ pub(crate) struct InvalidAsmTemplateModifierRegClass {
#[derive(Subdiagnostic)]
pub(crate) enum InvalidAsmTemplateModifierRegClassSub {
- #[note(ast_lowering_support_modifiers)]
+ #[note(
+ "the `{$class_name}` register class supports the following template modifiers: {$modifiers}"
+ )]
SupportModifier { class_name: Symbol, modifiers: String },
- #[note(ast_lowering_does_not_support_modifiers)]
+ #[note("the `{$class_name}` register class does not support template modifiers")]
DoesNotSupportModifier { class_name: Symbol },
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_invalid_asm_template_modifier_const)]
+#[diag("asm template modifiers are not allowed for `const` arguments")]
pub(crate) struct InvalidAsmTemplateModifierConst {
#[primary_span]
- #[label(ast_lowering_template_modifier)]
+ #[label("template modifier")]
pub placeholder_span: Span,
- #[label(ast_lowering_argument)]
+ #[label("argument")]
pub op_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_invalid_asm_template_modifier_sym)]
+#[diag("asm template modifiers are not allowed for `sym` arguments")]
pub(crate) struct InvalidAsmTemplateModifierSym {
#[primary_span]
- #[label(ast_lowering_template_modifier)]
+ #[label("template modifier")]
pub placeholder_span: Span,
- #[label(ast_lowering_argument)]
+ #[label("argument")]
pub op_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_invalid_asm_template_modifier_label)]
+#[diag("asm template modifiers are not allowed for `label` arguments")]
pub(crate) struct InvalidAsmTemplateModifierLabel {
#[primary_span]
- #[label(ast_lowering_template_modifier)]
+ #[label("template modifier")]
pub placeholder_span: Span,
- #[label(ast_lowering_argument)]
+ #[label("argument")]
pub op_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_register_class_only_clobber)]
+#[diag(
+ "register class `{$reg_class_name}` can only be used as a clobber, not as an input or output"
+)]
pub(crate) struct RegisterClassOnlyClobber {
#[primary_span]
pub op_span: Span,
@@ -266,7 +281,7 @@ pub(crate) struct RegisterClassOnlyClobber {
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_register_class_only_clobber_stable)]
+#[diag("register class `{$reg_class_name}` can only be used as a clobber in stable")]
pub(crate) struct RegisterClassOnlyClobberStable {
#[primary_span]
pub op_span: Span,
@@ -274,27 +289,27 @@ pub(crate) struct RegisterClassOnlyClobberStable {
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_register_conflict)]
+#[diag("register `{$reg1_name}` conflicts with register `{$reg2_name}`")]
pub(crate) struct RegisterConflict<'a> {
#[primary_span]
- #[label(ast_lowering_register1)]
+ #[label("register `{$reg1_name}`")]
pub op_span1: Span,
- #[label(ast_lowering_register2)]
+ #[label("register `{$reg2_name}`")]
pub op_span2: Span,
pub reg1_name: &'a str,
pub reg2_name: &'a str,
- #[help]
+ #[help("use `lateout` instead of `out` to avoid conflict")]
pub in_out: Option,
}
#[derive(Diagnostic)]
-#[help]
-#[diag(ast_lowering_sub_tuple_binding)]
+#[help("remove this and bind each tuple field independently")]
+#[diag("`{$ident_name} @` is not allowed in a {$ctx}")]
pub(crate) struct SubTupleBinding<'a> {
#[primary_span]
- #[label]
+ #[label("this is only allowed in slice patterns")]
#[suggestion(
- ast_lowering_sub_tuple_binding_suggestion,
+ "if you don't need to use the contents of {$ident}, discard the tuple's remaining fields",
style = "verbose",
code = "..",
applicability = "maybe-incorrect"
@@ -306,63 +321,67 @@ pub(crate) struct SubTupleBinding<'a> {
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_extra_double_dot)]
+#[diag("`..` can only be used once per {$ctx} pattern")]
pub(crate) struct ExtraDoubleDot<'a> {
#[primary_span]
- #[label]
+ #[label("can only be used once per {$ctx} pattern")]
pub span: Span,
- #[label(ast_lowering_previously_used_here)]
+ #[label("previously used here")]
pub prev_span: Span,
pub ctx: &'a str,
}
#[derive(Diagnostic)]
-#[note]
-#[diag(ast_lowering_misplaced_double_dot)]
+#[note("only allowed in tuple, tuple struct, and slice patterns")]
+#[diag("`..` patterns are not allowed here")]
pub(crate) struct MisplacedDoubleDot {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_match_arm_with_no_body)]
+#[diag("`match` arm with no body")]
pub(crate) struct MatchArmWithNoBody {
#[primary_span]
pub span: Span,
- #[suggestion(code = " => todo!(),", applicability = "has-placeholders")]
+ #[suggestion(
+ "add a body after the pattern",
+ code = " => todo!(),",
+ applicability = "has-placeholders"
+ )]
pub suggestion: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_never_pattern_with_body)]
+#[diag("a never pattern is always unreachable")]
pub(crate) struct NeverPatternWithBody {
#[primary_span]
- #[label]
- #[suggestion(code = "", applicability = "maybe-incorrect")]
+ #[label("this will never be executed")]
+ #[suggestion("remove this expression", code = "", applicability = "maybe-incorrect")]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_never_pattern_with_guard)]
+#[diag("a guard on a never pattern will never be run")]
pub(crate) struct NeverPatternWithGuard {
#[primary_span]
- #[suggestion(code = "", applicability = "maybe-incorrect")]
+ #[suggestion("remove this guard", code = "", applicability = "maybe-incorrect")]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_arbitrary_expression_in_pattern)]
+#[diag("arbitrary expressions aren't allowed in patterns")]
pub(crate) struct ArbitraryExpressionInPattern {
#[primary_span]
pub span: Span,
- #[note(ast_lowering_pattern_from_macro_note)]
+ #[note("the `expr` fragment specifier forces the metavariable's content to be an expression")]
pub pattern_from_macro_note: bool,
- #[help(ast_lowering_const_block_in_pattern_help)]
+ #[help("use a named `const`-item or an `if`-guard (`x if x == const {\"{ ... }\"}`) instead")]
pub const_block_in_pattern_help: bool,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_inclusive_range_with_no_end)]
+#[diag("inclusive range with no end")]
pub(crate) struct InclusiveRangeWithNoEnd {
#[primary_span]
pub span: Span,
@@ -370,7 +389,7 @@ pub(crate) struct InclusiveRangeWithNoEnd {
#[derive(Subdiagnostic)]
#[multipart_suggestion(
- ast_lowering_bad_return_type_notation_output_suggestion,
+ "use the right argument notation and remove the return type",
applicability = "machine-applicable",
style = "verbose"
)]
@@ -384,26 +403,36 @@ pub(crate) struct RTNSuggestion {
#[derive(Diagnostic)]
pub(crate) enum BadReturnTypeNotation {
- #[diag(ast_lowering_bad_return_type_notation_inputs)]
+ #[diag("argument types not allowed with return type notation")]
Inputs {
#[primary_span]
- #[suggestion(code = "(..)", applicability = "machine-applicable", style = "verbose")]
+ #[suggestion(
+ "remove the input types",
+ code = "(..)",
+ applicability = "machine-applicable",
+ style = "verbose"
+ )]
span: Span,
},
- #[diag(ast_lowering_bad_return_type_notation_output)]
+ #[diag("return type not allowed with return type notation")]
Output {
#[primary_span]
span: Span,
#[subdiagnostic]
suggestion: RTNSuggestion,
},
- #[diag(ast_lowering_bad_return_type_notation_needs_dots)]
+ #[diag("return type notation arguments must be elided with `..`")]
NeedsDots {
#[primary_span]
- #[suggestion(code = "(..)", applicability = "machine-applicable", style = "verbose")]
+ #[suggestion(
+ "use the correct syntax by adding `..` to the arguments",
+ code = "(..)",
+ applicability = "machine-applicable",
+ style = "verbose"
+ )]
span: Span,
},
- #[diag(ast_lowering_bad_return_type_notation_position)]
+ #[diag("return type notation not allowed in this position yet")]
Position {
#[primary_span]
span: Span,
@@ -411,14 +440,14 @@ pub(crate) enum BadReturnTypeNotation {
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_generic_param_default_in_binder)]
+#[diag("defaults for generic parameters are not allowed in `for<...>` binders")]
pub(crate) struct GenericParamDefaultInBinder {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_async_bound_not_on_trait)]
+#[diag("`async` bound modifier only allowed on trait, not `{$descr}`")]
pub(crate) struct AsyncBoundNotOnTrait {
#[primary_span]
pub span: Span,
@@ -426,30 +455,37 @@ pub(crate) struct AsyncBoundNotOnTrait {
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_async_bound_only_for_fn_traits)]
+#[diag("`async` bound modifier only allowed on `Fn`/`FnMut`/`FnOnce` traits")]
pub(crate) struct AsyncBoundOnlyForFnTraits {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_no_precise_captures_on_apit)]
+#[diag("`use<...>` precise capturing syntax not allowed in argument-position `impl Trait`")]
pub(crate) struct NoPreciseCapturesOnApit {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_yield_in_closure)]
+#[diag("`yield` can only be used in `#[coroutine]` closures, or `gen` blocks")]
pub(crate) struct YieldInClosure {
#[primary_span]
pub span: Span,
- #[suggestion(code = "#[coroutine] ", applicability = "maybe-incorrect", style = "verbose")]
+ #[suggestion(
+ "use `#[coroutine]` to make this closure a coroutine",
+ code = "#[coroutine] ",
+ applicability = "maybe-incorrect",
+ style = "verbose"
+ )]
pub suggestion: Option,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_invalid_legacy_const_generic_arg)]
+#[diag(
+ "invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items"
+)]
pub(crate) struct InvalidLegacyConstGenericArg {
#[primary_span]
pub span: Span,
@@ -459,7 +495,7 @@ pub(crate) struct InvalidLegacyConstGenericArg {
#[derive(Subdiagnostic)]
#[multipart_suggestion(
- ast_lowering_invalid_legacy_const_generic_arg_suggestion,
+ "try using a const generic argument instead",
applicability = "maybe-incorrect"
)]
pub(crate) struct UseConstGenericArg {
@@ -472,21 +508,21 @@ pub(crate) struct UseConstGenericArg {
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_union_default_field_values)]
+#[diag("unions cannot have default field values")]
pub(crate) struct UnionWithDefault {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_delegation_unresolved_callee)]
+#[diag("failed to resolve delegation callee")]
pub(crate) struct UnresolvedDelegationCallee {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_lowering_delegation_cycle_in_signature_resolution)]
+#[diag("encountered a cycle during delegation signature resolution")]
pub(crate) struct CycleInDelegationSignatureResolution {
#[primary_span]
pub span: Span,
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 9fbfeb7a11e6..b034e250b58d 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -5,6 +5,7 @@ use std::sync::Arc;
use rustc_ast::*;
use rustc_ast_pretty::pprust::expr_to_string;
use rustc_data_structures::stack::ensure_sufficient_stack;
+use rustc_errors::msg;
use rustc_hir as hir;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::{DefKind, Res};
@@ -28,9 +29,7 @@ use super::{
GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt,
};
use crate::errors::{InvalidLegacyConstGenericArg, UseConstGenericArg, YieldInClosure};
-use crate::{
- AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, TryBlockScope, fluent_generated,
-};
+use crate::{AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, TryBlockScope};
struct WillCreateDefIdsVisitor {}
@@ -967,14 +966,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
this.arena.alloc(this.expr(gen_future_span, expr_break))
});
- self.arm(ready_pat, break_x)
+ self.arm(ready_pat, break_x, span)
};
// `::std::task::Poll::Pending => {}`
let pending_arm = {
let pending_pat = self.pat_lang_item_variant(span, hir::LangItem::PollPending, &[]);
let empty_block = self.expr_block_empty(span);
- self.arm(pending_pat, empty_block)
+ self.arm(pending_pat, empty_block, span)
};
let inner_match_stmt = {
@@ -1028,7 +1027,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
});
// mut __awaitee => loop { ... }
- let awaitee_arm = self.arm(awaitee_pat, loop_expr);
+ let awaitee_arm = self.arm(awaitee_pat, loop_expr, span);
// `match ::std::future::IntoFuture::into_future() { ... }`
let into_future_expr = match await_kind {
@@ -1703,7 +1702,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
&self.tcx.sess,
sym::yield_expr,
span,
- fluent_generated::ast_lowering_yield,
+ msg!("yield syntax is experimental"),
)
.emit();
}
@@ -1818,7 +1817,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let break_expr =
self.with_loop_scope(loop_hir_id, |this| this.expr_break_alloc(for_span));
let pat = self.pat_none(for_span);
- self.arm(pat, break_expr)
+ self.arm(pat, break_expr, for_span)
};
// Some() => ,
@@ -1827,7 +1826,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let body_block =
self.with_loop_scope(loop_hir_id, |this| this.lower_block(body, false));
let body_expr = self.arena.alloc(self.expr_block(body_block));
- self.arm(some_pat, body_expr)
+ self.arm(some_pat, body_expr, for_span)
};
// `mut iter`
@@ -1886,7 +1885,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let loop_expr = self.arena.alloc(hir::Expr { hir_id: loop_hir_id, kind, span: for_span });
// `mut iter => { ... }`
- let iter_arm = self.arm(iter_pat, loop_expr);
+ let iter_arm = self.arm(iter_pat, loop_expr, for_span);
let match_expr = match loop_kind {
ForLoopKind::For => {
@@ -1931,7 +1930,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::LangItem::IntoAsyncIterIntoIter,
arena_vec![self; head],
);
- let iter_arm = self.arm(async_iter_pat, inner_match_expr);
+ let iter_arm = self.arm(async_iter_pat, inner_match_expr, for_span);
self.arena.alloc(self.expr_match(
for_span,
iter,
@@ -1998,7 +1997,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let val_expr = self.expr_ident(span, val_ident, val_pat_nid);
self.lower_attrs(val_expr.hir_id, &attrs, span, Target::Expression);
let continue_pat = self.pat_cf_continue(unstable_span, val_pat);
- self.arm(continue_pat, val_expr)
+ self.arm(continue_pat, val_expr, try_span)
};
// `ControlFlow::Break(residual) =>
@@ -2041,7 +2040,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_attrs(ret_expr.hir_id, &attrs, span, Target::Expression);
let break_pat = self.pat_cf_break(try_span, residual_local);
- self.arm(break_pat, ret_expr)
+ self.arm(break_pat, ret_expr, try_span)
};
hir::ExprKind::Match(
@@ -2369,12 +2368,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
&mut self,
pat: &'hir hir::Pat<'hir>,
expr: &'hir hir::Expr<'hir>,
+ span: Span,
) -> hir::Arm<'hir> {
hir::Arm {
hir_id: self.next_id(),
pat,
guard: None,
- span: self.lower_span(expr.span),
+ span: self.lower_span(span),
body: expr,
}
}
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index b497c6beeb98..9922ed8a5c58 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -288,7 +288,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ident,
generics,
ty,
- rhs,
+ rhs_kind,
define_opaque,
}) => {
let ident = self.lower_ident(*ident);
@@ -301,7 +301,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ty,
ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy),
);
- let rhs = this.lower_const_item_rhs(attrs, rhs.as_ref(), span);
+ let rhs = this.lower_const_item_rhs(rhs_kind, span);
(ty, rhs)
},
);
@@ -827,7 +827,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir_id,
def_id: self.local_def_id(v.id),
data: self.lower_variant_data(hir_id, item_kind, &v.data),
- disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const_to_anon_const(e)),
+ disr_expr: v
+ .disr_expr
+ .as_ref()
+ .map(|e| self.lower_anon_const_to_anon_const(e, e.value.span)),
ident: self.lower_ident(v.ident),
span: self.lower_span(v.span),
}
@@ -917,7 +920,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
None => Ident::new(sym::integer(index), self.lower_span(f.span)),
},
vis_span: self.lower_span(f.vis.span),
- default: f.default.as_ref().map(|v| self.lower_anon_const_to_anon_const(v)),
+ default: f
+ .default
+ .as_ref()
+ .map(|v| self.lower_anon_const_to_anon_const(v, v.value.span)),
ty,
safety: self.lower_safety(f.safety, hir::Safety::Safe),
}
@@ -935,7 +941,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (ident, generics, kind, has_default) = match &i.kind {
AssocItemKind::Const(box ConstItem {
- ident, generics, ty, rhs, define_opaque, ..
+ ident,
+ generics,
+ ty,
+ rhs_kind,
+ define_opaque,
+ ..
}) => {
let (generics, kind) = self.lower_generics(
generics,
@@ -946,15 +957,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
ty,
ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy),
);
- let rhs = rhs
- .as_ref()
- .map(|rhs| this.lower_const_item_rhs(attrs, Some(rhs), i.span));
- hir::TraitItemKind::Const(ty, rhs)
+ // Trait associated consts don't need an expression/body.
+ let rhs = if rhs_kind.has_expr() {
+ Some(this.lower_const_item_rhs(rhs_kind, i.span))
+ } else {
+ None
+ };
+ hir::TraitItemKind::Const(ty, rhs, rhs_kind.is_type_const().into())
},
);
if define_opaque.is_some() {
- if rhs.is_some() {
+ if rhs_kind.has_expr() {
self.lower_define_opaque(hir_id, &define_opaque);
} else {
self.dcx().span_err(
@@ -964,7 +978,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}
- (*ident, generics, kind, rhs.is_some())
+ (*ident, generics, kind, rhs_kind.has_expr())
}
AssocItemKind::Fn(box Fn {
sig, ident, generics, body: None, define_opaque, ..
@@ -1148,7 +1162,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (ident, (generics, kind)) = match &i.kind {
AssocItemKind::Const(box ConstItem {
- ident, generics, ty, rhs, define_opaque, ..
+ ident,
+ generics,
+ ty,
+ rhs_kind,
+ define_opaque,
+ ..
}) => (
*ident,
self.lower_generics(
@@ -1161,7 +1180,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy),
);
this.lower_define_opaque(hir_id, &define_opaque);
- let rhs = this.lower_const_item_rhs(attrs, rhs.as_ref(), i.span);
+ let rhs = this.lower_const_item_rhs(rhs_kind, i.span);
hir::ImplItemKind::Const(ty, rhs)
},
),
@@ -1391,7 +1410,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// create a fake body so that the entire rest of the compiler doesn't have to deal with
// this as a special case.
return self.lower_fn_body(decl, contract, |this| {
- if attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic))
+ if find_attr!(attrs, AttributeKind::RustcIntrinsic)
|| this.tcx.is_sdylib_interface_build()
{
let span = this.lower_span(span);
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 8c6ee9d6bc63..6265a06410d5 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -88,8 +88,6 @@ mod pat;
mod path;
pub mod stability;
-rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
-
struct LoweringContext<'a, 'hir> {
tcx: TyCtxt<'hir>,
resolver: &'a mut ResolverAstLowering,
@@ -880,7 +878,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
(hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind))
}
- LifetimeRes::Static { .. } | LifetimeRes::Error => return None,
+ LifetimeRes::Static { .. } | LifetimeRes::Error(..) => return None,
res => panic!(
"Unexpected lifetime resolution {:?} for {:?} at {:?}",
res, ident, ident.span
@@ -1933,26 +1931,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
source: LifetimeSource,
syntax: LifetimeSyntax,
) -> &'hir hir::Lifetime {
- let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
- let res = match res {
- LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param),
- LifetimeRes::Fresh { param, .. } => {
- assert_eq!(ident.name, kw::UnderscoreLifetime);
- let param = self.local_def_id(param);
- hir::LifetimeKind::Param(param)
- }
- LifetimeRes::Infer => {
- assert_eq!(ident.name, kw::UnderscoreLifetime);
- hir::LifetimeKind::Infer
- }
- LifetimeRes::Static { .. } => {
- assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime));
- hir::LifetimeKind::Static
- }
- LifetimeRes::Error => hir::LifetimeKind::Error,
- LifetimeRes::ElidedAnchor { .. } => {
- panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span);
+ let res = if let Some(res) = self.resolver.get_lifetime_res(id) {
+ match res {
+ LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param),
+ LifetimeRes::Fresh { param, .. } => {
+ assert_eq!(ident.name, kw::UnderscoreLifetime);
+ let param = self.local_def_id(param);
+ hir::LifetimeKind::Param(param)
+ }
+ LifetimeRes::Infer => {
+ assert_eq!(ident.name, kw::UnderscoreLifetime);
+ hir::LifetimeKind::Infer
+ }
+ LifetimeRes::Static { .. } => {
+ assert!(matches!(ident.name, kw::StaticLifetime | kw::UnderscoreLifetime));
+ hir::LifetimeKind::Static
+ }
+ LifetimeRes::Error(guar) => hir::LifetimeKind::Error(guar),
+ LifetimeRes::ElidedAnchor { .. } => {
+ panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span);
+ }
}
+ } else {
+ hir::LifetimeKind::Error(self.dcx().span_delayed_bug(ident.span, "unresolved lifetime"))
};
debug!(?res);
@@ -2016,12 +2017,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// AST resolution emitted an error on those parameters, so we lower them using
// `ParamName::Error`.
let ident = self.lower_ident(param.ident);
- let param_name =
- if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
- ParamName::Error(ident)
- } else {
- ParamName::Plain(ident)
- };
+ let param_name = if let Some(LifetimeRes::Error(..)) =
+ self.resolver.get_lifetime_res(param.id)
+ {
+ ParamName::Error(ident)
+ } else {
+ ParamName::Plain(ident)
+ };
let kind =
hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
@@ -2376,15 +2378,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_const_item_rhs(
&mut self,
- attrs: &[hir::Attribute],
- rhs: Option<&ConstItemRhs>,
+ rhs_kind: &ConstItemRhsKind,
span: Span,
) -> hir::ConstItemRhs<'hir> {
- match rhs {
- Some(ConstItemRhs::TypeConst(anon)) => {
+ match rhs_kind {
+ ConstItemRhsKind::Body { rhs: Some(body) } => {
+ hir::ConstItemRhs::Body(self.lower_const_body(span, Some(body)))
+ }
+ ConstItemRhsKind::Body { rhs: None } => {
+ hir::ConstItemRhs::Body(self.lower_const_body(span, None))
+ }
+ ConstItemRhsKind::TypeConst { rhs: Some(anon) } => {
hir::ConstItemRhs::TypeConst(self.lower_anon_const_to_const_arg_and_alloc(anon))
}
- None if find_attr!(attrs, AttributeKind::TypeConst(_)) => {
+ ConstItemRhsKind::TypeConst { rhs: None } => {
let const_arg = ConstArg {
hir_id: self.next_id(),
kind: hir::ConstArgKind::Error(
@@ -2394,10 +2401,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
};
hir::ConstItemRhs::TypeConst(self.arena.alloc(const_arg))
}
- Some(ConstItemRhs::Body(body)) => {
- hir::ConstItemRhs::Body(self.lower_const_body(span, Some(body)))
- }
- None => hir::ConstItemRhs::Body(self.lower_const_body(span, None)),
}
}
@@ -2427,15 +2430,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
);
let lowered_args = self.arena.alloc_from_iter(args.iter().map(|arg| {
- let const_arg = if let ExprKind::ConstBlock(anon_const) = &arg.kind {
- let def_id = self.local_def_id(anon_const.id);
- let def_kind = self.tcx.def_kind(def_id);
- assert_eq!(DefKind::AnonConst, def_kind);
- self.lower_anon_const_to_const_arg(anon_const)
- } else {
- self.lower_expr_to_const_arg_direct(arg)
- };
-
+ let const_arg = self.lower_expr_to_const_arg_direct(arg);
&*self.arena.alloc(const_arg)
}));
@@ -2447,16 +2442,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
ExprKind::Tup(exprs) => {
let exprs = self.arena.alloc_from_iter(exprs.iter().map(|expr| {
- let expr = if let ExprKind::ConstBlock(anon_const) = &expr.kind {
- let def_id = self.local_def_id(anon_const.id);
- let def_kind = self.tcx.def_kind(def_id);
- assert_eq!(DefKind::AnonConst, def_kind);
-
- self.lower_anon_const_to_const_arg(anon_const)
- } else {
- self.lower_expr_to_const_arg_direct(&expr)
- };
-
+ let expr = self.lower_expr_to_const_arg_direct(&expr);
&*self.arena.alloc(expr)
}));
@@ -2496,16 +2482,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// then go unused as the `Target::ExprField` is not actually
// corresponding to `Node::ExprField`.
self.lower_attrs(hir_id, &f.attrs, f.span, Target::ExprField);
-
- let expr = if let ExprKind::ConstBlock(anon_const) = &f.expr.kind {
- let def_id = self.local_def_id(anon_const.id);
- let def_kind = self.tcx.def_kind(def_id);
- assert_eq!(DefKind::AnonConst, def_kind);
-
- self.lower_anon_const_to_const_arg(anon_const)
- } else {
- self.lower_expr_to_const_arg_direct(&f.expr)
- };
+ let expr = self.lower_expr_to_const_arg_direct(&f.expr);
&*self.arena.alloc(hir::ConstArgExprField {
hir_id,
@@ -2523,13 +2500,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
ExprKind::Array(elements) => {
let lowered_elems = self.arena.alloc_from_iter(elements.iter().map(|element| {
- let const_arg = if let ExprKind::ConstBlock(anon_const) = &element.kind {
- let def_id = self.local_def_id(anon_const.id);
- assert_eq!(DefKind::AnonConst, self.tcx.def_kind(def_id));
- self.lower_anon_const_to_const_arg(anon_const)
- } else {
- self.lower_expr_to_const_arg_direct(element)
- };
+ let const_arg = self.lower_expr_to_const_arg_direct(element);
&*self.arena.alloc(const_arg)
}));
let array_expr = self.arena.alloc(hir::ConstArgArrayExpr {
@@ -2559,6 +2530,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
| ExprKind::Call(..)
| ExprKind::Tup(..)
| ExprKind::Array(..)
+ | ExprKind::ConstBlock(..)
)
{
return self.lower_expr_to_const_arg_direct(expr);
@@ -2572,10 +2544,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ConstArg {
hir_id: self.lower_node_id(expr.id),
- kind: hir::ConstArgKind::Literal(literal.node),
+ kind: hir::ConstArgKind::Literal { lit: literal.node, negated: false },
span,
}
}
+ ExprKind::Unary(UnOp::Neg, inner_expr)
+ if let ExprKind::Lit(literal) = &inner_expr.kind =>
+ {
+ let span = expr.span;
+ let literal = self.lower_lit(literal, span);
+
+ ConstArg {
+ hir_id: self.lower_node_id(expr.id),
+ kind: hir::ConstArgKind::Literal { lit: literal.node, negated: true },
+ span,
+ }
+ }
+ ExprKind::ConstBlock(anon_const) => {
+ let def_id = self.local_def_id(anon_const.id);
+ assert_eq!(DefKind::AnonConst, self.tcx.def_kind(def_id));
+ self.lower_anon_const_to_const_arg(anon_const, span)
+ }
_ => overly_complex_const(self),
}
}
@@ -2586,11 +2575,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&mut self,
anon: &AnonConst,
) -> &'hir hir::ConstArg<'hir> {
- self.arena.alloc(self.lower_anon_const_to_const_arg(anon))
+ self.arena.alloc(self.lower_anon_const_to_const_arg(anon, anon.value.span))
}
#[instrument(level = "debug", skip(self))]
- fn lower_anon_const_to_const_arg(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
+ fn lower_anon_const_to_const_arg(
+ &mut self,
+ anon: &AnonConst,
+ span: Span,
+ ) -> hir::ConstArg<'hir> {
let tcx = self.tcx;
// We cannot change parsing depending on feature gates available,
@@ -2601,7 +2594,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
if tcx.features().min_generic_const_args() {
return match anon.mgca_disambiguation {
MgcaDisambiguation::AnonConst => {
- let lowered_anon = self.lower_anon_const_to_anon_const(anon);
+ let lowered_anon = self.lower_anon_const_to_anon_const(anon, span);
ConstArg {
hir_id: self.next_id(),
kind: hir::ConstArgKind::Anon(lowered_anon),
@@ -2647,7 +2640,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
};
}
- let lowered_anon = self.lower_anon_const_to_anon_const(anon);
+ let lowered_anon = self.lower_anon_const_to_anon_const(anon, anon.value.span);
ConstArg {
hir_id: self.next_id(),
kind: hir::ConstArgKind::Anon(lowered_anon),
@@ -2657,7 +2650,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
/// See [`hir::ConstArg`] for when to use this function vs
/// [`Self::lower_anon_const_to_const_arg`].
- fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst {
+ fn lower_anon_const_to_anon_const(
+ &mut self,
+ c: &AnonConst,
+ span: Span,
+ ) -> &'hir hir::AnonConst {
self.arena.alloc(self.with_new_scopes(c.value.span, |this| {
let def_id = this.local_def_id(c.id);
let hir_id = this.lower_node_id(c.id);
@@ -2665,7 +2662,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
def_id,
hir_id,
body: this.lower_const_body(c.value.span, Some(&c.value)),
- span: this.lower_span(c.value.span),
+ span: this.lower_span(span),
}
}))
}
diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml
index 3e04f8b11ec9..fdc735fa8d4f 100644
--- a/compiler/rustc_ast_passes/Cargo.toml
+++ b/compiler/rustc_ast_passes/Cargo.toml
@@ -13,7 +13,6 @@ rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
-rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_macros = { path = "../rustc_macros" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
deleted file mode 100644
index b9117c83ae2f..000000000000
--- a/compiler/rustc_ast_passes/messages.ftl
+++ /dev/null
@@ -1,342 +0,0 @@
-ast_passes_abi_cannot_be_coroutine =
- functions with the {$abi} ABI cannot be `{$coroutine_kind_str}`
- .suggestion = remove the `{$coroutine_kind_str}` keyword from this definition
-
-ast_passes_abi_custom_safe_foreign_function =
- foreign functions with the "custom" ABI cannot be safe
- .suggestion = remove the `safe` keyword from this definition
-
-ast_passes_abi_custom_safe_function =
- functions with the "custom" ABI must be unsafe
- .suggestion = add the `unsafe` keyword to this definition
-
-ast_passes_abi_must_not_have_parameters_or_return_type=
- invalid signature for `extern {$abi}` function
- .note = functions with the {$abi} ABI cannot have any parameters or return type
- .suggestion = remove the parameters and return type
-
-ast_passes_abi_must_not_have_return_type=
- invalid signature for `extern {$abi}` function
- .note = functions with the {$abi} ABI cannot have a return type
- .help = remove the return type
-
-ast_passes_abi_x86_interrupt =
- invalid signature for `extern "x86-interrupt"` function
- .note = functions with the "x86-interrupt" ABI must be have either 1 or 2 parameters (but found {$param_count})
-
-ast_passes_assoc_const_without_body =
- associated constant in `impl` without body
- .suggestion = provide a definition for the constant
-
-ast_passes_assoc_fn_without_body =
- associated function in `impl` without body
- .suggestion = provide a definition for the function
-
-ast_passes_assoc_type_without_body =
- associated type in `impl` without body
- .suggestion = provide a definition for the type
-
-ast_passes_async_fn_in_const_trait_or_trait_impl =
- async functions are not allowed in `const` {$context ->
- [trait_impl] trait impls
- [impl] impls
- *[trait] traits
- }
- .label = associated functions of `const` cannot be declared `async`
-
-ast_passes_at_least_one_trait = at least one trait must be specified
-
-ast_passes_auto_generic = auto traits cannot have generic parameters
- .label = auto trait cannot have generic parameters
- .suggestion = remove the parameters
-
-ast_passes_auto_items = auto traits cannot have associated items
- .label = {ast_passes_auto_items}
- .suggestion = remove the associated items
-
-ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetime bounds
- .label = {ast_passes_auto_super_lifetime}
- .suggestion = remove the super traits or lifetime bounds
-
-ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block
- .cannot_have = cannot have a body
- .invalid = the invalid body
- .existing = `extern` blocks define existing foreign {$kind}s and {$kind}s inside of them cannot have a body
-
-ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect
-
-ast_passes_c_variadic_bad_extern = `...` is not supported for `extern "{$abi}"` functions
- .label = `extern "{$abi}"` because of this
- .help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
-
-ast_passes_c_variadic_bad_naked_extern = `...` is not supported for `extern "{$abi}"` naked functions
- .label = `extern "{$abi}"` because of this
- .help = C-variadic function must have a compatible calling convention
-
-ast_passes_c_variadic_must_be_unsafe =
- functions with a C variable argument list must be unsafe
- .suggestion = add the `unsafe` keyword to this definition
-
-ast_passes_c_variadic_no_extern = `...` is not supported for non-extern functions
- .help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
-
-ast_passes_c_variadic_not_supported = the `{$target}` target does not support c-variadic functions
-
-ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic
- .const = `const` because of this
- .variadic = C-variadic because of this
-
-ast_passes_const_and_coroutine = functions cannot be both `const` and `{$coroutine_kind}`
- .const = `const` because of this
- .coroutine = `{$coroutine_kind}` because of this
- .label = {""}
-
-ast_passes_const_auto_trait = auto traits cannot be const
- .help = remove the `const` keyword
-
-ast_passes_const_bound_trait_object = const trait bounds are not allowed in trait object types
-
-ast_passes_const_without_body =
- free constant item without body
- .suggestion = provide a definition for the constant
-
-ast_passes_constraint_on_negative_bound =
- associated type constraints not allowed on negative bounds
-
-ast_passes_coroutine_and_c_variadic = functions cannot be both `{$coroutine_kind}` and C-variadic
- .const = `{$coroutine_kind}` because of this
- .variadic = C-variadic because of this
-
-ast_passes_equality_in_where = equality constraints are not yet supported in `where` clauses
- .label = not supported
- .suggestion = if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax
- .suggestion_path = if `{$trait_segment}::{$potential_assoc}` is an associated type you're trying to set, use the associated type binding syntax
- .note = see issue #20041 for more information
-
-ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block
-
-ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have `{$kw}` qualifier
- .label = in this `extern` block
- .suggestion = remove the `{$kw}` qualifier
-
-ast_passes_extern_invalid_safety = items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers
- .suggestion = add `unsafe` to this `extern` block
-
-ast_passes_extern_item_ascii = items in `extern` blocks cannot use non-ascii identifiers
- .label = in this `extern` block
- .note = this limitation may be lifted in the future; see issue #83942 for more information
-
-ast_passes_extern_keyword_link = for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
-
-ast_passes_extern_types_cannot = `type`s inside `extern` blocks cannot have {$descr}
- .suggestion = remove the {$remove_descr}
- .label = `extern` block begins here
-
-ast_passes_extern_without_abi = `extern` declarations without an explicit ABI are disallowed
- .suggestion = specify an ABI
- .help = prior to Rust 2024, a default ABI was inferred
-
-ast_passes_extern_without_abi_sugg = `extern` declarations without an explicit ABI are deprecated
- .label = ABI should be specified here
- .suggestion = explicitly specify the {$default_abi} ABI
-
-ast_passes_feature_on_non_nightly = `#![feature]` may not be used on the {$channel} release channel
- .suggestion = remove the attribute
- .stable_since = the feature `{$name}` has been stable since `{$since}` and no longer requires an attribute to enable
-
-ast_passes_fieldless_union = unions cannot have zero fields
-
-ast_passes_fn_body_extern = incorrect function inside `extern` block
- .cannot_have = cannot have a body
- .suggestion = remove the invalid body
- .help = you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block
- .label = `extern` blocks define existing foreign functions and functions inside of them cannot have a body
-
-ast_passes_fn_param_c_var_args_not_last =
- `...` must be the last argument of a C-variadic function
-
-ast_passes_fn_param_doc_comment =
- documentation comments cannot be applied to function parameters
- .label = doc comments are not allowed here
-
-ast_passes_fn_param_forbidden_attr =
- allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters
-
-ast_passes_fn_param_forbidden_self =
- `self` parameter is only allowed in associated functions
- .label = not semantically valid as function parameter
- .note = associated functions are those in `impl` or `trait` definitions
-
-ast_passes_fn_param_too_many =
- function can not have more than {$max_num_args} arguments
-
-ast_passes_fn_ptr_invalid_safety = function pointers cannot be declared with `safe` safety qualifier
- .suggestion = remove safe from this item
-
-ast_passes_fn_without_body =
- free function without a body
- .suggestion = provide a definition for the function
-
-ast_passes_forbidden_bound =
- bounds cannot be used in this context
-
-ast_passes_forbidden_const_param =
- late-bound const parameters cannot be used currently
-
-ast_passes_forbidden_default =
- `default` is only allowed on items in trait impls
- .label = `default` because of this
-
-ast_passes_forbidden_non_lifetime_param =
- only lifetime parameters can be used in this context
-
-ast_passes_generic_before_constraints = generic arguments must come before the first constraint
- .constraints = {$constraint_len ->
- [one] constraint
- *[other] constraints
- }
- .args = generic {$args_len ->
- [one] argument
- *[other] arguments
- }
- .empty_string = {""},
- .suggestion = move the {$constraint_len ->
- [one] constraint
- *[other] constraints
- } after the generic {$args_len ->
- [one] argument
- *[other] arguments
- }
-
-ast_passes_generic_default_trailing = generic parameters with a default must be trailing
-
-ast_passes_impl_fn_const =
- redundant `const` fn marker in const impl
- .parent_constness = this declares all associated functions implicitly const
- .label = remove the `const`
-
-ast_passes_incompatible_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed
- .help = remove one of these features
-
-ast_passes_item_invalid_safety = items outside of `unsafe extern {"{ }"}` cannot be declared with `safe` safety qualifier
- .suggestion = remove safe from this item
-
-ast_passes_item_underscore = `{$kind}` items in this context need a name
- .label = `_` is not a valid name for this `{$kind}` item
-
-ast_passes_match_arm_with_no_body =
- `match` arm with no body
- .suggestion = add a body after the pattern
-
-ast_passes_missing_unsafe_on_extern = extern blocks must be unsafe
- .suggestion = needs `unsafe` before the extern keyword
-
-ast_passes_missing_unsafe_on_extern_lint = extern blocks should be unsafe
- .suggestion = needs `unsafe` before the extern keyword
-
-ast_passes_module_nonascii = trying to load file for module `{$name}` with non-ascii identifier name
- .help = consider using the `#[path]` attribute to specify filesystem path
-
-ast_passes_negative_bound_not_supported =
- negative bounds are not supported
-
-ast_passes_negative_bound_with_parenthetical_notation =
- parenthetical notation may not be used for negative bounds
-
-ast_passes_nested_impl_trait = nested `impl Trait` is not allowed
- .outer = outer `impl Trait`
- .inner = nested `impl Trait` here
-
-ast_passes_nested_lifetimes = nested quantification of lifetimes
-
-ast_passes_nomangle_ascii = `#[no_mangle]` requires ASCII identifier
-
-ast_passes_obsolete_auto = `impl Trait for .. {"{}"}` is an obsolete syntax
- .help = use `auto trait Trait {"{}"}` instead
-
-ast_passes_out_of_order_params = {$param_ord} parameters must be declared prior to {$max_param} parameters
- .suggestion = reorder the parameters: lifetimes, then consts and types
-
-ast_passes_pattern_in_bodiless = patterns aren't allowed in functions without bodies
- .label = pattern not allowed in function without body
-
-ast_passes_pattern_in_fn_pointer = patterns aren't allowed in function pointer types
-
-ast_passes_pattern_in_foreign = patterns aren't allowed in foreign function declarations
- .label = pattern not allowed in foreign function
-
-ast_passes_precise_capturing_duplicated = duplicate `use<...>` precise capturing syntax
- .label = second `use<...>` here
-
-ast_passes_precise_capturing_not_allowed_here = `use<...>` precise capturing syntax not allowed in {$loc}
-
-ast_passes_scalable_vector_not_tuple_struct = scalable vectors must be tuple structs
-
-ast_passes_static_without_body =
- free static item without body
- .suggestion = provide a definition for the static
-
-ast_passes_tilde_const_disallowed = `[const]` is not allowed here
- .closure = closures cannot have `[const]` trait bounds
- .function = this function is not `const`, so it cannot have `[const]` trait bounds
- .trait = this trait is not `const`, so it cannot have `[const]` trait bounds
- .trait_impl = this impl is not `const`, so it cannot have `[const]` trait bounds
- .impl = inherent impls cannot have `[const]` trait bounds
- .trait_assoc_ty = associated types in non-`const` traits cannot have `[const]` trait bounds
- .trait_impl_assoc_ty = associated types in non-const impls cannot have `[const]` trait bounds
- .inherent_assoc_ty = inherent associated types cannot have `[const]` trait bounds
- .struct = structs cannot have `[const]` trait bounds
- .enum = enums cannot have `[const]` trait bounds
- .union = unions cannot have `[const]` trait bounds
- .anon_const = anonymous constants cannot have `[const]` trait bounds
- .object = trait objects cannot have `[const]` trait bounds
- .item = this item cannot have `[const]` trait bounds
-
-ast_passes_trait_fn_const =
- functions in {$in_impl ->
- [true] trait impls
- *[false] traits
- } cannot be declared const
- .label = functions in {$in_impl ->
- [true] trait impls
- *[false] traits
- } cannot be const
- .const_context_label = this declares all associated functions implicitly const
- .remove_const_sugg = remove the `const`{$requires_multiple_changes ->
- [true] {" ..."}
- *[false] {""}
- }
- .make_impl_const_sugg = ... and declare the impl to be const instead
- .make_trait_const_sugg = ... and declare the trait to be const instead
-
-ast_passes_trait_object_single_bound = only a single explicit lifetime bound is permitted
-
-ast_passes_ty_alias_without_body =
- free type alias without body
- .suggestion = provide a definition for the type
-
-ast_passes_unsafe_item = {$kind} cannot be declared unsafe
-
-ast_passes_unsafe_negative_impl = negative impls cannot be unsafe
- .negative = negative because of this
- .unsafe = unsafe because of this
-
-ast_passes_unsafe_static =
- static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
-
-ast_passes_visibility_not_permitted =
- visibility qualifiers are not permitted here
- .enum_variant = enum variants and their fields always share the visibility of the enum they are in
- .trait_impl = trait items always share the visibility of their trait
- .individual_impl_items = place qualifiers on individual impl items instead
- .individual_foreign_items = place qualifiers on individual foreign items instead
- .remove_qualifier_sugg = remove the qualifier
-
-ast_passes_where_clause_after_type_alias = where clauses are not allowed after the type for type aliases
- .note = see issue #112792 for more information
- .help = add `#![feature(lazy_type_alias)]` to the crate attributes to enable
-
-ast_passes_where_clause_before_type_alias = where clauses are not allowed before the type for type aliases
- .note = see issue #89122 for more information
- .remove_suggestion = remove this `where`
- .move_suggestion = move it to the end of the type declaration
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 2457e0a777e4..b9fb20b68971 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -1361,9 +1361,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
});
}
- ItemKind::Const(box ConstItem { defaultness, ident, rhs, .. }) => {
+ ItemKind::Const(box ConstItem { defaultness, ident, rhs_kind, .. }) => {
self.check_defaultness(item.span, *defaultness);
- if rhs.is_none() {
+ if !rhs_kind.has_expr() {
self.dcx().emit_err(errors::ConstWithoutBody {
span: item.span,
replace_span: self.ending_semi_or_hi(item.span),
@@ -1715,11 +1715,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if let AssocCtxt::Impl { .. } = ctxt {
match &item.kind {
- AssocItemKind::Const(box ConstItem { rhs: None, .. }) => {
- self.dcx().emit_err(errors::AssocConstWithoutBody {
- span: item.span,
- replace_span: self.ending_semi_or_hi(item.span),
- });
+ AssocItemKind::Const(box ConstItem { rhs_kind, .. }) => {
+ if !rhs_kind.has_expr() {
+ self.dcx().emit_err(errors::AssocConstWithoutBody {
+ span: item.span,
+ replace_span: self.ending_semi_or_hi(item.span),
+ });
+ }
}
AssocItemKind::Fn(box Fn { body, .. }) => {
if body.is_none() && !self.is_sdylib_interface {
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 22adaae8c6f2..dd260aede489 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -7,64 +7,72 @@ use rustc_errors::{Applicability, Diag, EmissionGuarantee, Subdiagnostic};
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
use rustc_span::{Ident, Span, Symbol};
-use crate::fluent_generated as fluent;
-
#[derive(Diagnostic)]
-#[diag(ast_passes_visibility_not_permitted, code = E0449)]
+#[diag("visibility qualifiers are not permitted here", code = E0449)]
pub(crate) struct VisibilityNotPermitted {
#[primary_span]
pub span: Span,
#[subdiagnostic]
pub note: VisibilityNotPermittedNote,
- #[suggestion(
- ast_passes_remove_qualifier_sugg,
- code = "",
- applicability = "machine-applicable"
- )]
+ #[suggestion("remove the qualifier", code = "", applicability = "machine-applicable")]
pub remove_qualifier_sugg: Span,
}
#[derive(Subdiagnostic)]
pub(crate) enum VisibilityNotPermittedNote {
- #[note(ast_passes_enum_variant)]
+ #[note("enum variants and their fields always share the visibility of the enum they are in")]
EnumVariant,
- #[note(ast_passes_trait_impl)]
+ #[note("trait items always share the visibility of their trait")]
TraitImpl,
- #[note(ast_passes_individual_impl_items)]
+ #[note("place qualifiers on individual impl items instead")]
IndividualImplItems,
- #[note(ast_passes_individual_foreign_items)]
+ #[note("place qualifiers on individual foreign items instead")]
IndividualForeignItems,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_impl_fn_const)]
+#[diag("redundant `const` fn marker in const impl")]
pub(crate) struct ImplFnConst {
#[primary_span]
- #[suggestion(ast_passes_label, code = "", applicability = "machine-applicable")]
+ #[suggestion("remove the `const`", code = "", applicability = "machine-applicable")]
pub span: Span,
- #[label(ast_passes_parent_constness)]
+ #[label("this declares all associated functions implicitly const")]
pub parent_constness: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_trait_fn_const, code = E0379)]
+#[diag("functions in {$in_impl ->
+ [true] trait impls
+ *[false] traits
+ } cannot be declared const", code = E0379)]
pub(crate) struct TraitFnConst {
#[primary_span]
- #[label]
+ #[label(
+ "functions in {$in_impl ->
+ [true] trait impls
+ *[false] traits
+ } cannot be const"
+ )]
pub span: Span,
pub in_impl: bool,
- #[label(ast_passes_const_context_label)]
+ #[label("this declares all associated functions implicitly const")]
pub const_context_label: Option,
- #[suggestion(ast_passes_remove_const_sugg, code = "")]
+ #[suggestion(
+ "remove the `const`{$requires_multiple_changes ->
+ [true] {\" ...\"}
+ *[false] {\"\"}
+ }",
+ code = ""
+ )]
pub remove_const_sugg: (Span, Applicability),
pub requires_multiple_changes: bool,
#[suggestion(
- ast_passes_make_impl_const_sugg,
+ "... and declare the impl to be const instead",
code = "const ",
applicability = "maybe-incorrect"
)]
pub make_impl_const_sugg: Option,
#[suggestion(
- ast_passes_make_trait_const_sugg,
+ "... and declare the trait to be const instead",
code = "const ",
applicability = "maybe-incorrect"
)]
@@ -72,31 +80,37 @@ pub(crate) struct TraitFnConst {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_async_fn_in_const_trait_or_trait_impl)]
+#[diag(
+ "async functions are not allowed in `const` {$context ->
+ [trait_impl] trait impls
+ [impl] impls
+ *[trait] traits
+ }"
+)]
pub(crate) struct AsyncFnInConstTraitOrTraitImpl {
#[primary_span]
pub async_keyword: Span,
pub context: &'static str,
- #[label]
+ #[label("associated functions of `const` cannot be declared `async`")]
pub const_keyword: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_forbidden_bound)]
+#[diag("bounds cannot be used in this context")]
pub(crate) struct ForbiddenBound {
#[primary_span]
pub spans: Vec,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_forbidden_const_param)]
+#[diag("late-bound const parameters cannot be used currently")]
pub(crate) struct ForbiddenConstParam {
#[primary_span]
pub const_param_spans: Vec,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_fn_param_too_many)]
+#[diag("function can not have more than {$max_num_args} arguments")]
pub(crate) struct FnParamTooMany {
#[primary_span]
pub span: Span,
@@ -104,105 +118,135 @@ pub(crate) struct FnParamTooMany {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_fn_param_c_var_args_not_last)]
+#[diag("`...` must be the last argument of a C-variadic function")]
pub(crate) struct FnParamCVarArgsNotLast {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_fn_param_doc_comment)]
+#[diag("documentation comments cannot be applied to function parameters")]
pub(crate) struct FnParamDocComment {
#[primary_span]
- #[label]
+ #[label("doc comments are not allowed here")]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_fn_param_forbidden_attr)]
+#[diag(
+ "allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters"
+)]
pub(crate) struct FnParamForbiddenAttr {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_fn_param_forbidden_self)]
-#[note]
+#[diag("`self` parameter is only allowed in associated functions")]
+#[note("associated functions are those in `impl` or `trait` definitions")]
pub(crate) struct FnParamForbiddenSelf {
#[primary_span]
- #[label]
+ #[label("not semantically valid as function parameter")]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_forbidden_default)]
+#[diag("`default` is only allowed on items in trait impls")]
pub(crate) struct ForbiddenDefault {
#[primary_span]
pub span: Span,
- #[label]
+ #[label("`default` because of this")]
pub def_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_assoc_const_without_body)]
+#[diag("associated constant in `impl` without body")]
pub(crate) struct AssocConstWithoutBody {
#[primary_span]
pub span: Span,
- #[suggestion(code = " = ;", applicability = "has-placeholders")]
+ #[suggestion(
+ "provide a definition for the constant",
+ code = " = ;",
+ applicability = "has-placeholders"
+ )]
pub replace_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_assoc_fn_without_body)]
+#[diag("associated function in `impl` without body")]
pub(crate) struct AssocFnWithoutBody {
#[primary_span]
pub span: Span,
- #[suggestion(code = " {{ }}", applicability = "has-placeholders")]
+ #[suggestion(
+ "provide a definition for the function",
+ code = " {{ }}",
+ applicability = "has-placeholders"
+ )]
pub replace_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_assoc_type_without_body)]
+#[diag("associated type in `impl` without body")]
pub(crate) struct AssocTypeWithoutBody {
#[primary_span]
pub span: Span,
- #[suggestion(code = " = ;", applicability = "has-placeholders")]
+ #[suggestion(
+ "provide a definition for the type",
+ code = " = ;",
+ applicability = "has-placeholders"
+ )]
pub replace_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_const_without_body)]
+#[diag("free constant item without body")]
pub(crate) struct ConstWithoutBody {
#[primary_span]
pub span: Span,
- #[suggestion(code = " = ;", applicability = "has-placeholders")]
+ #[suggestion(
+ "provide a definition for the constant",
+ code = " = ;",
+ applicability = "has-placeholders"
+ )]
pub replace_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_static_without_body)]
+#[diag("free static item without body")]
pub(crate) struct StaticWithoutBody {
#[primary_span]
pub span: Span,
- #[suggestion(code = " = ;", applicability = "has-placeholders")]
+ #[suggestion(
+ "provide a definition for the static",
+ code = " = ;",
+ applicability = "has-placeholders"
+ )]
pub replace_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_ty_alias_without_body)]
+#[diag("free type alias without body")]
pub(crate) struct TyAliasWithoutBody {
#[primary_span]
pub span: Span,
- #[suggestion(code = " = ;", applicability = "has-placeholders")]
+ #[suggestion(
+ "provide a definition for the type",
+ code = " = ;",
+ applicability = "has-placeholders"
+ )]
pub replace_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_fn_without_body)]
+#[diag("free function without a body")]
pub(crate) struct FnWithoutBody {
#[primary_span]
pub span: Span,
- #[suggestion(code = " {{ }}", applicability = "has-placeholders")]
+ #[suggestion(
+ "provide a definition for the function",
+ code = " {{ }}",
+ applicability = "has-placeholders"
+ )]
pub replace_span: Span,
#[subdiagnostic]
pub extern_block_suggestion: Option,
@@ -210,14 +254,20 @@ pub(crate) struct FnWithoutBody {
#[derive(Subdiagnostic)]
pub(crate) enum ExternBlockSuggestion {
- #[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")]
+ #[multipart_suggestion(
+ "if you meant to declare an externally defined function, use an `extern` block",
+ applicability = "maybe-incorrect"
+ )]
Implicit {
#[suggestion_part(code = "extern {{")]
start_span: Span,
#[suggestion_part(code = " }}")]
end_span: Span,
},
- #[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")]
+ #[multipart_suggestion(
+ "if you meant to declare an externally defined function, use an `extern` block",
+ applicability = "maybe-incorrect"
+ )]
Explicit {
#[suggestion_part(code = "extern \"{abi}\" {{")]
start_span: Span,
@@ -228,37 +278,44 @@ pub(crate) enum ExternBlockSuggestion {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_extern_invalid_safety)]
+#[diag("items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers")]
pub(crate) struct InvalidSafetyOnExtern {
#[primary_span]
pub item_span: Span,
- #[suggestion(code = "unsafe ", applicability = "machine-applicable", style = "verbose")]
+ #[suggestion(
+ "add `unsafe` to this `extern` block",
+ code = "unsafe ",
+ applicability = "machine-applicable",
+ style = "verbose"
+ )]
pub block: Option,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_item_invalid_safety)]
+#[diag(
+ "items outside of `unsafe extern {\"{ }\"}` cannot be declared with `safe` safety qualifier"
+)]
pub(crate) struct InvalidSafetyOnItem {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_fn_ptr_invalid_safety)]
+#[diag("function pointers cannot be declared with `safe` safety qualifier")]
pub(crate) struct InvalidSafetyOnFnPtr {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_unsafe_static)]
+#[diag("static items cannot be declared with `unsafe` safety qualifier outside of `extern` block")]
pub(crate) struct UnsafeStatic {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_bound_in_context)]
+#[diag("bounds on `type`s in {$ctx} have no effect")]
pub(crate) struct BoundInContext<'a> {
#[primary_span]
pub span: Span,
@@ -266,83 +323,93 @@ pub(crate) struct BoundInContext<'a> {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_extern_types_cannot)]
-#[note(ast_passes_extern_keyword_link)]
+#[diag("`type`s inside `extern` blocks cannot have {$descr}")]
+#[note("for more information, visit https://doc.rust-lang.org/std/keyword.extern.html")]
pub(crate) struct ExternTypesCannotHave<'a> {
#[primary_span]
- #[suggestion(code = "", applicability = "maybe-incorrect")]
+ #[suggestion("remove the {$remove_descr}", code = "", applicability = "maybe-incorrect")]
pub span: Span,
pub descr: &'a str,
pub remove_descr: &'a str,
- #[label]
+ #[label("`extern` block begins here")]
pub block_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_body_in_extern)]
-#[note(ast_passes_extern_keyword_link)]
+#[diag("incorrect `{$kind}` inside `extern` block")]
+#[note("for more information, visit https://doc.rust-lang.org/std/keyword.extern.html")]
pub(crate) struct BodyInExtern<'a> {
#[primary_span]
- #[label(ast_passes_cannot_have)]
+ #[label("cannot have a body")]
pub span: Span,
- #[label(ast_passes_invalid)]
+ #[label("the invalid body")]
pub body: Span,
- #[label(ast_passes_existing)]
+ #[label(
+ "`extern` blocks define existing foreign {$kind}s and {$kind}s inside of them cannot have a body"
+ )]
pub block: Span,
pub kind: &'a str,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_fn_body_extern)]
-#[help]
-#[note(ast_passes_extern_keyword_link)]
+#[diag("incorrect function inside `extern` block")]
+#[help(
+ "you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block"
+)]
+#[note("for more information, visit https://doc.rust-lang.org/std/keyword.extern.html")]
pub(crate) struct FnBodyInExtern {
#[primary_span]
- #[label(ast_passes_cannot_have)]
+ #[label("cannot have a body")]
pub span: Span,
- #[suggestion(code = ";", applicability = "maybe-incorrect")]
+ #[suggestion("remove the invalid body", code = ";", applicability = "maybe-incorrect")]
pub body: Span,
- #[label]
+ #[label(
+ "`extern` blocks define existing foreign functions and functions inside of them cannot have a body"
+ )]
pub block: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_extern_fn_qualifiers)]
+#[diag("functions in `extern` blocks cannot have `{$kw}` qualifier")]
pub(crate) struct FnQualifierInExtern {
#[primary_span]
- #[suggestion(code = "", applicability = "maybe-incorrect")]
+ #[suggestion("remove the `{$kw}` qualifier", code = "", applicability = "maybe-incorrect")]
pub span: Span,
- #[label]
+ #[label("in this `extern` block")]
pub block: Span,
pub kw: &'static str,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_extern_item_ascii)]
-#[note]
+#[diag("items in `extern` blocks cannot use non-ascii identifiers")]
+#[note(
+ "this limitation may be lifted in the future; see issue #83942 for more information"
+)]
pub(crate) struct ExternItemAscii {
#[primary_span]
pub span: Span,
- #[label]
+ #[label("in this `extern` block")]
pub block: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_c_variadic_no_extern)]
-#[help]
+#[diag("`...` is not supported for non-extern functions")]
+#[help(
+ "only `extern \"C\"` and `extern \"C-unwind\"` functions may have a C variable argument list"
+)]
pub(crate) struct CVariadicNoExtern {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_c_variadic_must_be_unsafe)]
+#[diag("functions with a C variable argument list must be unsafe")]
pub(crate) struct CVariadicMustBeUnsafe {
#[primary_span]
pub span: Span,
#[suggestion(
- ast_passes_suggestion,
+ "add the `unsafe` keyword to this definition",
applicability = "maybe-incorrect",
code = "unsafe ",
style = "verbose"
@@ -351,46 +418,48 @@ pub(crate) struct CVariadicMustBeUnsafe {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_c_variadic_bad_extern)]
-#[help]
+#[diag("`...` is not supported for `extern \"{$abi}\"` functions")]
+#[help(
+ "only `extern \"C\"` and `extern \"C-unwind\"` functions may have a C variable argument list"
+)]
pub(crate) struct CVariadicBadExtern {
#[primary_span]
pub span: Span,
pub abi: &'static str,
- #[label]
+ #[label("`extern \"{$abi}\"` because of this")]
pub extern_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_c_variadic_bad_naked_extern)]
-#[help]
+#[diag("`...` is not supported for `extern \"{$abi}\"` naked functions")]
+#[help("C-variadic function must have a compatible calling convention")]
pub(crate) struct CVariadicBadNakedExtern {
#[primary_span]
pub span: Span,
pub abi: &'static str,
- #[label]
+ #[label("`extern \"{$abi}\"` because of this")]
pub extern_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_item_underscore)]
+#[diag("`{$kind}` items in this context need a name")]
pub(crate) struct ItemUnderscore<'a> {
#[primary_span]
- #[label]
+ #[label("`_` is not a valid name for this `{$kind}` item")]
pub span: Span,
pub kind: &'a str,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_nomangle_ascii, code = E0754)]
+#[diag("`#[no_mangle]` requires ASCII identifier", code = E0754)]
pub(crate) struct NoMangleAscii {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_module_nonascii, code = E0754)]
-#[help]
+#[diag("trying to load file for module `{$name}` with non-ascii identifier name", code = E0754)]
+#[help("consider using the `#[path]` attribute to specify filesystem path")]
pub(crate) struct ModuleNonAscii {
#[primary_span]
pub span: Span,
@@ -398,55 +467,91 @@ pub(crate) struct ModuleNonAscii {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_auto_generic, code = E0567)]
+#[diag("auto traits cannot have generic parameters", code = E0567)]
pub(crate) struct AutoTraitGeneric {
#[primary_span]
- #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
+ #[suggestion(
+ "remove the parameters",
+ code = "",
+ applicability = "machine-applicable",
+ style = "tool-only"
+ )]
pub span: Span,
- #[label]
+ #[label("auto trait cannot have generic parameters")]
pub ident: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_auto_super_lifetime, code = E0568)]
+#[diag("auto traits cannot have super traits or lifetime bounds", code = E0568)]
pub(crate) struct AutoTraitBounds {
#[primary_span]
pub span: Vec,
- #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
+ #[suggestion(
+ "remove the super traits or lifetime bounds",
+ code = "",
+ applicability = "machine-applicable",
+ style = "tool-only"
+ )]
pub removal: Span,
- #[label]
+ #[label("auto traits cannot have super traits or lifetime bounds")]
pub ident: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_auto_items, code = E0380)]
+#[diag("auto traits cannot have associated items", code = E0380)]
pub(crate) struct AutoTraitItems {
#[primary_span]
pub spans: Vec,
- #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
+ #[suggestion(
+ "remove the associated items",
+ code = "",
+ applicability = "machine-applicable",
+ style = "tool-only"
+ )]
pub total: Span,
- #[label]
+ #[label("auto traits cannot have associated items")]
pub ident: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_const_auto_trait)]
-#[help]
+#[diag("auto traits cannot be const")]
+#[help("remove the `const` keyword")]
pub(crate) struct ConstAutoTrait {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_generic_before_constraints)]
+#[diag("generic arguments must come before the first constraint")]
pub(crate) struct ArgsBeforeConstraint {
#[primary_span]
pub arg_spans: Vec,
- #[label(ast_passes_constraints)]
+ #[label(
+ "{$constraint_len ->
+ [one] constraint
+ *[other] constraints
+ }"
+ )]
pub constraints: Span,
- #[label(ast_passes_args)]
+ #[label(
+ "generic {$args_len ->
+ [one] argument
+ *[other] arguments
+ }"
+ )]
pub args: Span,
- #[suggestion(code = "{suggestion}", applicability = "machine-applicable", style = "verbose")]
+ #[suggestion(
+ "move the {$constraint_len ->
+ [one] constraint
+ *[other] constraints
+ } after the generic {$args_len ->
+ [one] argument
+ *[other] arguments
+ }",
+ code = "{suggestion}",
+ applicability = "machine-applicable",
+ style = "verbose"
+ )]
pub data: Span,
pub suggestion: String,
pub constraint_len: usize,
@@ -467,43 +572,47 @@ impl Subdiagnostic for EmptyLabelManySpans {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_pattern_in_fn_pointer, code = E0561)]
+#[diag("patterns aren't allowed in function pointer types", code = E0561)]
pub(crate) struct PatternFnPointer {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_trait_object_single_bound, code = E0226)]
+#[diag("only a single explicit lifetime bound is permitted", code = E0226)]
pub(crate) struct TraitObjectBound {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_nested_impl_trait, code = E0666)]
+#[diag("nested `impl Trait` is not allowed", code = E0666)]
pub(crate) struct NestedImplTrait {
#[primary_span]
pub span: Span,
- #[label(ast_passes_outer)]
+ #[label("outer `impl Trait`")]
pub outer: Span,
- #[label(ast_passes_inner)]
+ #[label("nested `impl Trait` here")]
pub inner: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_at_least_one_trait)]
+#[diag("at least one trait must be specified")]
pub(crate) struct AtLeastOneTrait {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_out_of_order_params)]
+#[diag("{$param_ord} parameters must be declared prior to {$max_param} parameters")]
pub(crate) struct OutOfOrderParams<'a> {
#[primary_span]
pub spans: Vec,
- #[suggestion(code = "{ordered_params}", applicability = "machine-applicable")]
+ #[suggestion(
+ "reorder the parameters: lifetimes, then consts and types",
+ code = "{ordered_params}",
+ applicability = "machine-applicable"
+ )]
pub sugg_span: Span,
pub param_ord: &'a ParamKindOrd,
pub max_param: &'a ParamKindOrd,
@@ -511,26 +620,26 @@ pub(crate) struct OutOfOrderParams<'a> {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_obsolete_auto)]
-#[help]
+#[diag("`impl Trait for .. {\"{}\"}` is an obsolete syntax")]
+#[help("use `auto trait Trait {\"{}\"}` instead")]
pub(crate) struct ObsoleteAuto {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_unsafe_negative_impl, code = E0198)]
+#[diag("negative impls cannot be unsafe", code = E0198)]
pub(crate) struct UnsafeNegativeImpl {
#[primary_span]
pub span: Span,
- #[label(ast_passes_negative)]
+ #[label("negative because of this")]
pub negative: Span,
- #[label(ast_passes_unsafe)]
+ #[label("unsafe because of this")]
pub r#unsafe: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_unsafe_item)]
+#[diag("{$kind} cannot be declared unsafe")]
pub(crate) struct UnsafeItem {
#[primary_span]
pub span: Span,
@@ -538,39 +647,43 @@ pub(crate) struct UnsafeItem {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_missing_unsafe_on_extern)]
+#[diag("extern blocks must be unsafe")]
pub(crate) struct MissingUnsafeOnExtern {
#[primary_span]
pub span: Span,
}
#[derive(LintDiagnostic)]
-#[diag(ast_passes_missing_unsafe_on_extern_lint)]
+#[diag("extern blocks should be unsafe")]
pub(crate) struct MissingUnsafeOnExternLint {
- #[suggestion(code = "unsafe ", applicability = "machine-applicable")]
+ #[suggestion(
+ "needs `unsafe` before the extern keyword",
+ code = "unsafe ",
+ applicability = "machine-applicable"
+ )]
pub suggestion: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_fieldless_union)]
+#[diag("unions cannot have zero fields")]
pub(crate) struct FieldlessUnion {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_where_clause_after_type_alias)]
-#[note]
+#[diag("where clauses are not allowed after the type for type aliases")]
+#[note("see issue #112792 for more information")]
pub(crate) struct WhereClauseAfterTypeAlias {
#[primary_span]
pub span: Span,
- #[help]
+ #[help("add `#![feature(lazy_type_alias)]` to the crate attributes to enable")]
pub help: bool,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_where_clause_before_type_alias)]
-#[note]
+#[diag("where clauses are not allowed before the type for type aliases")]
+#[note("see issue #89122 for more information")]
pub(crate) struct WhereClauseBeforeTypeAlias {
#[primary_span]
pub span: Span,
@@ -580,13 +693,13 @@ pub(crate) struct WhereClauseBeforeTypeAlias {
#[derive(Subdiagnostic)]
pub(crate) enum WhereClauseBeforeTypeAliasSugg {
- #[suggestion(ast_passes_remove_suggestion, applicability = "machine-applicable", code = "")]
+ #[suggestion("remove this `where`", applicability = "machine-applicable", code = "")]
Remove {
#[primary_span]
span: Span,
},
#[multipart_suggestion(
- ast_passes_move_suggestion,
+ "move it to the end of the type declaration",
applicability = "machine-applicable",
style = "verbose"
)]
@@ -600,21 +713,21 @@ pub(crate) enum WhereClauseBeforeTypeAliasSugg {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_generic_default_trailing)]
+#[diag("generic parameters with a default must be trailing")]
pub(crate) struct GenericDefaultTrailing {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_nested_lifetimes, code = E0316)]
+#[diag("nested quantification of lifetimes", code = E0316)]
pub(crate) struct NestedLifetimes {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_const_bound_trait_object)]
+#[diag("const trait bounds are not allowed in trait object types")]
pub(crate) struct ConstBoundTraitObject {
#[primary_span]
pub span: Span,
@@ -623,7 +736,7 @@ pub(crate) struct ConstBoundTraitObject {
// FIXME(const_trait_impl): Consider making the note/reason the message of the diagnostic.
// FIXME(const_trait_impl): Provide structured suggestions (e.g., add `const` here).
#[derive(Diagnostic)]
-#[diag(ast_passes_tilde_const_disallowed)]
+#[diag("`[const]` is not allowed here")]
pub(crate) struct TildeConstDisallowed {
#[primary_span]
pub span: Span,
@@ -633,108 +746,108 @@ pub(crate) struct TildeConstDisallowed {
#[derive(Subdiagnostic, Copy, Clone)]
pub(crate) enum TildeConstReason {
- #[note(ast_passes_closure)]
+ #[note("closures cannot have `[const]` trait bounds")]
Closure,
- #[note(ast_passes_function)]
+ #[note("this function is not `const`, so it cannot have `[const]` trait bounds")]
Function {
#[primary_span]
ident: Span,
},
- #[note(ast_passes_trait)]
+ #[note("this trait is not `const`, so it cannot have `[const]` trait bounds")]
Trait {
#[primary_span]
span: Span,
},
- #[note(ast_passes_trait_impl)]
+ #[note("this impl is not `const`, so it cannot have `[const]` trait bounds")]
TraitImpl {
#[primary_span]
span: Span,
},
- #[note(ast_passes_impl)]
+ #[note("inherent impls cannot have `[const]` trait bounds")]
Impl {
#[primary_span]
span: Span,
},
- #[note(ast_passes_trait_assoc_ty)]
+ #[note("associated types in non-`const` traits cannot have `[const]` trait bounds")]
TraitAssocTy {
#[primary_span]
span: Span,
},
- #[note(ast_passes_trait_impl_assoc_ty)]
+ #[note("associated types in non-const impls cannot have `[const]` trait bounds")]
TraitImplAssocTy {
#[primary_span]
span: Span,
},
- #[note(ast_passes_inherent_assoc_ty)]
+ #[note("inherent associated types cannot have `[const]` trait bounds")]
InherentAssocTy {
#[primary_span]
span: Span,
},
- #[note(ast_passes_struct)]
+ #[note("structs cannot have `[const]` trait bounds")]
Struct {
#[primary_span]
span: Span,
},
- #[note(ast_passes_enum)]
+ #[note("enums cannot have `[const]` trait bounds")]
Enum {
#[primary_span]
span: Span,
},
- #[note(ast_passes_union)]
+ #[note("unions cannot have `[const]` trait bounds")]
Union {
#[primary_span]
span: Span,
},
- #[note(ast_passes_anon_const)]
+ #[note("anonymous constants cannot have `[const]` trait bounds")]
AnonConst {
#[primary_span]
span: Span,
},
- #[note(ast_passes_object)]
+ #[note("trait objects cannot have `[const]` trait bounds")]
TraitObject,
- #[note(ast_passes_item)]
+ #[note("this item cannot have `[const]` trait bounds")]
Item,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_const_and_coroutine)]
+#[diag("functions cannot be both `const` and `{$coroutine_kind}`")]
pub(crate) struct ConstAndCoroutine {
#[primary_span]
pub spans: Vec,
- #[label(ast_passes_const)]
+ #[label("`const` because of this")]
pub const_span: Span,
- #[label(ast_passes_coroutine)]
+ #[label("`{$coroutine_kind}` because of this")]
pub coroutine_span: Span,
- #[label]
+ #[label("{\"\"}")]
pub span: Span,
pub coroutine_kind: &'static str,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_const_and_c_variadic)]
+#[diag("functions cannot be both `const` and C-variadic")]
pub(crate) struct ConstAndCVariadic {
#[primary_span]
pub spans: Vec,
- #[label(ast_passes_const)]
+ #[label("`const` because of this")]
pub const_span: Span,
- #[label(ast_passes_variadic)]
+ #[label("C-variadic because of this")]
pub variadic_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_coroutine_and_c_variadic)]
+#[diag("functions cannot be both `{$coroutine_kind}` and C-variadic")]
pub(crate) struct CoroutineAndCVariadic {
#[primary_span]
pub spans: Vec,
pub coroutine_kind: &'static str,
- #[label(ast_passes_const)]
+ #[label("`{$coroutine_kind}` because of this")]
pub coroutine_span: Span,
- #[label(ast_passes_variadic)]
+ #[label("C-variadic because of this")]
pub variadic_span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_c_variadic_not_supported)]
+#[diag("the `{$target}` target does not support c-variadic functions")]
pub(crate) struct CVariadicNotSupported<'a> {
#[primary_span]
pub variadic_span: Span,
@@ -742,29 +855,29 @@ pub(crate) struct CVariadicNotSupported<'a> {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_pattern_in_foreign, code = E0130)]
+#[diag("patterns aren't allowed in foreign function declarations", code = E0130)]
// FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`)
pub(crate) struct PatternInForeign {
#[primary_span]
- #[label]
+ #[label("pattern not allowed in foreign function")]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_pattern_in_bodiless, code = E0642)]
+#[diag("patterns aren't allowed in functions without bodies", code = E0642)]
// FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`)
pub(crate) struct PatternInBodiless {
#[primary_span]
- #[label]
+ #[label("pattern not allowed in function without body")]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_equality_in_where)]
-#[note]
+#[diag("equality constraints are not yet supported in `where` clauses")]
+#[note("see issue #20041 for more information")]
pub(crate) struct EqualityInWhere {
#[primary_span]
- #[label]
+ #[label("not supported")]
pub span: Span,
#[subdiagnostic]
pub assoc: Option,
@@ -774,7 +887,7 @@ pub(crate) struct EqualityInWhere {
#[derive(Subdiagnostic)]
#[suggestion(
- ast_passes_suggestion,
+ "if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax",
code = "{param}: {path}",
style = "verbose",
applicability = "maybe-incorrect"
@@ -788,7 +901,10 @@ pub(crate) struct AssociatedSuggestion {
}
#[derive(Subdiagnostic)]
-#[multipart_suggestion(ast_passes_suggestion_path, applicability = "maybe-incorrect")]
+#[multipart_suggestion(
+ "if `{$trait_segment}::{$potential_assoc}` is an associated type you're trying to set, use the associated type binding syntax",
+ applicability = "maybe-incorrect"
+)]
pub(crate) struct AssociatedSuggestion2 {
#[suggestion_part(code = "{args}")]
pub span: Span,
@@ -800,33 +916,29 @@ pub(crate) struct AssociatedSuggestion2 {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_feature_on_non_nightly, code = E0554)]
+#[diag("`#![feature]` may not be used on the {$channel} release channel", code = E0554)]
pub(crate) struct FeatureOnNonNightly {
#[primary_span]
pub span: Span,
pub channel: &'static str,
#[subdiagnostic]
pub stable_features: Vec,
- #[suggestion(code = "", applicability = "machine-applicable")]
+ #[suggestion("remove the attribute", code = "", applicability = "machine-applicable")]
pub sugg: Option,
}
+#[derive(Subdiagnostic)]
+#[help(
+ "the feature `{$name}` has been stable since `{$since}` and no longer requires an attribute to enable"
+)]
pub(crate) struct StableFeature {
pub name: Symbol,
pub since: Symbol,
}
-impl Subdiagnostic for StableFeature {
- fn add_to_diag(self, diag: &mut Diag<'_, G>) {
- diag.arg("name", self.name);
- diag.arg("since", self.since);
- diag.help(fluent::ast_passes_stable_since);
- }
-}
-
#[derive(Diagnostic)]
-#[diag(ast_passes_incompatible_features)]
-#[help]
+#[diag("`{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed")]
+#[help("remove one of these features")]
pub(crate) struct IncompatibleFeatures {
#[primary_span]
pub spans: Vec,
@@ -835,28 +947,38 @@ pub(crate) struct IncompatibleFeatures {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_negative_bound_not_supported)]
+#[diag("`{$parent}` requires {$missing} to be enabled")]
+#[help("enable all of these features")]
+pub(crate) struct MissingDependentFeatures {
+ #[primary_span]
+ pub parent_span: Span,
+ pub parent: Symbol,
+ pub missing: String,
+}
+
+#[derive(Diagnostic)]
+#[diag("negative bounds are not supported")]
pub(crate) struct NegativeBoundUnsupported {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_constraint_on_negative_bound)]
+#[diag("associated type constraints not allowed on negative bounds")]
pub(crate) struct ConstraintOnNegativeBound {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_negative_bound_with_parenthetical_notation)]
+#[diag("parenthetical notation may not be used for negative bounds")]
pub(crate) struct NegativeBoundWithParentheticalNotation {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_match_arm_with_no_body)]
+#[diag("`match` arm with no body")]
pub(crate) struct MatchArmWithNoBody {
#[primary_span]
pub span: Span,
@@ -864,6 +986,7 @@ pub(crate) struct MatchArmWithNoBody {
// any logic looking at the arm being replaced if there was a comma already or not for the
// resulting code to be correct.
#[suggestion(
+ "add a body after the pattern",
code = " => {{ todo!() }}",
applicability = "has-placeholders",
style = "verbose"
@@ -872,7 +995,7 @@ pub(crate) struct MatchArmWithNoBody {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_precise_capturing_not_allowed_here)]
+#[diag("`use<...>` precise capturing syntax not allowed in {$loc}")]
pub(crate) struct PreciseCapturingNotAllowedHere {
#[primary_span]
pub span: Span,
@@ -880,39 +1003,43 @@ pub(crate) struct PreciseCapturingNotAllowedHere {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_precise_capturing_duplicated)]
+#[diag("duplicate `use<...>` precise capturing syntax")]
pub(crate) struct DuplicatePreciseCapturing {
#[primary_span]
pub bound1: Span,
- #[label]
+ #[label("second `use<...>` here")]
pub bound2: Span,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_extern_without_abi)]
-#[help]
+#[diag("`extern` declarations without an explicit ABI are disallowed")]
+#[help("prior to Rust 2024, a default ABI was inferred")]
pub(crate) struct MissingAbi {
#[primary_span]
- #[suggestion(code = "extern \"\"", applicability = "has-placeholders")]
+ #[suggestion("specify an ABI", code = "extern \"\"", applicability = "has-placeholders")]
pub span: Span,
}
#[derive(LintDiagnostic)]
-#[diag(ast_passes_extern_without_abi_sugg)]
+#[diag("`extern` declarations without an explicit ABI are deprecated")]
pub(crate) struct MissingAbiSugg {
- #[suggestion(code = "extern {default_abi}", applicability = "machine-applicable")]
+ #[suggestion(
+ "explicitly specify the {$default_abi} ABI",
+ code = "extern {default_abi}",
+ applicability = "machine-applicable"
+ )]
pub span: Span,
pub default_abi: ExternAbi,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_abi_custom_safe_foreign_function)]
+#[diag("foreign functions with the \"custom\" ABI cannot be safe")]
pub(crate) struct AbiCustomSafeForeignFunction {
#[primary_span]
pub span: Span,
#[suggestion(
- ast_passes_suggestion,
+ "remove the `safe` keyword from this definition",
applicability = "maybe-incorrect",
code = "",
style = "verbose"
@@ -921,14 +1048,14 @@ pub(crate) struct AbiCustomSafeForeignFunction {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_abi_custom_safe_function)]
+#[diag("functions with the \"custom\" ABI must be unsafe")]
pub(crate) struct AbiCustomSafeFunction {
#[primary_span]
pub span: Span,
pub abi: ExternAbi,
#[suggestion(
- ast_passes_suggestion,
+ "add the `unsafe` keyword to this definition",
applicability = "maybe-incorrect",
code = "unsafe ",
style = "verbose"
@@ -937,14 +1064,14 @@ pub(crate) struct AbiCustomSafeFunction {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_abi_cannot_be_coroutine)]
+#[diag("functions with the {$abi} ABI cannot be `{$coroutine_kind_str}`")]
pub(crate) struct AbiCannotBeCoroutine {
#[primary_span]
pub span: Span,
pub abi: ExternAbi,
#[suggestion(
- ast_passes_suggestion,
+ "remove the `{$coroutine_kind_str}` keyword from this definition",
applicability = "maybe-incorrect",
code = "",
style = "verbose"
@@ -954,15 +1081,15 @@ pub(crate) struct AbiCannotBeCoroutine {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_abi_must_not_have_parameters_or_return_type)]
-#[note]
+#[diag("invalid signature for `extern {$abi}` function")]
+#[note("functions with the {$abi} ABI cannot have any parameters or return type")]
pub(crate) struct AbiMustNotHaveParametersOrReturnType {
#[primary_span]
pub spans: Vec,
pub abi: ExternAbi,
#[suggestion(
- ast_passes_suggestion,
+ "remove the parameters and return type",
applicability = "maybe-incorrect",
code = "{padding}fn {symbol}()",
style = "verbose"
@@ -973,18 +1100,20 @@ pub(crate) struct AbiMustNotHaveParametersOrReturnType {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_abi_must_not_have_return_type)]
-#[note]
+#[diag("invalid signature for `extern {$abi}` function")]
+#[note("functions with the {$abi} ABI cannot have a return type")]
pub(crate) struct AbiMustNotHaveReturnType {
#[primary_span]
- #[help]
+ #[help("remove the return type")]
pub span: Span,
pub abi: ExternAbi,
}
#[derive(Diagnostic)]
-#[diag(ast_passes_abi_x86_interrupt)]
-#[note]
+#[diag("invalid signature for `extern \"x86-interrupt\"` function")]
+#[note(
+ "functions with the \"x86-interrupt\" ABI must be have either 1 or 2 parameters (but found {$param_count})"
+)]
pub(crate) struct AbiX86Interrupt {
#[primary_span]
pub spans: Vec,
@@ -992,7 +1121,7 @@ pub(crate) struct AbiX86Interrupt {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_scalable_vector_not_tuple_struct)]
+#[diag("scalable vectors must be tuple structs")]
pub(crate) struct ScalableVectorNotTupleStruct {
#[primary_span]
pub span: Span,
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 6376cab364db..4523b4c14163 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -1,5 +1,6 @@
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
use rustc_ast::{self as ast, AttrVec, NodeId, PatKind, attr, token};
+use rustc_errors::msg;
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Features};
use rustc_session::Session;
use rustc_session::parse::{feature_err, feature_warn};
@@ -124,7 +125,7 @@ impl<'a> PostExpansionVisitor<'a> {
&self,
non_lifetime_binders,
non_lt_param_spans,
- crate::fluent_generated::ast_passes_forbidden_non_lifetime_param
+ msg!("only lifetime parameters can be used in this context")
);
// FIXME(non_lifetime_binders): Const bound params are pretty broken.
@@ -248,6 +249,14 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
ast::ItemKind::TyAlias(box ast::TyAlias { ty: Some(ty), .. }) => {
self.check_impl_trait(ty, false)
}
+ ast::ItemKind::Const(box ast::ConstItem {
+ rhs_kind: ast::ConstItemRhsKind::TypeConst { .. },
+ ..
+ }) => {
+ // Make sure this is only allowed if the feature gate is enabled.
+ // #![feature(min_generic_const_args)]
+ gate!(&self, min_generic_const_args, i.span, "top-level `type const` are unstable");
+ }
_ => {}
}
@@ -329,15 +338,11 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_expr(&mut self, e: &'a ast::Expr) {
match e.kind {
ast::ExprKind::TryBlock(_, None) => {
+ // `try { ... }` is old and is only gated post-expansion here.
gate!(&self, try_blocks, e.span, "`try` expression is experimental");
}
ast::ExprKind::TryBlock(_, Some(_)) => {
- gate!(
- &self,
- try_blocks_heterogeneous,
- e.span,
- "`try bikeshed` expression is experimental"
- );
+ // `try_blocks_heterogeneous` is new, and gated pre-expansion instead.
}
ast::ExprKind::Lit(token::Lit {
kind: token::LitKind::Float | token::LitKind::Integer,
@@ -421,6 +426,20 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
false
}
+ ast::AssocItemKind::Const(box ast::ConstItem {
+ rhs_kind: ast::ConstItemRhsKind::TypeConst { .. },
+ ..
+ }) => {
+ // Make sure this is only allowed if the feature gate is enabled.
+ // #![feature(min_generic_const_args)]
+ gate!(
+ &self,
+ min_generic_const_args,
+ i.span,
+ "associated `type const` are unstable"
+ );
+ false
+ }
_ => false,
};
if let ast::Defaultness::Default(_) = i.kind.defaultness() {
@@ -440,6 +459,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
maybe_stage_features(sess, features, krate);
check_incompatible_features(sess, features);
+ check_dependent_features(sess, features);
check_new_solver_banned_features(sess, features);
let mut visitor = PostExpansionVisitor { sess, features };
@@ -498,6 +518,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
half_open_range_patterns_in_slices,
"half-open range patterns in slices are unstable"
);
+ gate_all!(try_blocks_heterogeneous, "`try bikeshed` expression is experimental");
gate_all!(yeet_expr, "`do yeet` expression is experimental");
gate_all!(const_closures, "const closures are experimental");
gate_all!(builtin_syntax, "`builtin #` syntax is unstable");
@@ -526,6 +547,27 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
}
}
}
+ // `mgca_type_const_syntax` is part of `min_generic_const_args` so either
+ // or both are enabled we don't need to emit a feature error.
+ if let Some(spans) = spans.get(&sym::mgca_type_const_syntax) {
+ for span in spans {
+ if visitor.features.min_generic_const_args()
+ || visitor.features.mgca_type_const_syntax()
+ || span.allows_unstable(sym::min_generic_const_args)
+ || span.allows_unstable(sym::mgca_type_const_syntax)
+ {
+ continue;
+ }
+ feature_err(
+ &visitor.sess,
+ sym::min_generic_const_args,
+ *span,
+ "`type const` syntax is experimental",
+ )
+ .emit();
+ }
+ }
+
gate_all!(global_registration, "global registration is experimental");
gate_all!(return_type_notation, "return type notation is experimental");
gate_all!(pin_ergonomics, "pinned reference syntax is experimental");
@@ -648,6 +690,27 @@ fn check_incompatible_features(sess: &Session, features: &Features) {
}
}
+fn check_dependent_features(sess: &Session, features: &Features) {
+ for &(parent, children) in
+ rustc_feature::DEPENDENT_FEATURES.iter().filter(|(parent, _)| features.enabled(*parent))
+ {
+ if children.iter().any(|f| !features.enabled(*f)) {
+ let parent_span = features
+ .enabled_features_iter_stable_order()
+ .find_map(|(name, span)| (name == parent).then_some(span))
+ .unwrap();
+ // FIXME: should probably format this in fluent instead of here
+ let missing = children
+ .iter()
+ .filter(|f| !features.enabled(**f))
+ .map(|s| format!("`{}`", s.as_str()))
+ .intersperse(String::from(", "))
+ .collect();
+ sess.dcx().emit_err(errors::MissingDependentFeatures { parent_span, parent, missing });
+ }
+ }
+}
+
fn check_new_solver_banned_features(sess: &Session, features: &Features) {
if !sess.opts.unstable_opts.next_solver.globally {
return;
diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs
index 06795a6be81e..7793f786cefe 100644
--- a/compiler/rustc_ast_passes/src/lib.rs
+++ b/compiler/rustc_ast_passes/src/lib.rs
@@ -5,11 +5,10 @@
// tidy-alphabetical-start
#![feature(box_patterns)]
#![feature(if_let_guard)]
+#![feature(iter_intersperse)]
#![feature(iter_is_partitioned)]
// tidy-alphabetical-end
pub mod ast_validation;
mod errors;
pub mod feature_gate;
-
-rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index e50e31c226fd..c8874ed99dca 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1961,7 +1961,8 @@ impl<'a> State<'a> {
}
fn print_lifetime(&mut self, lifetime: ast::Lifetime) {
- self.print_name(lifetime.ident.name)
+ self.word(lifetime.ident.name.to_string());
+ self.ann_post(lifetime.ident)
}
fn print_lifetime_bounds(&mut self, bounds: &ast::GenericBounds) {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index 68054b06e39f..c7f110a2e003 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -221,7 +221,7 @@ impl<'a> State<'a> {
ident,
generics,
ty,
- rhs,
+ rhs_kind,
define_opaque,
}) => {
self.print_item_const(
@@ -229,7 +229,7 @@ impl<'a> State<'a> {
None,
generics,
ty,
- rhs.as_ref().map(|ct| ct.expr()),
+ rhs_kind.expr(),
&item.vis,
ast::Safety::Default,
*defaultness,
@@ -573,7 +573,7 @@ impl<'a> State<'a> {
ident,
generics,
ty,
- rhs,
+ rhs_kind,
define_opaque,
}) => {
self.print_item_const(
@@ -581,7 +581,7 @@ impl<'a> State<'a> {
None,
generics,
ty,
- rhs.as_ref().map(|ct| ct.expr()),
+ rhs_kind.expr(),
vis,
ast::Safety::Default,
*defaultness,
diff --git a/compiler/rustc_attr_parsing/Cargo.toml b/compiler/rustc_attr_parsing/Cargo.toml
index 79193f394fe4..0a11a2da0dcf 100644
--- a/compiler/rustc_attr_parsing/Cargo.toml
+++ b/compiler/rustc_attr_parsing/Cargo.toml
@@ -8,9 +8,9 @@ edition = "2024"
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
+rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
-rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hir = { path = "../rustc_hir" }
rustc_lexer = { path = "../rustc_lexer" }
rustc_macros = { path = "../rustc_macros" }
diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl
deleted file mode 100644
index 3e4c1a9dfad8..000000000000
--- a/compiler/rustc_attr_parsing/messages.ftl
+++ /dev/null
@@ -1,246 +0,0 @@
-attr_parsing_as_needed_compatibility =
- linking modifier `as-needed` is only compatible with `dylib`, `framework` and `raw-dylib` linking kinds
-
-attr_parsing_bundle_needs_static =
- linking modifier `bundle` is only compatible with `static` linking kind
-
-attr_parsing_cfg_attr_bad_delim = wrong `cfg_attr` delimiters
-
-attr_parsing_deprecated_item_suggestion =
- suggestions on deprecated items are unstable
- .help = add `#![feature(deprecated_suggestion)]` to the crate root
- .note = see #94785 for more details
-
-attr_parsing_doc_alias_bad_char =
- {$char_} character isn't allowed in {$attr_str}
-
-attr_parsing_doc_alias_empty =
- {$attr_str} attribute cannot have empty value
-
-attr_parsing_doc_alias_malformed =
- doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]`
-
-attr_parsing_doc_alias_start_end =
- {$attr_str} cannot start or end with ' '
-
-attr_parsing_doc_attr_not_crate_level =
- `#![doc({$attr_name} = "...")]` isn't allowed as a crate-level attribute
-
-attr_parsing_doc_attribute_not_attribute =
- nonexistent builtin attribute `{$attribute}` used in `#[doc(attribute = "...")]`
- .help = only existing builtin attributes are allowed in core/std
-
-attr_parsing_doc_keyword_not_keyword =
- nonexistent keyword `{$keyword}` used in `#[doc(keyword = "...")]`
- .help = only existing keywords are allowed in core/std
-
-attr_parsing_empty_confusables =
- expected at least one confusable name
-
-attr_parsing_empty_link_name =
- link name must not be empty
- .label = empty link name
-
-attr_parsing_expected_single_version_literal =
- expected single version literal
-
-attr_parsing_expected_version_literal =
- expected a version literal
-
-attr_parsing_expects_feature_list =
- `{$name}` expects a list of feature names
-
-attr_parsing_expects_features =
- `{$name}` expects feature names
-
-attr_parsing_import_name_type_raw =
- import name type can only be used with link kind `raw-dylib`
-
-attr_parsing_import_name_type_x86 =
- import name type is only supported on x86
-
-attr_parsing_incompatible_wasm_link =
- `wasm_import_module` is incompatible with other arguments in `#[link]` attributes
-
-attr_parsing_incorrect_repr_format_align_one_arg =
- incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
-
-attr_parsing_incorrect_repr_format_expect_literal_integer =
- incorrect `repr(align)` attribute format: `align` expects a literal integer as argument
-
-attr_parsing_incorrect_repr_format_generic =
- incorrect `repr({$repr_arg})` attribute format
- .suggestion = use parentheses instead
-
-attr_parsing_incorrect_repr_format_packed_expect_integer =
- incorrect `repr(packed)` attribute format: `packed` expects a literal integer as argument
-
-attr_parsing_incorrect_repr_format_packed_one_or_zero_arg =
- incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all
-
-attr_parsing_invalid_alignment_value =
- invalid alignment value: {$error_part}
-
-attr_parsing_invalid_attr_unsafe = `{$name}` is not an unsafe attribute
- .label = this is not an unsafe attribute
- .suggestion = remove the `unsafe(...)`
- .note = extraneous unsafe is not allowed in attributes
-
-attr_parsing_invalid_issue_string =
- `issue` must be a non-zero numeric string or "none"
- .must_not_be_zero = `issue` must not be "0", use "none" instead
- .empty = cannot parse integer from empty string
- .invalid_digit = invalid digit found in string
- .pos_overflow = number too large to fit in target type
- .neg_overflow = number too small to fit in target type
-
-attr_parsing_invalid_link_modifier =
- invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed
-
-attr_parsing_invalid_meta_item = expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found {$descr}
- .remove_neg_sugg = negative numbers are not literals, try removing the `-` sign
- .quote_ident_sugg = surround the identifier with quotation marks to make it into a string literal
- .label = {$descr}s are not allowed here
-
-attr_parsing_invalid_predicate =
- invalid predicate `{$predicate}`
-
-attr_parsing_invalid_repr_align_need_arg =
- invalid `repr(align)` attribute: `align` needs an argument
- .suggestion = supply an argument here
-
-attr_parsing_invalid_repr_generic =
- invalid `repr({$repr_arg})` attribute: {$error_part}
-
-attr_parsing_invalid_repr_hint_no_paren =
- invalid representation hint: `{$name}` does not take a parenthesized argument list
-
-attr_parsing_invalid_repr_hint_no_value =
- invalid representation hint: `{$name}` does not take a value
-
-attr_parsing_invalid_since =
- 'since' must be a Rust version number, such as "1.31.0"
-
-attr_parsing_invalid_target = `#[{$name}]` attribute cannot be used on {$target}
- .help = `#[{$name}]` can {$only}be applied to {$applied}
- .suggestion = remove the attribute
-
-attr_parsing_limit_invalid =
- `limit` must be a non-negative integer
- .label = {$error_str}
-attr_parsing_link_arg_unstable =
- link kind `link-arg` is unstable
-
-attr_parsing_link_cfg_unstable =
- link cfg is unstable
-
-attr_parsing_link_framework_apple =
- link kind `framework` is only supported on Apple targets
-
-attr_parsing_link_ordinal_out_of_range = ordinal value in `link_ordinal` is too large: `{$ordinal}`
- .note = the value may not exceed `u16::MAX`
-
-attr_parsing_link_requires_name =
- `#[link]` attribute requires a `name = "string"` argument
- .label = missing `name` argument
-
-attr_parsing_meta_bad_delim = wrong meta list delimiters
-attr_parsing_meta_bad_delim_suggestion = the delimiters should be `(` and `)`
-
-attr_parsing_missing_feature =
- missing 'feature'
-
-attr_parsing_missing_issue =
- missing 'issue'
-
-attr_parsing_missing_note =
- missing 'note'
-
-attr_parsing_missing_since =
- missing 'since'
-
-attr_parsing_multiple_modifiers =
- multiple `{$modifier}` modifiers in a single `modifiers` argument
-
-attr_parsing_multiple_stability_levels =
- multiple stability levels
-
-attr_parsing_naked_functions_incompatible_attribute =
- attribute incompatible with `#[unsafe(naked)]`
- .label = the `{$attr}` attribute is incompatible with `#[unsafe(naked)]`
- .naked_attribute = function marked with `#[unsafe(naked)]` here
-
-attr_parsing_non_ident_feature =
- 'feature' is not an identifier
-
-attr_parsing_null_on_export = `export_name` may not contain null characters
-
-attr_parsing_null_on_link_section = `link_section` may not contain null characters
-
-attr_parsing_null_on_objc_class = `objc::class!` may not contain null characters
-
-attr_parsing_null_on_objc_selector = `objc::selector!` may not contain null characters
-
-attr_parsing_objc_class_expected_string_literal = `objc::class!` expected a string literal
-
-attr_parsing_objc_selector_expected_string_literal = `objc::selector!` expected a string literal
-
-attr_parsing_raw_dylib_elf_unstable =
- link kind `raw-dylib` is unstable on ELF platforms
-
-attr_parsing_raw_dylib_no_nul =
- link name must not contain NUL characters if link kind is `raw-dylib`
-
-attr_parsing_raw_dylib_only_windows =
- link kind `raw-dylib` is only supported on Windows targets
-
-attr_parsing_repr_ident =
- meta item in `repr` must be an identifier
-
-attr_parsing_rustc_allowed_unstable_pairing =
- `rustc_allowed_through_unstable_modules` attribute must be paired with a `stable` attribute
-
-attr_parsing_rustc_promotable_pairing =
- `rustc_promotable` attribute must be paired with either a `rustc_const_unstable` or a `rustc_const_stable` attribute
-
-attr_parsing_rustc_scalable_vector_count_out_of_range = element count in `rustc_scalable_vector` is too large: `{$n}`
- .note = the value may not exceed `u16::MAX`
-
-attr_parsing_soft_no_args =
- `soft` should not have any arguments
-
-attr_parsing_stability_outside_std = stability attributes may not be used outside of the standard library
-
-attr_parsing_suffixed_literal_in_attribute = suffixed literals are not allowed in attributes
- .help = instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
-
-attr_parsing_unknown_version_literal =
- unknown version literal format, assuming it refers to a future version
-
-attr_parsing_unrecognized_repr_hint =
- unrecognized representation hint
- .help = valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
- .note = for more information, visit
-
-attr_parsing_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe
- .label = usage of unsafe attribute
-attr_parsing_unsafe_attr_outside_unsafe_suggestion = wrap the attribute in `unsafe(...)`
-
-attr_parsing_unstable_cfg_target_compact =
- compact `cfg(target(..))` is experimental and subject to change
-
-attr_parsing_unstable_feature_bound_incompatible_stability = item annotated with `#[unstable_feature_bound]` should not be stable
- .help = if this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]`
-
-attr_parsing_unsupported_instruction_set = target `{$current_target}` does not support `#[instruction_set({$instruction_set}::*)]`
-
-attr_parsing_unsupported_literal_suggestion =
- consider removing the prefix
-
-attr_parsing_unused_multiple =
- multiple `{$name}` attributes
- .suggestion = remove this attribute
- .note = attribute also specified here
-
-attr_parsing_whole_archive_needs_static =
- linking modifier `whole-archive` is only compatible with `static` linking kind
diff --git a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs
index 7323db06a8f1..4f1a8cd8b403 100644
--- a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs
@@ -29,7 +29,7 @@ impl CombineAttributeParser for AllowInternalUnstableParser {
pub(crate) struct UnstableFeatureBoundParser;
impl CombineAttributeParser for UnstableFeatureBoundParser {
- const PATH: &'static [rustc_span::Symbol] = &[sym::unstable_feature_bound];
+ const PATH: &[rustc_span::Symbol] = &[sym::unstable_feature_bound];
type Item = (Symbol, Span);
const CONVERT: ConvertFn = |items, _| AttributeKind::UnstableFeatureBound(items);
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
@@ -57,7 +57,7 @@ impl CombineAttributeParser for AllowConstFnUnstableParser {
const PATH: &[Symbol] = &[sym::rustc_allow_const_fn_unstable];
type Item = Symbol;
const CONVERT: ConvertFn =
- |items, first_span| AttributeKind::AllowConstFnUnstable(items, first_span);
+ |items, first_span| AttributeKind::RustcAllowConstFnUnstable(items, first_span);
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs
index 3a540d80998d..d2f743f6c5d8 100644
--- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs
@@ -3,14 +3,14 @@ use std::convert::identity;
use rustc_ast::token::Delimiter;
use rustc_ast::tokenstream::DelimSpan;
use rustc_ast::{AttrItem, Attribute, CRATE_NODE_ID, LitKind, ast, token};
-use rustc_errors::{Applicability, PResult};
+use rustc_errors::{Applicability, PResult, msg};
use rustc_feature::{
AttrSuggestionStyle, AttributeTemplate, Features, GatedCfg, find_gated_cfg, template,
};
use rustc_hir::attrs::CfgEntry;
use rustc_hir::lints::AttributeLintKind;
use rustc_hir::{AttrPath, RustcVersion, Target};
-use rustc_parse::parser::{ForceCollect, Parser};
+use rustc_parse::parser::{ForceCollect, Parser, Recovery};
use rustc_parse::{exp, parse_in};
use rustc_session::Session;
use rustc_session::config::ExpectedValues;
@@ -25,7 +25,7 @@ use crate::session_diagnostics::{
AttributeParseError, AttributeParseErrorReason, CfgAttrBadDelim, MetaBadDelimSugg,
ParsedDescription,
};
-use crate::{AttributeParser, fluent_generated, parse_version, session_diagnostics};
+use crate::{AttributeParser, parse_version, session_diagnostics};
pub const CFG_TEMPLATE: AttributeTemplate = template!(
List: &["predicate"],
@@ -141,7 +141,7 @@ fn parse_cfg_entry_target(
cx.sess(),
sym::cfg_target_compact,
meta_span,
- fluent_generated::attr_parsing_unstable_cfg_target_compact,
+ msg!("compact `cfg(target(..))` is experimental and subject to change"),
)
.emit();
}
@@ -360,8 +360,10 @@ fn parse_cfg_attr_internal<'a>(
) -> PResult<'a, (CfgEntry, Vec<(ast::AttrItem, Span)>)> {
// Parse cfg predicate
let pred_start = parser.token.span;
- let meta =
- MetaItemOrLitParser::parse_single(parser, ShouldEmit::ErrorsAndLints { recover: true })?;
+ let meta = MetaItemOrLitParser::parse_single(
+ parser,
+ ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed },
+ )?;
let pred_span = pred_start.with_hi(parser.token.span.hi());
let cfg_predicate = AttributeParser::parse_single_args(
@@ -376,7 +378,7 @@ fn parse_cfg_attr_internal<'a>(
CRATE_NODE_ID,
Target::Crate,
features,
- ShouldEmit::ErrorsAndLints { recover: true },
+ ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed },
&meta,
parse_cfg_entry,
&CFG_ATTR_TEMPLATE,
diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs
index ca844758daaa..b6cb5b4504ee 100644
--- a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs
@@ -1,22 +1,35 @@
use rustc_ast::token::Token;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::{AttrStyle, NodeId, token};
+use rustc_data_structures::fx::FxHashMap;
use rustc_feature::{AttributeTemplate, Features};
use rustc_hir::attrs::CfgEntry;
use rustc_hir::{AttrPath, Target};
use rustc_parse::exp;
-use rustc_parse::parser::Parser;
+use rustc_parse::parser::{Parser, Recovery};
use rustc_session::Session;
-use rustc_span::{ErrorGuaranteed, Span, sym};
+use rustc_session::lint::BuiltinLintDiag;
+use rustc_session::lint::builtin::UNREACHABLE_CFG_SELECT_PREDICATES;
+use rustc_span::{ErrorGuaranteed, Span, Symbol, sym};
use crate::parser::MetaItemOrLitParser;
use crate::{AttributeParser, ParsedDescription, ShouldEmit, parse_cfg_entry};
+#[derive(Clone)]
pub enum CfgSelectPredicate {
Cfg(CfgEntry),
Wildcard(Token),
}
+impl CfgSelectPredicate {
+ fn span(&self) -> Span {
+ match self {
+ CfgSelectPredicate::Cfg(cfg_entry) => cfg_entry.span(),
+ CfgSelectPredicate::Wildcard(token) => token.span,
+ }
+ }
+}
+
#[derive(Default)]
pub struct CfgSelectBranches {
/// All the conditional branches.
@@ -78,9 +91,11 @@ pub fn parse_cfg_select(
}
}
} else {
- let meta =
- MetaItemOrLitParser::parse_single(p, ShouldEmit::ErrorsAndLints { recover: true })
- .map_err(|diag| diag.emit())?;
+ let meta = MetaItemOrLitParser::parse_single(
+ p,
+ ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed },
+ )
+ .map_err(|diag| diag.emit())?;
let cfg_span = meta.span();
let cfg = AttributeParser::parse_single_args(
sess,
@@ -95,7 +110,7 @@ pub fn parse_cfg_select(
// Doesn't matter what the target actually is here.
Target::Crate,
features,
- ShouldEmit::ErrorsAndLints { recover: true },
+ ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed },
&meta,
parse_cfg_entry,
&AttributeTemplate::default(),
@@ -113,5 +128,102 @@ pub fn parse_cfg_select(
}
}
+ if let Some(features) = features
+ && features.enabled(sym::cfg_select)
+ {
+ let it = branches
+ .reachable
+ .iter()
+ .map(|(entry, _, _)| CfgSelectPredicate::Cfg(entry.clone()))
+ .chain(branches.wildcard.as_ref().map(|(t, _, _)| CfgSelectPredicate::Wildcard(*t)))
+ .chain(
+ branches.unreachable.iter().map(|(entry, _, _)| CfgSelectPredicate::clone(entry)),
+ );
+
+ lint_unreachable(p, it, lint_node_id);
+ }
+
Ok(branches)
}
+
+fn lint_unreachable(
+ p: &mut Parser<'_>,
+ predicates: impl Iterator- ,
+ lint_node_id: NodeId,
+) {
+ // Symbols that have a known value.
+ let mut known = FxHashMap::
::default();
+ let mut wildcard_span = None;
+ let mut it = predicates;
+
+ let branch_is_unreachable = |predicate: CfgSelectPredicate, wildcard_span| {
+ let span = predicate.span();
+ p.psess.buffer_lint(
+ UNREACHABLE_CFG_SELECT_PREDICATES,
+ span,
+ lint_node_id,
+ BuiltinLintDiag::UnreachableCfg { span, wildcard_span },
+ );
+ };
+
+ for predicate in &mut it {
+ let CfgSelectPredicate::Cfg(ref cfg_entry) = predicate else {
+ wildcard_span = Some(predicate.span());
+ break;
+ };
+
+ match cfg_entry {
+ CfgEntry::Bool(true, _) => {
+ wildcard_span = Some(predicate.span());
+ break;
+ }
+ CfgEntry::Bool(false, _) => continue,
+ CfgEntry::NameValue { name, value, .. } => match value {
+ None => {
+ // `name` will be false in all subsequent branches.
+ let current = known.insert(*name, false);
+
+ match current {
+ None => continue,
+ Some(false) => {
+ branch_is_unreachable(predicate, None);
+ break;
+ }
+ Some(true) => {
+ // this branch will be taken, so all subsequent branches are unreachable.
+ break;
+ }
+ }
+ }
+ Some(_) => { /* for now we don't bother solving these */ }
+ },
+ CfgEntry::Not(inner, _) => match &**inner {
+ CfgEntry::NameValue { name, value: None, .. } => {
+ // `name` will be true in all subsequent branches.
+ let current = known.insert(*name, true);
+
+ match current {
+ None => continue,
+ Some(true) => {
+ branch_is_unreachable(predicate, None);
+ break;
+ }
+ Some(false) => {
+ // this branch will be taken, so all subsequent branches are unreachable.
+ break;
+ }
+ }
+ }
+ _ => { /* for now we don't bother solving these */ }
+ },
+ CfgEntry::All(_, _) | CfgEntry::Any(_, _) => {
+ /* for now we don't bother solving these */
+ }
+ CfgEntry::Version(..) => { /* don't bother solving these */ }
+ }
+ }
+
+ for predicate in it {
+ branch_is_unreachable(predicate, wildcard_span)
+ }
+}
diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
index 063fa12d3896..485307622291 100644
--- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
@@ -181,7 +181,7 @@ impl SingleAttributeParser for ObjcClassParser {
cx.emit_err(NullOnObjcClass { span: nv.value_span });
return None;
}
- Some(AttributeKind::ObjcClass { classname, span: cx.attr_span })
+ Some(AttributeKind::RustcObjcClass { classname, span: cx.attr_span })
}
}
@@ -213,7 +213,7 @@ impl SingleAttributeParser for ObjcSelectorParser {
cx.emit_err(NullOnObjcSelector { span: nv.value_span });
return None;
}
- Some(AttributeKind::ObjcSelector { methname, span: cx.attr_span })
+ Some(AttributeKind::RustcObjcSelector { methname, span: cx.attr_span })
}
}
diff --git a/compiler/rustc_attr_parsing/src/attributes/confusables.rs b/compiler/rustc_attr_parsing/src/attributes/confusables.rs
index 0b7ac989346a..1897fed1e250 100644
--- a/compiler/rustc_attr_parsing/src/attributes/confusables.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/confusables.rs
@@ -43,7 +43,7 @@ impl AttributeParser for ConfusablesParser {
return None;
}
- Some(AttributeKind::Confusables {
+ Some(AttributeKind::RustcConfusables {
symbols: self.confusables,
first_span: self.first_span.unwrap(),
})
diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs
index a367e699fcb9..bdfe7bfb8f1f 100644
--- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs
@@ -274,3 +274,21 @@ impl NoArgsAttributeParser for NoBuiltinsParser {
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoBuiltins;
}
+
+pub(crate) struct RustcPreserveUbChecksParser;
+
+impl NoArgsAttributeParser for RustcPreserveUbChecksParser {
+ const PATH: &[Symbol] = &[sym::rustc_preserve_ub_checks];
+ const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
+ const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
+ const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcPreserveUbChecks;
+}
+
+pub(crate) struct RustcNoImplicitBoundsParser;
+
+impl NoArgsAttributeParser for RustcNoImplicitBoundsParser {
+ const PATH: &[Symbol] = &[sym::rustc_no_implicit_bounds];
+ const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
+ const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
+ const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoImplicitBounds;
+}
diff --git a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs
index e01377d247bb..c055c2936e95 100644
--- a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs
@@ -1,4 +1,5 @@
use rustc_hir::attrs::{DeprecatedSince, Deprecation};
+use rustc_hir::{RustcVersion, VERSION_PLACEHOLDER};
use super::prelude::*;
use super::util::parse_version;
@@ -143,6 +144,8 @@ impl SingleAttributeParser for DeprecationParser {
DeprecatedSince::Future
} else if !is_rustc {
DeprecatedSince::NonStandard(since)
+ } else if since.as_str() == VERSION_PLACEHOLDER {
+ DeprecatedSince::RustcVersion(RustcVersion::CURRENT)
} else if let Some(version) = parse_version(since) {
DeprecatedSince::RustcVersion(version)
} else {
diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs
index a287c0c5a930..f8968639f98c 100644
--- a/compiler/rustc_attr_parsing/src/attributes/doc.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs
@@ -70,6 +70,42 @@ fn check_attr_crate_level(cx: &mut AcceptContext<'_, '_, S>, span: Spa
true
}
+// FIXME: To be removed once merged and replace with `cx.expected_name_value(span, _name)`.
+fn expected_name_value(
+ cx: &mut AcceptContext<'_, '_, S>,
+ span: Span,
+ _name: Option,
+) {
+ cx.emit_lint(
+ rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
+ AttributeLintKind::ExpectedNameValue,
+ span,
+ );
+}
+
+// FIXME: remove this method once merged and use `cx.expected_no_args(span)` instead.
+fn expected_no_args(cx: &mut AcceptContext<'_, '_, S>, span: Span) {
+ cx.emit_lint(
+ rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
+ AttributeLintKind::ExpectedNoArgs,
+ span,
+ );
+}
+
+// FIXME: remove this method once merged and use `cx.expected_no_args(span)` instead.
+// cx.expected_string_literal(span, _actual_literal);
+fn expected_string_literal(
+ cx: &mut AcceptContext<'_, '_, S>,
+ span: Span,
+ _actual_literal: Option<&MetaItemLit>,
+) {
+ cx.emit_lint(
+ rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
+ AttributeLintKind::MalformedDoc,
+ span,
+ );
+}
+
fn parse_keyword_and_attribute(
cx: &mut AcceptContext<'_, '_, S>,
path: &OwnedPathParser,
@@ -78,12 +114,12 @@ fn parse_keyword_and_attribute(
attr_name: Symbol,
) {
let Some(nv) = args.name_value() else {
- cx.expected_name_value(args.span().unwrap_or(path.span()), path.word_sym());
+ expected_name_value(cx, args.span().unwrap_or(path.span()), path.word_sym());
return;
};
let Some(value) = nv.value_as_str() else {
- cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
+ expected_string_literal(cx, nv.value_span, Some(nv.value_as_lit()));
return;
};
@@ -127,12 +163,21 @@ impl DocParser {
match path.word_sym() {
Some(sym::no_crate_inject) => {
if let Err(span) = args.no_args() {
- cx.expected_no_args(span);
+ expected_no_args(cx, span);
return;
}
- if self.attribute.no_crate_inject.is_some() {
- cx.duplicate_key(path.span(), sym::no_crate_inject);
+ if let Some(used_span) = self.attribute.no_crate_inject {
+ let unused_span = path.span();
+ cx.emit_lint(
+ rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
+ AttributeLintKind::UnusedDuplicate {
+ this: unused_span,
+ other: used_span,
+ warning: true,
+ },
+ unused_span,
+ );
return;
}
@@ -144,7 +189,14 @@ impl DocParser {
}
Some(sym::attr) => {
let Some(list) = args.list() else {
- cx.expected_list(cx.attr_span, args);
+ // FIXME: remove this method once merged and uncomment the line below instead.
+ // cx.expected_list(cx.attr_span, args);
+ let span = cx.attr_span;
+ cx.emit_lint(
+ rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
+ AttributeLintKind::MalformedDoc,
+ span,
+ );
return;
};
@@ -246,7 +298,7 @@ impl DocParser {
inline: DocInline,
) {
if let Err(span) = args.no_args() {
- cx.expected_no_args(span);
+ expected_no_args(cx, span);
return;
}
@@ -328,7 +380,14 @@ impl DocParser {
match sub_item.args() {
a @ (ArgParser::NoArgs | ArgParser::NameValue(_)) => {
let Some(name) = sub_item.path().word_sym() else {
- cx.expected_identifier(sub_item.path().span());
+ // FIXME: remove this method once merged and uncomment the line
+ // below instead.
+ // cx.expected_identifier(sub_item.path().span());
+ cx.emit_lint(
+ rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
+ AttributeLintKind::MalformedDoc,
+ sub_item.path().span(),
+ );
continue;
};
if let Ok(CfgEntry::NameValue { name, value, .. }) =
@@ -391,7 +450,7 @@ impl DocParser {
macro_rules! no_args {
($ident: ident) => {{
if let Err(span) = args.no_args() {
- cx.expected_no_args(span);
+ expected_no_args(cx, span);
return;
}
@@ -410,7 +469,7 @@ impl DocParser {
macro_rules! no_args_and_not_crate_level {
($ident: ident) => {{
if let Err(span) = args.no_args() {
- cx.expected_no_args(span);
+ expected_no_args(cx, span);
return;
}
let span = path.span();
@@ -423,7 +482,7 @@ impl DocParser {
macro_rules! no_args_and_crate_level {
($ident: ident) => {{
if let Err(span) = args.no_args() {
- cx.expected_no_args(span);
+ expected_no_args(cx, span);
return;
}
let span = path.span();
@@ -436,12 +495,12 @@ impl DocParser {
macro_rules! string_arg_and_crate_level {
($ident: ident) => {{
let Some(nv) = args.name_value() else {
- cx.expected_name_value(args.span().unwrap_or(path.span()), path.word_sym());
+ expected_name_value(cx, args.span().unwrap_or(path.span()), path.word_sym());
return;
};
let Some(s) = nv.value_as_str() else {
- cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
+ expected_string_literal(cx, nv.value_span, Some(nv.value_as_lit()));
return;
};
@@ -512,7 +571,14 @@ impl DocParser {
self.parse_single_test_doc_attr_item(cx, mip);
}
MetaItemOrLitParser::Lit(lit) => {
- cx.unexpected_literal(lit.span);
+ // FIXME: remove this method once merged and uncomment the line
+ // below instead.
+ // cx.unexpected_literal(lit.span);
+ cx.emit_lint(
+ rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
+ AttributeLintKind::MalformedDoc,
+ lit.span,
+ );
}
}
}
@@ -582,7 +648,7 @@ impl DocParser {
let suggestions = cx.suggestions();
let span = cx.attr_span;
cx.emit_lint(
- rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT,
+ rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
AttributeLintKind::IllFormedAttributeInput { suggestions, docs: None },
span,
);
@@ -595,14 +661,14 @@ impl DocParser {
self.parse_single_doc_attr_item(cx, mip);
}
MetaItemOrLitParser::Lit(lit) => {
- cx.expected_name_value(lit.span, None);
+ expected_name_value(cx, lit.span, None);
}
}
}
}
ArgParser::NameValue(nv) => {
if nv.value_as_str().is_none() {
- cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
+ expected_string_literal(cx, nv.value_span, Some(nv.value_as_lit()));
} else {
unreachable!(
"Should have been handled at the same time as sugar-syntaxed doc comments"
diff --git a/compiler/rustc_attr_parsing/src/attributes/dummy.rs b/compiler/rustc_attr_parsing/src/attributes/dummy.rs
index 0a7d95f31799..9f97af48afa0 100644
--- a/compiler/rustc_attr_parsing/src/attributes/dummy.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/dummy.rs
@@ -16,6 +16,6 @@ impl SingleAttributeParser for DummyParser {
const TEMPLATE: AttributeTemplate = template!(Word); // Anything, really
fn convert(_: &mut AcceptContext<'_, '_, S>, _: &ArgParser) -> Option {
- Some(AttributeKind::Dummy)
+ Some(AttributeKind::RustcDummy)
}
}
diff --git a/compiler/rustc_attr_parsing/src/attributes/inline.rs b/compiler/rustc_attr_parsing/src/attributes/inline.rs
index f6aab9ea0ee2..767200bfa9bf 100644
--- a/compiler/rustc_attr_parsing/src/attributes/inline.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/inline.rs
@@ -10,7 +10,7 @@ use super::prelude::*;
pub(crate) struct InlineParser;
impl SingleAttributeParser for InlineParser {
- const PATH: &'static [Symbol] = &[sym::inline];
+ const PATH: &[Symbol] = &[sym::inline];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
@@ -67,7 +67,7 @@ impl SingleAttributeParser for InlineParser {
pub(crate) struct RustcForceInlineParser;
impl SingleAttributeParser for RustcForceInlineParser {
- const PATH: &'static [Symbol] = &[sym::rustc_force_inline];
+ const PATH: &[Symbol] = &[sym::rustc_force_inline];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
index a636b449ca56..21c05611ce29 100644
--- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
@@ -1,3 +1,4 @@
+use rustc_errors::msg;
use rustc_feature::Features;
use rustc_hir::attrs::AttributeKind::{LinkName, LinkOrdinal, LinkSection};
use rustc_hir::attrs::*;
@@ -10,12 +11,11 @@ use rustc_target::spec::{Arch, BinaryFormat};
use super::prelude::*;
use super::util::parse_single_integer;
use crate::attributes::cfg::parse_cfg_entry;
-use crate::fluent_generated;
use crate::session_diagnostics::{
- AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ImportNameTypeRaw, ImportNameTypeX86,
- IncompatibleWasmLink, InvalidLinkModifier, LinkFrameworkApple, LinkOrdinalOutOfRange,
- LinkRequiresName, MultipleModifiers, NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows,
- WholeArchiveNeedsStatic,
+ AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ExportSymbolsNeedsStatic,
+ ImportNameTypeRaw, ImportNameTypeX86, IncompatibleWasmLink, InvalidLinkModifier,
+ LinkFrameworkApple, LinkOrdinalOutOfRange, LinkRequiresName, MultipleModifiers,
+ NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows, WholeArchiveNeedsStatic,
};
pub(crate) struct LinkNameParser;
@@ -165,6 +165,14 @@ impl CombineAttributeParser for LinkParser {
cx.emit_err(BundleNeedsStatic { span });
}
+ (sym::export_symbols, Some(NativeLibKind::Static { export_symbols, .. })) => {
+ assign_modifier(export_symbols)
+ }
+
+ (sym::export_symbols, _) => {
+ cx.emit_err(ExportSymbolsNeedsStatic { span });
+ }
+
(sym::verbatim, _) => assign_modifier(&mut verbatim),
(
@@ -190,6 +198,7 @@ impl CombineAttributeParser for LinkParser {
span,
&[
sym::bundle,
+ sym::export_symbols,
sym::verbatim,
sym::whole_dash_archive,
sym::as_dash_needed,
@@ -285,7 +294,9 @@ impl LinkParser {
};
let link_kind = match link_kind {
- kw::Static => NativeLibKind::Static { bundle: None, whole_archive: None },
+ kw::Static => {
+ NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }
+ }
sym::dylib => NativeLibKind::Dylib { as_needed: None },
sym::framework => {
if !sess.target.is_like_darwin {
@@ -305,7 +316,7 @@ impl LinkParser {
sess,
sym::raw_dylib_elf,
nv.value_span,
- fluent_generated::attr_parsing_raw_dylib_elf_unstable,
+ msg!("link kind `raw-dylib` is unstable on ELF platforms"),
)
.emit();
} else {
@@ -320,7 +331,7 @@ impl LinkParser {
sess,
sym::link_arg_attribute,
nv.value_span,
- fluent_generated::attr_parsing_link_arg_unstable,
+ msg!("link kind `link-arg` is unstable"),
)
.emit();
}
@@ -385,13 +396,7 @@ impl LinkParser {
return true;
};
if !features.link_cfg() {
- feature_err(
- sess,
- sym::link_cfg,
- item.span(),
- fluent_generated::attr_parsing_link_cfg_unstable,
- )
- .emit();
+ feature_err(sess, sym::link_cfg, item.span(), msg!("link cfg is unstable")).emit();
}
*cfg = parse_cfg_entry(cx, link_cfg).ok();
true
@@ -529,7 +534,7 @@ impl NoArgsAttributeParser for StdInternalSymbolParser {
Allow(Target::Static),
Allow(Target::ForeignStatic),
]);
- const CREATE: fn(Span) -> AttributeKind = AttributeKind::StdInternalSymbol;
+ const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcStdInternalSymbol;
}
pub(crate) struct LinkOrdinalParser;
diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs
index 8ca5f0f7228e..60e83a6083ed 100644
--- a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs
@@ -11,7 +11,7 @@ impl NoArgsAttributeParser for AsPtrParser {
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::Method(MethodKind::TraitImpl)),
]);
- const CREATE: fn(Span) -> AttributeKind = AttributeKind::AsPtr;
+ const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcAsPtr;
}
pub(crate) struct PubTransparentParser;
@@ -23,7 +23,7 @@ impl NoArgsAttributeParser for PubTransparentParser {
Allow(Target::Enum),
Allow(Target::Union),
]);
- const CREATE: fn(Span) -> AttributeKind = AttributeKind::PubTransparent;
+ const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcPubTransparent;
}
pub(crate) struct PassByValueParser;
@@ -35,7 +35,7 @@ impl NoArgsAttributeParser for PassByValueParser {
Allow(Target::Enum),
Allow(Target::TyAlias),
]);
- const CREATE: fn(Span) -> AttributeKind = AttributeKind::PassByValue;
+ const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcPassByValue;
}
pub(crate) struct RustcShouldNotBeCalledOnConstItems;
diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs
index d37915b1b80b..00d40687fc85 100644
--- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs
@@ -206,3 +206,12 @@ impl SingleAttributeParser for CollapseDebugInfoParser {
Some(AttributeKind::CollapseDebugInfo(info))
}
}
+
+pub(crate) struct RustcProcMacroDeclsParser;
+
+impl NoArgsAttributeParser for RustcProcMacroDeclsParser {
+ const PATH: &[Symbol] = &[sym::rustc_proc_macro_decls];
+ const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
+ const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Static)]);
+ const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcProcMacroDecls;
+}
diff --git a/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs
index 3674aa7124ab..f9ace7e25d1b 100644
--- a/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs
@@ -1,3 +1,6 @@
+use rustc_hir::lints::AttributeLintKind;
+use rustc_session::lint::builtin::AMBIGUOUS_DERIVE_HELPERS;
+
use super::prelude::*;
const PROC_MACRO_ALLOWED_TARGETS: AllowedTargets =
@@ -126,6 +129,13 @@ fn parse_derive_like(
cx.expected_identifier(ident.span);
return None;
}
+ if rustc_feature::is_builtin_attr_name(ident.name) {
+ cx.emit_lint(
+ AMBIGUOUS_DERIVE_HELPERS,
+ AttributeLintKind::AmbiguousDeriveHelpers,
+ ident.span,
+ );
+ }
attributes.push(ident.name);
}
}
diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs
index 34d4957edc70..fb0b8df65284 100644
--- a/compiler/rustc_attr_parsing/src/attributes/repr.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs
@@ -272,7 +272,7 @@ fn parse_alignment(node: &LitKind) -> Result {
pub(crate) struct AlignParser(Option<(Align, Span)>);
impl AlignParser {
- const PATH: &'static [Symbol] = &[sym::rustc_align];
+ const PATH: &[Symbol] = &[sym::rustc_align];
const TEMPLATE: AttributeTemplate = template!(List: &[""]);
fn parse(&mut self, cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) {
@@ -329,7 +329,7 @@ impl AttributeParser for AlignParser {
pub(crate) struct AlignStaticParser(AlignParser);
impl AlignStaticParser {
- const PATH: &'static [Symbol] = &[sym::rustc_align_static];
+ const PATH: &[Symbol] = &[sym::rustc_align_static];
const TEMPLATE: AttributeTemplate = AlignParser::TEMPLATE;
fn parse(&mut self, cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) {
diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
index 53120dece916..71a8fb0dd47d 100644
--- a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
@@ -7,36 +7,36 @@ use crate::attributes::{NoArgsAttributeParser, OnDuplicate};
use crate::context::Stage;
use crate::target_checking::AllowedTargets;
-pub(crate) struct RustcDumpUserArgs;
+pub(crate) struct RustcDumpUserArgsParser;
-impl NoArgsAttributeParser for RustcDumpUserArgs {
+impl NoArgsAttributeParser for RustcDumpUserArgsParser {
const PATH: &[Symbol] = &[sym::rustc_dump_user_args];
const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpUserArgs;
}
-pub(crate) struct RustcDumpDefParents;
+pub(crate) struct RustcDumpDefParentsParser;
-impl NoArgsAttributeParser for RustcDumpDefParents {
+impl NoArgsAttributeParser for RustcDumpDefParentsParser {
const PATH: &[Symbol] = &[sym::rustc_dump_def_parents];
const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpDefParents;
}
-pub(crate) struct RustcDumpItemBounds;
+pub(crate) struct RustcDumpItemBoundsParser;
-impl NoArgsAttributeParser for RustcDumpItemBounds {
+impl NoArgsAttributeParser for RustcDumpItemBoundsParser {
const PATH: &[Symbol] = &[sym::rustc_dump_item_bounds];
const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::AssocTy)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpItemBounds;
}
-pub(crate) struct RustcDumpPredicates;
+pub(crate) struct RustcDumpPredicatesParser;
-impl NoArgsAttributeParser for RustcDumpPredicates {
+impl NoArgsAttributeParser for RustcDumpPredicatesParser {
const PATH: &[Symbol] = &[sym::rustc_dump_predicates];
const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
@@ -49,9 +49,9 @@ impl NoArgsAttributeParser for RustcDumpPredicates {
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpPredicates;
}
-pub(crate) struct RustcDumpVtable;
+pub(crate) struct RustcDumpVtableParser;
-impl NoArgsAttributeParser for RustcDumpVtable {
+impl NoArgsAttributeParser for RustcDumpVtableParser {
const PATH: &[Symbol] = &[sym::rustc_dump_vtable];
const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
index 365cd55bdc38..2c94a708a90c 100644
--- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
@@ -1,14 +1,25 @@
+use std::path::PathBuf;
+
use rustc_ast::{LitIntType, LitKind, MetaItemLit};
+use rustc_hir::LangItem;
+use rustc_hir::attrs::{
+ BorrowckGraphvizFormatKind, CguFields, CguKind, DivergingBlockBehavior,
+ DivergingFallbackBehavior, RustcCleanAttribute, RustcCleanQueries, RustcLayoutType,
+ RustcMirKind,
+};
use rustc_session::errors;
+use rustc_span::Symbol;
use super::prelude::*;
use super::util::parse_single_integer;
-use crate::session_diagnostics::RustcScalableVectorCountOutOfRange;
+use crate::session_diagnostics::{
+ AttributeRequiresOpt, CguFieldsMissing, RustcScalableVectorCountOutOfRange, UnknownLangItem,
+};
pub(crate) struct RustcMainParser;
impl NoArgsAttributeParser for RustcMainParser {
- const PATH: &'static [Symbol] = &[sym::rustc_main];
+ const PATH: &[Symbol] = &[sym::rustc_main];
const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcMain;
@@ -93,7 +104,7 @@ impl NoArgsAttributeParser for RustcNoImplicitAutorefsParser {
pub(crate) struct RustcLayoutScalarValidRangeStartParser;
impl SingleAttributeParser for RustcLayoutScalarValidRangeStartParser {
- const PATH: &'static [Symbol] = &[sym::rustc_layout_scalar_valid_range_start];
+ const PATH: &[Symbol] = &[sym::rustc_layout_scalar_valid_range_start];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
@@ -108,7 +119,7 @@ impl SingleAttributeParser for RustcLayoutScalarValidRangeStartPars
pub(crate) struct RustcLayoutScalarValidRangeEndParser;
impl SingleAttributeParser for RustcLayoutScalarValidRangeEndParser {
- const PATH: &'static [Symbol] = &[sym::rustc_layout_scalar_valid_range_end];
+ const PATH: &[Symbol] = &[sym::rustc_layout_scalar_valid_range_end];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
@@ -197,6 +208,325 @@ impl NoArgsAttributeParser for RustcLintOptTyParser {
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintOptTy;
}
+fn parse_cgu_fields(
+ cx: &mut AcceptContext<'_, '_, S>,
+ args: &ArgParser,
+ accepts_kind: bool,
+) -> Option<(Symbol, Symbol, Option)> {
+ let Some(args) = args.list() else {
+ cx.expected_list(cx.attr_span, args);
+ return None;
+ };
+
+ let mut cfg = None::<(Symbol, Span)>;
+ let mut module = None::<(Symbol, Span)>;
+ let mut kind = None::<(Symbol, Span)>;
+
+ for arg in args.mixed() {
+ let Some(arg) = arg.meta_item() else {
+ cx.expected_name_value(args.span, None);
+ continue;
+ };
+
+ let res = match arg.ident().map(|i| i.name) {
+ Some(sym::cfg) => &mut cfg,
+ Some(sym::module) => &mut module,
+ Some(sym::kind) if accepts_kind => &mut kind,
+ _ => {
+ cx.expected_specific_argument(
+ arg.path().span(),
+ if accepts_kind {
+ &[sym::cfg, sym::module, sym::kind]
+ } else {
+ &[sym::cfg, sym::module]
+ },
+ );
+ continue;
+ }
+ };
+
+ let Some(i) = arg.args().name_value() else {
+ cx.expected_name_value(arg.span(), None);
+ continue;
+ };
+
+ let Some(str) = i.value_as_str() else {
+ cx.expected_string_literal(i.value_span, Some(i.value_as_lit()));
+ continue;
+ };
+
+ if res.is_some() {
+ cx.duplicate_key(arg.span(), arg.ident().unwrap().name);
+ continue;
+ }
+
+ *res = Some((str, i.value_span));
+ }
+
+ let Some((cfg, _)) = cfg else {
+ cx.emit_err(CguFieldsMissing { span: args.span, name: &cx.attr_path, field: sym::cfg });
+ return None;
+ };
+ let Some((module, _)) = module else {
+ cx.emit_err(CguFieldsMissing { span: args.span, name: &cx.attr_path, field: sym::module });
+ return None;
+ };
+ let kind = if let Some((kind, span)) = kind {
+ Some(match kind {
+ sym::no => CguKind::No,
+ sym::pre_dash_lto => CguKind::PreDashLto,
+ sym::post_dash_lto => CguKind::PostDashLto,
+ sym::any => CguKind::Any,
+ _ => {
+ cx.expected_specific_argument_strings(
+ span,
+ &[sym::no, sym::pre_dash_lto, sym::post_dash_lto, sym::any],
+ );
+ return None;
+ }
+ })
+ } else {
+ // return None so that an unwrap for the attributes that need it is ok.
+ if accepts_kind {
+ cx.emit_err(CguFieldsMissing {
+ span: args.span,
+ name: &cx.attr_path,
+ field: sym::kind,
+ });
+ return None;
+ };
+
+ None
+ };
+
+ Some((cfg, module, kind))
+}
+
+#[derive(Default)]
+pub(crate) struct RustcCguTestAttributeParser {
+ items: ThinVec<(Span, CguFields)>,
+}
+
+impl AttributeParser for RustcCguTestAttributeParser {
+ const ATTRIBUTES: AcceptMapping = &[
+ (
+ &[sym::rustc_partition_reused],
+ template!(List: &[r#"cfg = "...", module = "...""#]),
+ |this, cx, args| {
+ this.items.extend(parse_cgu_fields(cx, args, false).map(|(cfg, module, _)| {
+ (cx.attr_span, CguFields::PartitionReused { cfg, module })
+ }));
+ },
+ ),
+ (
+ &[sym::rustc_partition_codegened],
+ template!(List: &[r#"cfg = "...", module = "...""#]),
+ |this, cx, args| {
+ this.items.extend(parse_cgu_fields(cx, args, false).map(|(cfg, module, _)| {
+ (cx.attr_span, CguFields::PartitionCodegened { cfg, module })
+ }));
+ },
+ ),
+ (
+ &[sym::rustc_expected_cgu_reuse],
+ template!(List: &[r#"cfg = "...", module = "...", kind = "...""#]),
+ |this, cx, args| {
+ this.items.extend(parse_cgu_fields(cx, args, true).map(|(cfg, module, kind)| {
+ // unwrap ok because if not given, we return None in `parse_cgu_fields`.
+ (cx.attr_span, CguFields::ExpectedCguReuse { cfg, module, kind: kind.unwrap() })
+ }));
+ },
+ ),
+ ];
+
+ const ALLOWED_TARGETS: AllowedTargets =
+ AllowedTargets::AllowList(&[Allow(Target::Mod), Allow(Target::Crate)]);
+
+ fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option {
+ Some(AttributeKind::RustcCguTestAttr(self.items))
+ }
+}
+
+pub(crate) struct RustcDeprecatedSafe2024Parser;
+
+impl SingleAttributeParser for RustcDeprecatedSafe2024Parser {
+ const PATH: &[Symbol] = &[sym::rustc_deprecated_safe_2024];
+ const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
+ const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
+ Allow(Target::Fn),
+ Allow(Target::Method(MethodKind::Inherent)),
+ Allow(Target::Method(MethodKind::Trait { body: false })),
+ Allow(Target::Method(MethodKind::Trait { body: true })),
+ Allow(Target::Method(MethodKind::TraitImpl)),
+ ]);
+ const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
+ const TEMPLATE: AttributeTemplate = template!(List: &[r#"audit_that = "...""#]);
+
+ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option {
+ let Some(args) = args.list() else {
+ cx.expected_list(cx.attr_span, args);
+ return None;
+ };
+
+ let Some(single) = args.single() else {
+ cx.expected_single_argument(args.span);
+ return None;
+ };
+
+ let Some(arg) = single.meta_item() else {
+ cx.expected_name_value(args.span, None);
+ return None;
+ };
+
+ let Some(args) = arg.word_is(sym::audit_that) else {
+ cx.expected_specific_argument(arg.span(), &[sym::audit_that]);
+ return None;
+ };
+
+ let Some(nv) = args.name_value() else {
+ cx.expected_name_value(arg.span(), Some(sym::audit_that));
+ return None;
+ };
+
+ let Some(suggestion) = nv.value_as_str() else {
+ cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
+ return None;
+ };
+
+ Some(AttributeKind::RustcDeprecatedSafe2024 { suggestion })
+ }
+}
+
+pub(crate) struct RustcConversionSuggestionParser;
+
+impl NoArgsAttributeParser for RustcConversionSuggestionParser {
+ const PATH: &[Symbol] = &[sym::rustc_conversion_suggestion];
+ const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
+ const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
+ Allow(Target::Fn),
+ Allow(Target::Method(MethodKind::Inherent)),
+ Allow(Target::Method(MethodKind::Trait { body: false })),
+ Allow(Target::Method(MethodKind::Trait { body: true })),
+ Allow(Target::Method(MethodKind::TraitImpl)),
+ ]);
+ const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcConversionSuggestion;
+}
+
+pub(crate) struct RustcCaptureAnalysisParser;
+
+impl NoArgsAttributeParser for RustcCaptureAnalysisParser {
+ const PATH: &[Symbol] = &[sym::rustc_capture_analysis];
+ const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
+ const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Closure)]);
+ const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCaptureAnalysis;
+}
+
+pub(crate) struct RustcNeverTypeOptionsParser;
+
+impl SingleAttributeParser for RustcNeverTypeOptionsParser {
+ const PATH: &[Symbol] = &[sym::rustc_never_type_options];
+ const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
+ const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
+ const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
+ const TEMPLATE: AttributeTemplate = template!(List: &[
+ r#"fallback = "unit", "never", "no""#,
+ r#"diverging_block_default = "unit", "never""#,
+ ]);
+
+ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option {
+ let Some(list) = args.list() else {
+ cx.expected_list(cx.attr_span, args);
+ return None;
+ };
+
+ let mut fallback = None::;
+ let mut diverging_block_default = None::;
+
+ for arg in list.mixed() {
+ let Some(meta) = arg.meta_item() else {
+ cx.expected_name_value(arg.span(), None);
+ continue;
+ };
+
+ let res = match meta.ident().map(|i| i.name) {
+ Some(sym::fallback) => &mut fallback,
+ Some(sym::diverging_block_default) => &mut diverging_block_default,
+ _ => {
+ cx.expected_specific_argument(
+ meta.path().span(),
+ &[sym::fallback, sym::diverging_block_default],
+ );
+ continue;
+ }
+ };
+
+ let Some(nv) = meta.args().name_value() else {
+ cx.expected_name_value(meta.span(), None);
+ continue;
+ };
+
+ let Some(field) = nv.value_as_str() else {
+ cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
+ continue;
+ };
+
+ if res.is_some() {
+ cx.duplicate_key(meta.span(), meta.ident().unwrap().name);
+ continue;
+ }
+
+ *res = Some(Ident { name: field, span: nv.value_span });
+ }
+
+ let fallback = match fallback {
+ None => None,
+ Some(Ident { name: sym::unit, .. }) => Some(DivergingFallbackBehavior::ToUnit),
+ Some(Ident { name: sym::never, .. }) => Some(DivergingFallbackBehavior::ToNever),
+ Some(Ident { name: sym::no, .. }) => Some(DivergingFallbackBehavior::NoFallback),
+ Some(Ident { span, .. }) => {
+ cx.expected_specific_argument_strings(span, &[sym::unit, sym::never, sym::no]);
+ return None;
+ }
+ };
+
+ let diverging_block_default = match diverging_block_default {
+ None => None,
+ Some(Ident { name: sym::unit, .. }) => Some(DivergingBlockBehavior::Unit),
+ Some(Ident { name: sym::never, .. }) => Some(DivergingBlockBehavior::Never),
+ Some(Ident { span, .. }) => {
+ cx.expected_specific_argument_strings(span, &[sym::unit, sym::no]);
+ return None;
+ }
+ };
+
+ Some(AttributeKind::RustcNeverTypeOptions { fallback, diverging_block_default })
+ }
+}
+
+pub(crate) struct RustcTrivialFieldReadsParser;
+
+impl NoArgsAttributeParser for RustcTrivialFieldReadsParser {
+ const PATH: &[Symbol] = &[sym::rustc_trivial_field_reads];
+ const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
+ const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
+ const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcTrivialFieldReads;
+}
+
+pub(crate) struct RustcNoMirInlineParser;
+
+impl NoArgsAttributeParser for RustcNoMirInlineParser {
+ const PATH: &[Symbol] = &[sym::rustc_no_mir_inline];
+ const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
+ const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
+ Allow(Target::Fn),
+ Allow(Target::Method(MethodKind::Inherent)),
+ Allow(Target::Method(MethodKind::Trait { body: false })),
+ Allow(Target::Method(MethodKind::Trait { body: true })),
+ Allow(Target::Method(MethodKind::TraitImpl)),
+ ]);
+ const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoMirInline;
+}
+
pub(crate) struct RustcLintQueryInstabilityParser;
impl NoArgsAttributeParser for RustcLintQueryInstabilityParser {
@@ -212,6 +542,22 @@ impl NoArgsAttributeParser for RustcLintQueryInstabilityParser {
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintQueryInstability;
}
+pub(crate) struct RustcRegionsParser;
+
+impl NoArgsAttributeParser for RustcRegionsParser {
+ const PATH: &[Symbol] = &[sym::rustc_regions];
+ const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
+ const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
+ Allow(Target::Fn),
+ Allow(Target::Method(MethodKind::Inherent)),
+ Allow(Target::Method(MethodKind::Trait { body: false })),
+ Allow(Target::Method(MethodKind::Trait { body: true })),
+ Allow(Target::Method(MethodKind::TraitImpl)),
+ ]);
+
+ const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcRegions;
+}
+
pub(crate) struct RustcLintUntrackedQueryInformationParser;
impl NoArgsAttributeParser for RustcLintUntrackedQueryInformationParser {
@@ -230,21 +576,11 @@ impl NoArgsAttributeParser for RustcLintUntrackedQueryInformationPa
pub(crate) struct RustcObjectLifetimeDefaultParser;
-impl SingleAttributeParser for RustcObjectLifetimeDefaultParser {
- const PATH: &[rustc_span::Symbol] = &[sym::rustc_object_lifetime_default];
- const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
+impl NoArgsAttributeParser for RustcObjectLifetimeDefaultParser {
+ const PATH: &[Symbol] = &[sym::rustc_object_lifetime_default];
const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
- const TEMPLATE: AttributeTemplate = template!(Word);
-
- fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option {
- if let Err(span) = args.no_args() {
- cx.expected_no_args(span);
- return None;
- }
-
- Some(AttributeKind::RustcObjectLifetimeDefault)
- }
+ const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcObjectLifetimeDefault;
}
pub(crate) struct RustcSimdMonomorphizeLaneLimitParser;
@@ -268,7 +604,7 @@ impl SingleAttributeParser for RustcSimdMonomorphizeLaneLimitParser
pub(crate) struct RustcScalableVectorParser;
impl SingleAttributeParser for RustcScalableVectorParser {
- const PATH: &[rustc_span::Symbol] = &[sym::rustc_scalable_vector];
+ const PATH: &[Symbol] = &[sym::rustc_scalable_vector];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
@@ -291,6 +627,32 @@ impl SingleAttributeParser for RustcScalableVectorParser {
}
}
+pub(crate) struct LangParser;
+
+impl SingleAttributeParser for LangParser {
+ const PATH: &[Symbol] = &[sym::lang];
+ const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
+ const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
+ const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Targets are checked per lang item in `rustc_passes`
+ const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
+
+ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option {
+ let Some(nv) = args.name_value() else {
+ cx.expected_name_value(cx.attr_span, None);
+ return None;
+ };
+ let Some(name) = nv.value_as_str() else {
+ cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
+ return None;
+ };
+ let Some(lang_item) = LangItem::from_name(name) else {
+ cx.emit_err(UnknownLangItem { span: cx.attr_span, name });
+ return None;
+ };
+ Some(AttributeKind::Lang(lang_item, cx.attr_span))
+ }
+}
+
pub(crate) struct RustcHasIncoherentInherentImplsParser;
impl NoArgsAttributeParser for RustcHasIncoherentInherentImplsParser {
@@ -306,6 +668,23 @@ impl NoArgsAttributeParser for RustcHasIncoherentInherentImplsParse
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcHasIncoherentInherentImpls;
}
+pub(crate) struct PanicHandlerParser;
+
+impl NoArgsAttributeParser for PanicHandlerParser {
+ const PATH: &[Symbol] = &[sym::panic_handler];
+ const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
+ const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Targets are checked per lang item in `rustc_passes`
+ const CREATE: fn(Span) -> AttributeKind = |span| AttributeKind::Lang(LangItem::PanicImpl, span);
+}
+
+pub(crate) struct RustcHiddenTypeOfOpaquesParser;
+
+impl NoArgsAttributeParser for RustcHiddenTypeOfOpaquesParser {
+ const PATH: &[Symbol] = &[sym::rustc_hidden_type_of_opaques];
+ const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error;
+ const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
+ const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcHiddenTypeOfOpaques;
+}
pub(crate) struct RustcNounwindParser;
impl NoArgsAttributeParser for RustcNounwindParser {
@@ -329,3 +708,590 @@ impl NoArgsAttributeParser