From bebaa8a29da776739f7d507d4e6a679656e687f2 Mon Sep 17 00:00:00 2001 From: binarycat Date: Wed, 9 Apr 2025 12:43:06 -0500 Subject: add sitemap to rust docs --- src/bootstrap/src/core/build_steps/dist.rs | 1 + src/doc/robots.txt | 2 ++ src/doc/sitemap.txt | 4 ++++ 3 files changed, 7 insertions(+) create mode 100644 src/doc/sitemap.txt (limited to 'src') diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 83f71aeed72..6ec39ffc436 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -82,6 +82,7 @@ impl Step for Docs { tarball.set_product_name("Rust Documentation"); tarball.add_bulk_dir(builder.doc_out(host), dest); tarball.add_file(builder.src.join("src/doc/robots.txt"), dest, FileType::Regular); + tarball.add_file(builder.src.join("src/doc/sitemap.txt"), dest, FileType::Regular); Some(tarball.generate()) } } diff --git a/src/doc/robots.txt b/src/doc/robots.txt index 3a2552e9a15..71a60f89c14 100644 --- a/src/doc/robots.txt +++ b/src/doc/robots.txt @@ -9,3 +9,5 @@ Disallow: /beta/book/first-edition/ Disallow: /beta/book/second-edition/ Disallow: /nightly/book/first-edition/ Disallow: /nightly/book/second-edition/ + +Sitemap: https://doc.rust-lang.org/sitemap.txt diff --git a/src/doc/sitemap.txt b/src/doc/sitemap.txt new file mode 100644 index 00000000000..6e5f0fbad37 --- /dev/null +++ b/src/doc/sitemap.txt @@ -0,0 +1,4 @@ +https://doc.rust-lang.org/stable/ +https://doc.rust-lang.org/beta/ +https://doc.rust-lang.org/nightly/ + -- cgit 1.4.1-3-g733a5 From ea44f12f72888528ddb5b26492c3b72ad4b7bcb4 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Fri, 15 Aug 2025 21:47:39 +0800 Subject: Rename and move tuple index suffix regression test To make it more obvious what it's testing. This is its own commit to make git blame easier. --- src/tools/tidy/src/issues.txt | 1 - tests/ui/parser/issues/issue-59418.rs | 18 ------------------ tests/ui/parser/issues/issue-59418.stderr | 26 -------------------------- tests/ui/parser/tuple-index-suffix.rs | 18 ++++++++++++++++++ tests/ui/parser/tuple-index-suffix.stderr | 26 ++++++++++++++++++++++++++ 5 files changed, 44 insertions(+), 45 deletions(-) delete mode 100644 tests/ui/parser/issues/issue-59418.rs delete mode 100644 tests/ui/parser/issues/issue-59418.stderr create mode 100644 tests/ui/parser/tuple-index-suffix.rs create mode 100644 tests/ui/parser/tuple-index-suffix.stderr (limited to 'src') diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index ee06707415f..849dcb9e88f 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -2021,7 +2021,6 @@ ui/parser/issues/issue-5806.rs ui/parser/issues/issue-58094-missing-right-square-bracket.rs ui/parser/issues/issue-58856-1.rs ui/parser/issues/issue-58856-2.rs -ui/parser/issues/issue-59418.rs ui/parser/issues/issue-60075.rs ui/parser/issues/issue-61858.rs ui/parser/issues/issue-62524.rs diff --git a/tests/ui/parser/issues/issue-59418.rs b/tests/ui/parser/issues/issue-59418.rs deleted file mode 100644 index 0fa191d4a7e..00000000000 --- a/tests/ui/parser/issues/issue-59418.rs +++ /dev/null @@ -1,18 +0,0 @@ -struct X(i32,i32,i32); - -fn main() { - let a = X(1, 2, 3); - let b = a.1suffix; - //~^ ERROR suffixes on a tuple index are invalid - println!("{}", b); - let c = (1, 2, 3); - let d = c.1suffix; - //~^ ERROR suffixes on a tuple index are invalid - println!("{}", d); - let s = X { 0suffix: 0, 1: 1, 2: 2 }; - //~^ ERROR suffixes on a tuple index are invalid - match s { - X { 0suffix: _, .. } => {} - //~^ ERROR suffixes on a tuple index are invalid - } -} diff --git a/tests/ui/parser/issues/issue-59418.stderr b/tests/ui/parser/issues/issue-59418.stderr deleted file mode 100644 index 347051e9f92..00000000000 --- a/tests/ui/parser/issues/issue-59418.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: suffixes on a tuple index are invalid - --> $DIR/issue-59418.rs:5:15 - | -LL | let b = a.1suffix; - | ^^^^^^^ invalid suffix `suffix` - -error: suffixes on a tuple index are invalid - --> $DIR/issue-59418.rs:9:15 - | -LL | let d = c.1suffix; - | ^^^^^^^ invalid suffix `suffix` - -error: suffixes on a tuple index are invalid - --> $DIR/issue-59418.rs:12:17 - | -LL | let s = X { 0suffix: 0, 1: 1, 2: 2 }; - | ^^^^^^^ invalid suffix `suffix` - -error: suffixes on a tuple index are invalid - --> $DIR/issue-59418.rs:15:13 - | -LL | X { 0suffix: _, .. } => {} - | ^^^^^^^ invalid suffix `suffix` - -error: aborting due to 4 previous errors - diff --git a/tests/ui/parser/tuple-index-suffix.rs b/tests/ui/parser/tuple-index-suffix.rs new file mode 100644 index 00000000000..0fa191d4a7e --- /dev/null +++ b/tests/ui/parser/tuple-index-suffix.rs @@ -0,0 +1,18 @@ +struct X(i32,i32,i32); + +fn main() { + let a = X(1, 2, 3); + let b = a.1suffix; + //~^ ERROR suffixes on a tuple index are invalid + println!("{}", b); + let c = (1, 2, 3); + let d = c.1suffix; + //~^ ERROR suffixes on a tuple index are invalid + println!("{}", d); + let s = X { 0suffix: 0, 1: 1, 2: 2 }; + //~^ ERROR suffixes on a tuple index are invalid + match s { + X { 0suffix: _, .. } => {} + //~^ ERROR suffixes on a tuple index are invalid + } +} diff --git a/tests/ui/parser/tuple-index-suffix.stderr b/tests/ui/parser/tuple-index-suffix.stderr new file mode 100644 index 00000000000..347051e9f92 --- /dev/null +++ b/tests/ui/parser/tuple-index-suffix.stderr @@ -0,0 +1,26 @@ +error: suffixes on a tuple index are invalid + --> $DIR/issue-59418.rs:5:15 + | +LL | let b = a.1suffix; + | ^^^^^^^ invalid suffix `suffix` + +error: suffixes on a tuple index are invalid + --> $DIR/issue-59418.rs:9:15 + | +LL | let d = c.1suffix; + | ^^^^^^^ invalid suffix `suffix` + +error: suffixes on a tuple index are invalid + --> $DIR/issue-59418.rs:12:17 + | +LL | let s = X { 0suffix: 0, 1: 1, 2: 2 }; + | ^^^^^^^ invalid suffix `suffix` + +error: suffixes on a tuple index are invalid + --> $DIR/issue-59418.rs:15:13 + | +LL | X { 0suffix: _, .. } => {} + | ^^^^^^^ invalid suffix `suffix` + +error: aborting due to 4 previous errors + -- cgit 1.4.1-3-g733a5 From 4996f53d8d770e8d481d5a59729dd163c5cfae32 Mon Sep 17 00:00:00 2001 From: Ali Nazzal Date: Tue, 26 Aug 2025 09:35:08 +0300 Subject: stabilization_guide: fix macro name and syntax in gating example --- src/doc/rustc-dev-guide/src/stabilization_guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/stabilization_guide.md b/src/doc/rustc-dev-guide/src/stabilization_guide.md index e399930fc52..7b9e1eb5629 100644 --- a/src/doc/rustc-dev-guide/src/stabilization_guide.md +++ b/src/doc/rustc-dev-guide/src/stabilization_guide.md @@ -82,7 +82,7 @@ Most importantly, remove the code which flags an error if the feature-gate is no gate_all!(pub_restricted, "`pub(restricted)` syntax is experimental"); ``` -This `gate_feature_post!` macro prints an error if the `pub_restricted` feature is not enabled. It is not needed now that `#[pub_restricted]` is stable. +The `gate_all!` macro reports an error if the `pub_restricted` feature is not enabled. It is not needed now that `pub(restricted)` is stable. For more subtle features, you may find code like this: -- cgit 1.4.1-3-g733a5 From 2521a90809e10b5065fce3dc42fe79490120b956 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Tue, 26 Aug 2025 19:28:08 +0800 Subject: Remove myself from adhoc_group --- src/doc/rustc-dev-guide/triagebot.toml | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/triagebot.toml b/src/doc/rustc-dev-guide/triagebot.toml index 3ac5d57a52b..4a885239152 100644 --- a/src/doc/rustc-dev-guide/triagebot.toml +++ b/src/doc/rustc-dev-guide/triagebot.toml @@ -90,7 +90,6 @@ does not need reviews. You can request a review using `r? rustc-dev-guide` or \ [assign.adhoc_groups] rustc-dev-guide = [ "@BoxyUwU", - "@jieyouxu", "@jyn514", "@tshepang", ] -- cgit 1.4.1-3-g733a5 From 6b49e11f885dfeab5b701561b79528e95c210a27 Mon Sep 17 00:00:00 2001 From: Ali Nazzal Date: Tue, 26 Aug 2025 19:36:53 +0300 Subject: contributing: clarify when to update a branch vs avoid during review --- src/doc/rustc-dev-guide/src/contributing.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 963bef3af8d..157dbbc1379 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -154,13 +154,11 @@ The CI in rust-lang/rust applies your patches directly against the current maste not against the commit your branch is based on. This can lead to unexpected failures if your branch is outdated, even when there are no explicit merge conflicts. -Before submitting or updating a PR, make sure to update your branch -as mentioned [here](git.md#keeping-things-up-to-date) if it's significantly -behind the master branch (e.g., more than 100 commits behind). -This fetches the latest master branch and rebases your changes on top of it, -ensuring your PR is tested against the latest code. +Update your branch only when needed: when you have merge conflicts, upstream CI is broken and blocking your green PR, or a maintainer requests it. Avoid updating an already-green PR under review unless necessary. During review, make incremental commits to address feedback. Prefer to squash or rebase at the end, and do so when a reviewer requests it. -After rebasing, it's recommended to [run the relevant tests locally](tests/intro.md) to catch any issues before CI runs. +When updating, use `git push --force-with-lease` and leave a brief comment explaining what changed. Some repos prefer merging from `upstream/master` instead of rebasing; follow the project's conventions. See [keeping things up to date](git.md#keeping-things-up-to-date) for detailed instructions. + +After updating, run local checks (e.g., `mdbook build` for this repo) to catch issues before CI runs. ### r? -- cgit 1.4.1-3-g733a5 From 65f1a9f26747f3a573c1b1a4f4eea4a412f0ffdc Mon Sep 17 00:00:00 2001 From: Ali Nazzal Date: Tue, 26 Aug 2025 19:41:08 +0300 Subject: contributing: restore tests/intro.md link; avoid 'this repo' wording --- src/doc/rustc-dev-guide/src/contributing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 157dbbc1379..d0a32f71a3d 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -154,11 +154,11 @@ The CI in rust-lang/rust applies your patches directly against the current maste not against the commit your branch is based on. This can lead to unexpected failures if your branch is outdated, even when there are no explicit merge conflicts. -Update your branch only when needed: when you have merge conflicts, upstream CI is broken and blocking your green PR, or a maintainer requests it. Avoid updating an already-green PR under review unless necessary. During review, make incremental commits to address feedback. Prefer to squash or rebase at the end, and do so when a reviewer requests it. +Update your branch only when needed: when you have merge conflicts, upstream CI is broken and blocking your green PR, or a maintainer requests it. Avoid updating an already-green PR under review unless necessary. During review, make incremental commits to address feedback. Prefer to squash or rebase only at the end, or when a reviewer requests it. When updating, use `git push --force-with-lease` and leave a brief comment explaining what changed. Some repos prefer merging from `upstream/master` instead of rebasing; follow the project's conventions. See [keeping things up to date](git.md#keeping-things-up-to-date) for detailed instructions. -After updating, run local checks (e.g., `mdbook build` for this repo) to catch issues before CI runs. +After rebasing, it's recommended to [run the relevant tests locally](tests/intro.md) to catch any issues before CI runs. ### r? -- cgit 1.4.1-3-g733a5 From 9ddd03ce1f67fa2b73e181f810ebc21d464eb7d9 Mon Sep 17 00:00:00 2001 From: apiraino Date: Wed, 6 Aug 2025 11:07:57 +0200 Subject: Mention our policy on typofixes for internal docs --- src/doc/rustc-dev-guide/src/contributing.md | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index d0a32f71a3d..1ade4953d2e 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -370,6 +370,9 @@ You can also use `rustdoc` directly to check small fixes. For example, `rustdoc src/doc/reference.md` will render reference to `doc/reference.html`. The CSS might be messed up, but you can verify that the HTML is right. +Please notice that at this time we don't accept typography/spellcheck fixes to **internal documentation** (example: +tests, library or compiler code) as it's usually not worth the churn or the review time. + ### Contributing to rustc-dev-guide Contributions to the [rustc-dev-guide] are always welcome, and can be made directly at -- cgit 1.4.1-3-g733a5 From e2a4fb0bbe0f2a60917f900b8e6c4dc31b01cf64 Mon Sep 17 00:00:00 2001 From: Ali Nazzal Date: Thu, 28 Aug 2025 11:38:42 +0300 Subject: dates(diagnostics,tests): refresh annotated dates to Aug 2025; preserve local style --- src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md | 2 +- src/doc/rustc-dev-guide/src/diagnostics/error-codes.md | 2 +- src/doc/rustc-dev-guide/src/diagnostics/lintstore.md | 2 +- src/doc/rustc-dev-guide/src/diagnostics/translation.md | 4 ++-- src/doc/rustc-dev-guide/src/tests/ci.md | 2 +- src/doc/rustc-dev-guide/src/tests/directives.md | 4 ++-- src/doc/rustc-dev-guide/src/tests/misc.md | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md index 9360427d660..4000cbdb8ce 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md @@ -48,7 +48,7 @@ A new diagnostic item can be added with these two steps: For the naming conventions of diagnostic items, please refer to [*Naming Conventions*](#naming-conventions). -2. +2. Diagnostic items in code are accessed via symbols in [`rustc_span::symbol::sym`]. To add your newly-created diagnostic item, diff --git a/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md b/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md index 1693432b90d..98d9a7ab0a1 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md @@ -10,7 +10,7 @@ explanation: new error codes must include them. Note that not all _historical_ The explanations are written in Markdown (see the [CommonMark Spec] for specifics around syntax), and all of them are linked in the [`rustc_error_codes`] crate. Please read [RFC 1567] for details on how to format and write long error -codes. As of February 2023, there is an +codes. As of August 2025, there is an effort[^new-explanations] to replace this largely outdated RFC with a new more flexible standard. diff --git a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md index 7b98bc62116..f0d349c91b9 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md @@ -21,7 +21,7 @@ which boils down to a static with type [`&rustc_lint_defs::Lint`] as the macro is somewhat unwieldy to add new fields to, like all macros). -As of Aug 2022, +As of Aug 2025, we lint against direct declarations without the use of the macro. Lint declarations don't carry any "state" - they are merely global identifiers diff --git a/src/doc/rustc-dev-guide/src/diagnostics/translation.md b/src/doc/rustc-dev-guide/src/diagnostics/translation.md index 58d75f54a00..5d143da2bad 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/translation.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/translation.md @@ -2,12 +2,12 @@
rustc's current diagnostics translation infrastructure (as of - October 2024 + August 2025 ) unfortunately causes some friction for compiler contributors, and the current infrastructure is mostly pending a redesign that better addresses needs of both compiler contributors and translation teams. Note that there is no current active redesign proposals (as of - October 2024 + August 2025 )! Please see the tracking issue diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index a8cc959124f..95850c07cfe 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -22,7 +22,7 @@ jobs](#modifying-ci-jobs). ## CI workflow - + Our CI is primarily executed on [GitHub Actions], with a single workflow defined in [`.github/workflows/ci.yml`], which contains a bunch of steps that are diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index fbbeb7e97d3..6cf73909b11 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -42,7 +42,7 @@ not be exhaustive. Directives can generally be found by browsing the ### Assembly - + | Directive | Explanation | Supported test suites | Possible values | |-------------------|-------------------------------|-----------------------|----------------------------------------| @@ -113,7 +113,7 @@ for more details. | `known-bug` | No error annotation needed due to known bug | `ui`, `crashes`, `incremental` | Issue number `#123456` | | `compare-output-by-lines` | Compare the output by lines, rather than as a single string | All | N/A | -[^check_stdout]: presently this has a weird quirk +[^check_stdout]: presently this has a weird quirk where the test binary's stdout and stderr gets concatenated and then `error-pattern`s are matched on this combined output, which is ??? slightly questionable to say the least. diff --git a/src/doc/rustc-dev-guide/src/tests/misc.md b/src/doc/rustc-dev-guide/src/tests/misc.md index 39f88174879..ed80c6c3479 100644 --- a/src/doc/rustc-dev-guide/src/tests/misc.md +++ b/src/doc/rustc-dev-guide/src/tests/misc.md @@ -2,7 +2,7 @@ ## `RUSTC_BOOTSTRAP` and stability - + This is a bootstrap/compiler implementation detail, but it can also be useful for testing: -- cgit 1.4.1-3-g733a5 From 8e618a92c122a1546e21d86f7b6ef9cae197ec6f Mon Sep 17 00:00:00 2001 From: Ali Nazzal Date: Thu, 28 Aug 2025 19:00:47 +0300 Subject: dates(infra): refresh date-check annotations for Aug 2025; preserve local style --- src/doc/rustc-dev-guide/src/backend/updating-llvm.md | 4 ++-- src/doc/rustc-dev-guide/src/fuzzing.md | 2 +- src/doc/rustc-dev-guide/src/overview.md | 2 +- src/doc/rustc-dev-guide/src/parallel-rustc.md | 8 ++++---- src/doc/rustc-dev-guide/src/profiling.md | 2 +- src/doc/rustc-dev-guide/src/rustdoc-internals.md | 6 +++--- 6 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md index ebef15d40ba..a4e22b73984 100644 --- a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md +++ b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md @@ -1,6 +1,6 @@ # Updating LLVM - + Rust supports building against multiple LLVM versions: * Tip-of-tree for the current LLVM development branch is usually supported @@ -93,7 +93,7 @@ An example PR: ## New LLVM Release Updates - + Unlike bugfixes, updating to a new release of LLVM typically requires a lot more work. diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 30005378617..540a8c69061 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -1,6 +1,6 @@ # Fuzzing - + For the purposes of this guide, *fuzzing* is any testing methodology that involves compiling a wide variety of programs in an attempt to uncover bugs in diff --git a/src/doc/rustc-dev-guide/src/overview.md b/src/doc/rustc-dev-guide/src/overview.md index 378d8c4453f..9f0201942d0 100644 --- a/src/doc/rustc-dev-guide/src/overview.md +++ b/src/doc/rustc-dev-guide/src/overview.md @@ -304,7 +304,7 @@ Moreover, the compiler wasn't originally built to use a query system; the query system has been retrofitted into the compiler, so parts of it are not query-fied yet. Also, LLVM isn't our code, so that isn't querified either. The plan is to eventually query-fy all of the steps listed in the previous section, -but as of November 2022, only the steps between `HIR` and +but as of August 2025, only the steps between `HIR` and `LLVM-IR` are query-fied. That is, lexing, parsing, name resolution, and macro expansion are done all at once for the whole program. diff --git a/src/doc/rustc-dev-guide/src/parallel-rustc.md b/src/doc/rustc-dev-guide/src/parallel-rustc.md index ce69b66c2da..b448243223f 100644 --- a/src/doc/rustc-dev-guide/src/parallel-rustc.md +++ b/src/doc/rustc-dev-guide/src/parallel-rustc.md @@ -1,14 +1,14 @@ # Parallel compilation
-As of November 2024, +As of August 2025, the parallel front-end is undergoing significant changes, so this page contains quite a bit of outdated information. Tracking issue:
-As of November 2024, most of the rust compiler is now +As of August 2025, most of the rust compiler is now parallelized. - The codegen part is executed concurrently by default. You can use the `-C @@ -104,7 +104,7 @@ when `parallel-compiler` is true. | **ModuleItems::par_foreign_items**(&self, f: impl Fn(ForeignItemId)) | run `f` on all foreign items in the module | rustc_middle::hir | There are a lot of loops in the compiler which can possibly be parallelized -using these functions. As of August 2022, scenarios where +using these functions. As of August 2025, scenarios where the parallel iterator function has been used are as follows: | caller | scenario | callee | @@ -155,7 +155,7 @@ open feature tracking issue][tracking]. ## Rustdoc -As of November 2022, there are still a number of steps to +As of August 2025, there are still a number of steps to complete before `rustdoc` rendering can be made parallel (see a open discussion of [parallel `rustdoc`][parallel-rustdoc]). diff --git a/src/doc/rustc-dev-guide/src/profiling.md b/src/doc/rustc-dev-guide/src/profiling.md index de06bd7cda7..7dfd74aba3a 100644 --- a/src/doc/rustc-dev-guide/src/profiling.md +++ b/src/doc/rustc-dev-guide/src/profiling.md @@ -108,6 +108,6 @@ The llvm-lines output is affected by several options. MIR optimizations have little impact. Compared to the default `RUSTFLAGS="-Z mir-opt-level=1"`, level 0 adds 0.3GB and level 2 removes 0.2GB. -As of July 2022, +As of August 2025, inlining happens in LLVM and GCC codegen backends, missing only in the Cranelift one. diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals.md b/src/doc/rustc-dev-guide/src/rustdoc-internals.md index 4affbafe477..02abce2e63a 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals.md @@ -99,7 +99,7 @@ regarding dropping private/hidden items can be bypassed by passing `--document-private-items` to `rustdoc`. Note that unlike the previous set of [`AST`][ast] transformations, the passes are run on the _cleaned_ crate. -Here is the list of passes as of March 2023: +Here is the list of passes as of August 2025: - `calculate-doc-coverage` calculates information used for the `--show-coverage` flag. @@ -122,7 +122,7 @@ Here is the list of passes as of March 2023: - `bare_urls` detects links that are not linkified, e.g., in Markdown such as `Go to https://example.com/.` It suggests wrapping the link with angle brackets: `Go to .` to linkify it. This is the code behind the `rustdoc::bare_urls` `lint`. + date-check: Aug 2025 --> `rustdoc::bare_urls` `lint`. - `check_code_block_syntax` validates syntax inside Rust code blocks (```rust) @@ -212,7 +212,7 @@ directly, even during `HTML` generation. This [didn't used to be the case], and a lot of `rustdoc`'s architecture was designed around not doing that, but a `TyCtxt` is now passed to `formats::renderer::run_format`, which is used to run generation for both `HTML` and the -(unstable as of March 2023) JSON format. +(unstable as of August 2025) JSON format. This change has allowed other changes to remove data from the "clean" [`AST`][ast] that can be easily derived from `TyCtxt` queries, and we'll usually accept -- cgit 1.4.1-3-g733a5 From d9022991f0293971262e902388fff1b4fc8fde8b Mon Sep 17 00:00:00 2001 From: Ali Nazzal Date: Thu, 28 Aug 2025 22:26:42 +0300 Subject: dates(queries): refresh date-check annotations to 2025-08; preserve local style --- src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md | 2 +- src/doc/rustc-dev-guide/src/queries/salsa.md | 2 +- src/doc/rustc-dev-guide/src/query.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md b/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md index c1a4373f7da..f487707cd32 100644 --- a/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md +++ b/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md @@ -74,7 +74,7 @@ executed, no results are cached. But the context already provides access to "input" data, i.e. pieces of immutable data that were computed before the context was created and that queries can access to do their computations. -As of January 2021, this input data consists mainly of +As of August 2025, this input data consists mainly of the HIR map, upstream crate metadata, and the command-line options the compiler was invoked with; but in the future inputs will just consist of command-line options and a list of source files -- the HIR map will itself be provided by a diff --git a/src/doc/rustc-dev-guide/src/queries/salsa.md b/src/doc/rustc-dev-guide/src/queries/salsa.md index dc7160edc22..c0caa201f97 100644 --- a/src/doc/rustc-dev-guide/src/queries/salsa.md +++ b/src/doc/rustc-dev-guide/src/queries/salsa.md @@ -7,7 +7,7 @@ want to watch [Salsa In More Depth](https://www.youtube.com/watch?v=i_IhACacPRY), also by Niko Matsakis. -> As of November 2022, although Salsa is inspired by (among +> As of August 2025, although Salsa is inspired by (among > other things) rustc's query system, it is not used directly in rustc. It > _is_ used in [chalk], an implementation of Rust's trait system, and > extensively in [`rust-analyzer`], the official implementation of the language diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md index 8377a7b2f31..0a927319471 100644 --- a/src/doc/rustc-dev-guide/src/query.md +++ b/src/doc/rustc-dev-guide/src/query.md @@ -1,7 +1,7 @@ # Queries: demand-driven compilation As described in [Overview of the compiler], the Rust compiler -is still (as of July 2021) transitioning from a +is still (as of August 2025) transitioning from a traditional "pass-based" setup to a "demand-driven" system. The compiler query system is the key to rustc's demand-driven organization. The idea is pretty simple. Instead of entirely independent passes -- cgit 1.4.1-3-g733a5 From a557aef8813f1d300ba8c21eb4f24f3350a28f7e Mon Sep 17 00:00:00 2001 From: Ali Nazzal Date: Thu, 28 Aug 2025 22:34:41 +0300 Subject: dates(types,traits): refresh date-check annotations for Aug/2025-08; preserve local style --- .../src/borrow_check/region_inference/member_constraints.md | 2 +- src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md | 2 +- src/doc/rustc-dev-guide/src/stability.md | 2 +- src/doc/rustc-dev-guide/src/thir.md | 4 ++-- src/doc/rustc-dev-guide/src/traits/chalk.md | 2 +- src/doc/rustc-dev-guide/src/traits/resolution.md | 2 +- src/doc/rustc-dev-guide/src/ty-fold.md | 2 +- src/doc/rustc-dev-guide/src/type-inference.md | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md index 2804c97724f..52e7400ffde 100644 --- a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md +++ b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md @@ -92,7 +92,7 @@ member constraints come in. ## Choices are always lifetime parameters At present, the "choice" regions from a member constraint are always lifetime -parameters from the current function. As of October 2021, +parameters from the current function. As of August 2025, this falls out from the placement of impl Trait, though in the future it may not be the case. We take some advantage of this fact, as it simplifies the current code. In particular, we don't have to consider a case like `'0 member of ['1, diff --git a/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md b/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md index 956f568285a..5a4a31e0a82 100644 --- a/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md +++ b/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md @@ -15,7 +15,7 @@ it implements `Bar`. Therefore, any of `Bar`'s interface can be used on a `Foo`, but nothing else (regardless of whether it implements any other traits). Since there needs to be a concrete background type, -you can (as of January 2021) express that type +you can (as of August 2025) express that type by using the opaque type in a "defining use site". ```rust,ignore diff --git a/src/doc/rustc-dev-guide/src/stability.md b/src/doc/rustc-dev-guide/src/stability.md index 3c4c65fdd5a..665215fda04 100644 --- a/src/doc/rustc-dev-guide/src/stability.md +++ b/src/doc/rustc-dev-guide/src/stability.md @@ -30,7 +30,7 @@ unstable modules or vice versa. Previously, due to a [rustc bug], stable items inside unstable modules were available to stable code in that location. -As of September 2024, items with [accidentally stabilized +As of August 2025, items with [accidentally stabilized paths] are marked with the `#[rustc_allowed_through_unstable_modules]` attribute to prevent code dependent on those paths from breaking. Do *not* add this attribute to any more items unless that is needed to avoid breaking changes. diff --git a/src/doc/rustc-dev-guide/src/thir.md b/src/doc/rustc-dev-guide/src/thir.md index 3d3dafaef49..6a3525d5b8f 100644 --- a/src/doc/rustc-dev-guide/src/thir.md +++ b/src/doc/rustc-dev-guide/src/thir.md @@ -2,7 +2,7 @@ The THIR ("Typed High-Level Intermediate Representation"), previously called HAIR for "High-Level Abstract IR", is another IR used by rustc that is generated after -[type checking]. It is (as of January 2024) used for +[type checking]. It is (as of August 2025) used for [MIR construction], [exhaustiveness checking], and [unsafety checking]. [type checking]: ./type-checking.md @@ -52,7 +52,7 @@ fn main() { } ``` -Here is how that gets represented in THIR (as of Aug 2022): +Here is how that gets represented in THIR (as of August 2025): ```rust,no_run Thir { diff --git a/src/doc/rustc-dev-guide/src/traits/chalk.md b/src/doc/rustc-dev-guide/src/traits/chalk.md index 844f42b9879..eac8e6b5c20 100644 --- a/src/doc/rustc-dev-guide/src/traits/chalk.md +++ b/src/doc/rustc-dev-guide/src/traits/chalk.md @@ -1,7 +1,7 @@ # Chalk-based trait solving [Chalk][chalk] is an experimental trait solver for Rust that is -(as of May 2022) under development by the [Types team]. +(as of August 2025) under development by the [Types team]. Its goal is to enable a lot of trait system features and bug fixes that are hard to implement (e.g. GATs or specialization). If you would like to help in hacking on the new solver, drop by on the rust-lang Zulip in the [`#t-types`] diff --git a/src/doc/rustc-dev-guide/src/traits/resolution.md b/src/doc/rustc-dev-guide/src/traits/resolution.md index ccb2b04268e..711b7ebe65e 100644 --- a/src/doc/rustc-dev-guide/src/traits/resolution.md +++ b/src/doc/rustc-dev-guide/src/traits/resolution.md @@ -120,7 +120,7 @@ the obligation contains unbound inference variables. The subroutines that decide whether a particular impl/where-clause/etc applies to a particular obligation are collectively referred to as the process of -_matching_. For `impl` candidates , +_matching_. For `impl` candidates , this amounts to unifying the impl header (the `Self` type and the trait arguments) while ignoring nested obligations. If matching succeeds then we add it to a set of candidates. There are other rules when assembling candidates for diff --git a/src/doc/rustc-dev-guide/src/ty-fold.md b/src/doc/rustc-dev-guide/src/ty-fold.md index 23253022ffe..d0fa548a625 100644 --- a/src/doc/rustc-dev-guide/src/ty-fold.md +++ b/src/doc/rustc-dev-guide/src/ty-fold.md @@ -1,4 +1,4 @@ - + # `TypeFoldable` and `TypeFolder` In [a previous chapter], we discussed instantiating binders. diff --git a/src/doc/rustc-dev-guide/src/type-inference.md b/src/doc/rustc-dev-guide/src/type-inference.md index 2243205f129..0c7e2839b28 100644 --- a/src/doc/rustc-dev-guide/src/type-inference.md +++ b/src/doc/rustc-dev-guide/src/type-inference.md @@ -66,7 +66,7 @@ inference works, or perhaps this blog post on [Unification in the Chalk project]: http://smallcultfollowing.com/babysteps/blog/2017/03/25/unification-in-chalk-part-1/ All told, the inference context stores five kinds of inference variables -(as of March 2023): +(as of August 2025): - Type variables, which come in three varieties: - General type variables (the most common). These can be unified with any -- cgit 1.4.1-3-g733a5 From b0897f31b998472d024a2e00a7b00c5fc875351e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 29 Aug 2025 15:06:54 +0000 Subject: Update getopts to remove unicode-width dependency --- Cargo.lock | 6 +++--- library/Cargo.lock | 15 ++------------- library/test/Cargo.toml | 2 +- src/tools/tidy/src/deps.rs | 1 - 4 files changed, 6 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index 91528a4135e..82ba9ce178a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -674,7 +674,7 @@ checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" dependencies = [ "serde", "termcolor", - "unicode-width 0.2.1", + "unicode-width 0.1.14", ] [[package]] @@ -1470,9 +1470,9 @@ dependencies = [ [[package]] name = "getopts" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cba6ae63eb948698e300f645f87c70f76630d505f23b8907cf1e193ee85048c1" +checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df" dependencies = [ "unicode-width 0.2.1", ] diff --git a/library/Cargo.lock b/library/Cargo.lock index f0ac9d259c0..3fb6af2c598 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -99,13 +99,12 @@ dependencies = [ [[package]] name = "getopts" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cba6ae63eb948698e300f645f87c70f76630d505f23b8907cf1e193ee85048c1" +checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df" dependencies = [ "rustc-std-workspace-core", "rustc-std-workspace-std", - "unicode-width", ] [[package]] @@ -360,16 +359,6 @@ dependencies = [ "std", ] -[[package]] -name = "unicode-width" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" -dependencies = [ - "rustc-std-workspace-core", - "rustc-std-workspace-std", -] - [[package]] name = "unwind" version = "0.0.0" diff --git a/library/test/Cargo.toml b/library/test/Cargo.toml index 2a32a7dd76e..fe749847b7c 100644 --- a/library/test/Cargo.toml +++ b/library/test/Cargo.toml @@ -6,7 +6,7 @@ version = "0.0.0" edition = "2024" [dependencies] -getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] } +getopts = { version = "0.2.24", default-features = false, features = ['rustc-dep-of-std'] } std = { path = "../std", public = true } core = { path = "../core", public = true } diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 80b6d54ce1c..4efaf1fb771 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -478,7 +478,6 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[ "rustc-demangle", "rustc-literal-escaper", "shlex", - "unicode-width", "unwinding", "wasi", "windows-sys", -- cgit 1.4.1-3-g733a5 From 80c1ea31c75199e8f94d5da0f485f065f0729a79 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Fri, 29 Aug 2025 09:33:25 -0700 Subject: Update mdbook This updates mdbook to 0.4.52, which includes a number of fixes and enhancements since 0.4.48. Changelog: https://github.com/rust-lang/mdBook/blob/master/CHANGELOG.md#mdbook-0452 --- src/doc/rustc-dev-guide/.github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/.github/workflows/ci.yml b/src/doc/rustc-dev-guide/.github/workflows/ci.yml index 6eabb999fb0..2dd695b7a47 100644 --- a/src/doc/rustc-dev-guide/.github/workflows/ci.yml +++ b/src/doc/rustc-dev-guide/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: if: github.repository == 'rust-lang/rustc-dev-guide' runs-on: ubuntu-latest env: - MDBOOK_VERSION: 0.4.48 + MDBOOK_VERSION: 0.4.52 MDBOOK_LINKCHECK2_VERSION: 0.9.1 MDBOOK_MERMAID_VERSION: 0.12.6 MDBOOK_OUTPUT__LINKCHECK__FOLLOW_WEB_LINKS: ${{ github.event_name != 'pull_request' }} -- cgit 1.4.1-3-g733a5 From f9a596795ad127f14ecf94d5a03481b495cc4f1c Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Wed, 28 May 2025 21:20:41 +0100 Subject: Start documenting tests/rustdoc-json --- src/doc/rustc-dev-guide/src/compiler-src.md | 4 +- .../rustdoc-internals/rustdoc-json-test-suite.md | 46 +++++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/compiler-src.md b/src/doc/rustc-dev-guide/src/compiler-src.md index d67bacb1b33..11b7e15e30d 100644 --- a/src/doc/rustc-dev-guide/src/compiler-src.md +++ b/src/doc/rustc-dev-guide/src/compiler-src.md @@ -153,7 +153,8 @@ The bulk of [`rustdoc`] is in [`librustdoc`]. However, the [`rustdoc`] binary itself is [`src/tools/rustdoc`], which does nothing except call [`rustdoc::main`]. There is also `JavaScript` and `CSS` for the docs in [`src/tools/rustdoc-js`] -and [`src/tools/rustdoc-themes`]. +and [`src/tools/rustdoc-themes`]. The type definitions for `--output-format=json` +are in a seperate crate in [`src/rustdoc-json-types`]. You can read more about [`rustdoc`] in [this chapter][rustdoc-chapter]. @@ -162,6 +163,7 @@ You can read more about [`rustdoc`] in [this chapter][rustdoc-chapter]. [`src/tools/rustdoc-js`]: https://github.com/rust-lang/rust/tree/master/src/tools/rustdoc-js [`src/tools/rustdoc-themes`]: https://github.com/rust-lang/rust/tree/master/src/tools/rustdoc-themes [`src/tools/rustdoc`]: https://github.com/rust-lang/rust/tree/master/src/tools/rustdoc +[`src/rustdoc-json-types`]: https://github.com/rust-lang/rust/tree/master/src/rustdoc-json-types [rustdoc-chapter]: ./rustdoc.md ## Tests diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md index e08f7709506..79b2ede61da 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md @@ -1,3 +1,47 @@ # The `rustdoc-json` test suite -> **FIXME**: This section is a stub. It will be populated by [PR #2422](https://github.com/rust-lang/rustc-dev-guide/pull/2422/). +This page is specifically about the test suite named `rustdoc-json`, which tests rustdoc's [json output]. +For other test suites used for testing rustdoc, see [Rustdoc tests](../rustdoc.md#tests). + +Tests are run with compiletest, and have access to the usuall set of [directives](../tests/directives.md). +Frequenly used directives here are: + +- [`//@ aux-build`][aux-build] to have dependencies. +- `//@ edition: 2021` (or some other edition). +- `//@ compile-flags: --document-hidden-items` to enable [document private items]. + +Each crate's json output is checked by 2 programs: [jsondoclint] and [jsondocck]. + +## jsondoclint + +[jsondoclint] checks that all [`Id`]s exist in the `index` (or `paths`). +This makes sure their are no dangling [`Id`]s. + + + +## jsondocck + + + +### Directives + +- `//@ has `:: Checks `` exists, i.e. matches at least 1 value. +- `//@ !has `:: Checks `` doesn't exist, i.e. matches 0 values. +- `//@ has `: Check `` exists, and 1 of the matches is equal to the given `` +- `//@ !has `: Checks `` exists, but none of the matches equal the given ``. +- `//@ is `: Check `` matches exacly one value, and it's equal to the given ``. +- `//@ is ...`: Check that `` matches to exactly every given ``. + Ordering doesn't matter here. +- `//@ !is `: Check `` matches exactly one value, and that value is not equal to the given ``. +- `//@ count ` Check that `` matches to `` of values. + + + +[json output]: https://doc.rust-lang.org/nightly/rustdoc/unstable-features.html#json-output +[jsondocck]: https://github.com/rust-lang/rust/tree/master/src/tools/jsondocck +[jsondoclint]: https://github.com/rust-lang/rust/tree/master/src/tools/jsondoclint +[aux-build]: ../tests/compiletest.md#building-auxiliary-crates +[`Id`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc_json_types/struct.Id.html +[document private items]: https://doc.rust-lang.org/nightly/rustdoc/command-line-arguments.html#--document-private-items-show-items-that-are-not-public -- cgit 1.4.1-3-g733a5 From 93e65927f483c6cb2a76eb5294b0014e6866b7a0 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Sat, 30 Aug 2025 23:50:23 +0100 Subject: More docs --- src/doc/rustc-dev-guide/src/compiler-src.md | 2 +- .../rustdoc-internals/rustdoc-json-test-suite.md | 48 +++++++++++++++++++--- 2 files changed, 43 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/compiler-src.md b/src/doc/rustc-dev-guide/src/compiler-src.md index 11b7e15e30d..27b40f1fe01 100644 --- a/src/doc/rustc-dev-guide/src/compiler-src.md +++ b/src/doc/rustc-dev-guide/src/compiler-src.md @@ -154,7 +154,7 @@ itself is [`src/tools/rustdoc`], which does nothing except call [`rustdoc::main` There is also `JavaScript` and `CSS` for the docs in [`src/tools/rustdoc-js`] and [`src/tools/rustdoc-themes`]. The type definitions for `--output-format=json` -are in a seperate crate in [`src/rustdoc-json-types`]. +are in a separate crate in [`src/rustdoc-json-types`]. You can read more about [`rustdoc`] in [this chapter][rustdoc-chapter]. diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md index 79b2ede61da..efc576cc900 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md @@ -3,19 +3,19 @@ This page is specifically about the test suite named `rustdoc-json`, which tests rustdoc's [json output]. For other test suites used for testing rustdoc, see [Rustdoc tests](../rustdoc.md#tests). -Tests are run with compiletest, and have access to the usuall set of [directives](../tests/directives.md). +Tests are run with compiletest, and have access to the usual set of [directives](../tests/directives.md). Frequenly used directives here are: - [`//@ aux-build`][aux-build] to have dependencies. - `//@ edition: 2021` (or some other edition). - `//@ compile-flags: --document-hidden-items` to enable [document private items]. -Each crate's json output is checked by 2 programs: [jsondoclint] and [jsondocck]. +Each crate's json output is checked by 2 programs: [jsondoclint](#jsondocck) and [jsondocck](#jsondocck). ## jsondoclint [jsondoclint] checks that all [`Id`]s exist in the `index` (or `paths`). -This makes sure their are no dangling [`Id`]s. +This makes sure there are no dangling [`Id`]s. +[jsondocck] processes direcives given in comments, to assert that the values in the output are expected. +It's alot like [htmldocck](./rustdoc-test-suite.md) in that way. + +It uses [JSONPath] as a query language, which takes a path, and returns a *list* of values that that path is said to match to. ### Directives - `//@ has `:: Checks `` exists, i.e. matches at least 1 value. - `//@ !has `:: Checks `` doesn't exist, i.e. matches 0 values. -- `//@ has `: Check `` exists, and 1 of the matches is equal to the given `` +- `//@ has `: Check `` exists, and at least 1 of the matches is equal to the given `` - `//@ !has `: Checks `` exists, but none of the matches equal the given ``. -- `//@ is `: Check `` matches exacly one value, and it's equal to the given ``. +- `//@ is `: Check `` matches exactly one value, and it's equal to the given ``. - `//@ is ...`: Check that `` matches to exactly every given ``. Ordering doesn't matter here. - `//@ !is `: Check `` matches exactly one value, and that value is not equal to the given ``. - `//@ count ` Check that `` matches to `` of values. +- `//@ set = `, Check that `` matches exactly one value, and store that value to the variable called `` + +These are defined in [`directive.rs`]. + +### Values + +Values can be either JSON values, or variables. + +- JSON values are JSON literals, e.g. `true`, `"string"`, `{"key": "value"}`. + These often need to be quoted using `'`, to be processed as 1 value. See [§Argument spliting](#argument-spliting) +- Variables can be used to store the value in one path, and use it in later queries. + They are set with the `//@ set = ` directive, and accessed with `$` + + ```rust + //@ set foo = $some.path + //@ is $.some.other.path $foo + ``` + +### Argument spliting + +Arguments to directives are split using the [shlex] crate, which implements POSIX shell escaping. +This is because both `` and `` arguments to [directives](#directives) frequently have both +whitespace and quote marks. + +To use the `@ is` with a `` of `$.index[?(@.docs == "foo")].some.field` and a value of `"bar"` [^why quote], you'd write: +```rust +//@ is '$.is[?(@.docs == "foo")].some.field' '"bar"' +``` +[^why quote]: The value needs to be `"bar"` *after* shlex splitting, because we + it needs to be a JSON string value. [json output]: https://doc.rust-lang.org/nightly/rustdoc/unstable-features.html#json-output [jsondocck]: https://github.com/rust-lang/rust/tree/master/src/tools/jsondocck @@ -45,3 +78,6 @@ Also, talk about how it works [aux-build]: ../tests/compiletest.md#building-auxiliary-crates [`Id`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc_json_types/struct.Id.html [document private items]: https://doc.rust-lang.org/nightly/rustdoc/command-line-arguments.html#--document-private-items-show-items-that-are-not-public +[`directive.rs`]: https://github.com/rust-lang/rust/blob/master/src/tools/jsondocck/src/directive.rs +[shlex]: https://docs.rs/shlex/1.3.0/shlex/index.html +[JSONPath]: https://www.rfc-editor.org/rfc/rfc9535.html -- cgit 1.4.1-3-g733a5 From c206945328050c45704f64e77ac88a19b5bac4a4 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 1 Sep 2025 11:10:19 +0200 Subject: Revert "dates: refresh type system & traits date annotations to Aug/2025" --- .../src/borrow_check/region_inference/member_constraints.md | 2 +- src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md | 2 +- src/doc/rustc-dev-guide/src/stability.md | 2 +- src/doc/rustc-dev-guide/src/thir.md | 4 ++-- src/doc/rustc-dev-guide/src/traits/chalk.md | 2 +- src/doc/rustc-dev-guide/src/traits/resolution.md | 2 +- src/doc/rustc-dev-guide/src/ty-fold.md | 2 +- src/doc/rustc-dev-guide/src/type-inference.md | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md index 52e7400ffde..2804c97724f 100644 --- a/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md +++ b/src/doc/rustc-dev-guide/src/borrow_check/region_inference/member_constraints.md @@ -92,7 +92,7 @@ member constraints come in. ## Choices are always lifetime parameters At present, the "choice" regions from a member constraint are always lifetime -parameters from the current function. As of August 2025, +parameters from the current function. As of October 2021, this falls out from the placement of impl Trait, though in the future it may not be the case. We take some advantage of this fact, as it simplifies the current code. In particular, we don't have to consider a case like `'0 member of ['1, diff --git a/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md b/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md index 5a4a31e0a82..956f568285a 100644 --- a/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md +++ b/src/doc/rustc-dev-guide/src/opaque-types-type-alias-impl-trait.md @@ -15,7 +15,7 @@ it implements `Bar`. Therefore, any of `Bar`'s interface can be used on a `Foo`, but nothing else (regardless of whether it implements any other traits). Since there needs to be a concrete background type, -you can (as of August 2025) express that type +you can (as of January 2021) express that type by using the opaque type in a "defining use site". ```rust,ignore diff --git a/src/doc/rustc-dev-guide/src/stability.md b/src/doc/rustc-dev-guide/src/stability.md index 665215fda04..3c4c65fdd5a 100644 --- a/src/doc/rustc-dev-guide/src/stability.md +++ b/src/doc/rustc-dev-guide/src/stability.md @@ -30,7 +30,7 @@ unstable modules or vice versa. Previously, due to a [rustc bug], stable items inside unstable modules were available to stable code in that location. -As of August 2025, items with [accidentally stabilized +As of September 2024, items with [accidentally stabilized paths] are marked with the `#[rustc_allowed_through_unstable_modules]` attribute to prevent code dependent on those paths from breaking. Do *not* add this attribute to any more items unless that is needed to avoid breaking changes. diff --git a/src/doc/rustc-dev-guide/src/thir.md b/src/doc/rustc-dev-guide/src/thir.md index 6a3525d5b8f..3d3dafaef49 100644 --- a/src/doc/rustc-dev-guide/src/thir.md +++ b/src/doc/rustc-dev-guide/src/thir.md @@ -2,7 +2,7 @@ The THIR ("Typed High-Level Intermediate Representation"), previously called HAIR for "High-Level Abstract IR", is another IR used by rustc that is generated after -[type checking]. It is (as of August 2025) used for +[type checking]. It is (as of January 2024) used for [MIR construction], [exhaustiveness checking], and [unsafety checking]. [type checking]: ./type-checking.md @@ -52,7 +52,7 @@ fn main() { } ``` -Here is how that gets represented in THIR (as of August 2025): +Here is how that gets represented in THIR (as of Aug 2022): ```rust,no_run Thir { diff --git a/src/doc/rustc-dev-guide/src/traits/chalk.md b/src/doc/rustc-dev-guide/src/traits/chalk.md index eac8e6b5c20..844f42b9879 100644 --- a/src/doc/rustc-dev-guide/src/traits/chalk.md +++ b/src/doc/rustc-dev-guide/src/traits/chalk.md @@ -1,7 +1,7 @@ # Chalk-based trait solving [Chalk][chalk] is an experimental trait solver for Rust that is -(as of August 2025) under development by the [Types team]. +(as of May 2022) under development by the [Types team]. Its goal is to enable a lot of trait system features and bug fixes that are hard to implement (e.g. GATs or specialization). If you would like to help in hacking on the new solver, drop by on the rust-lang Zulip in the [`#t-types`] diff --git a/src/doc/rustc-dev-guide/src/traits/resolution.md b/src/doc/rustc-dev-guide/src/traits/resolution.md index 711b7ebe65e..ccb2b04268e 100644 --- a/src/doc/rustc-dev-guide/src/traits/resolution.md +++ b/src/doc/rustc-dev-guide/src/traits/resolution.md @@ -120,7 +120,7 @@ the obligation contains unbound inference variables. The subroutines that decide whether a particular impl/where-clause/etc applies to a particular obligation are collectively referred to as the process of -_matching_. For `impl` candidates , +_matching_. For `impl` candidates , this amounts to unifying the impl header (the `Self` type and the trait arguments) while ignoring nested obligations. If matching succeeds then we add it to a set of candidates. There are other rules when assembling candidates for diff --git a/src/doc/rustc-dev-guide/src/ty-fold.md b/src/doc/rustc-dev-guide/src/ty-fold.md index d0fa548a625..23253022ffe 100644 --- a/src/doc/rustc-dev-guide/src/ty-fold.md +++ b/src/doc/rustc-dev-guide/src/ty-fold.md @@ -1,4 +1,4 @@ - + # `TypeFoldable` and `TypeFolder` In [a previous chapter], we discussed instantiating binders. diff --git a/src/doc/rustc-dev-guide/src/type-inference.md b/src/doc/rustc-dev-guide/src/type-inference.md index 0c7e2839b28..2243205f129 100644 --- a/src/doc/rustc-dev-guide/src/type-inference.md +++ b/src/doc/rustc-dev-guide/src/type-inference.md @@ -66,7 +66,7 @@ inference works, or perhaps this blog post on [Unification in the Chalk project]: http://smallcultfollowing.com/babysteps/blog/2017/03/25/unification-in-chalk-part-1/ All told, the inference context stores five kinds of inference variables -(as of August 2025): +(as of March 2023): - Type variables, which come in three varieties: - General type variables (the most common). These can be unified with any -- cgit 1.4.1-3-g733a5 From eab1ffd520f375a58b19810d94205ef04ca361e0 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 1 Sep 2025 11:13:46 +0200 Subject: Revert "dates: refresh query-system date annotations to 2025-08 (preserve style)" --- src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md | 2 +- src/doc/rustc-dev-guide/src/queries/salsa.md | 2 +- src/doc/rustc-dev-guide/src/query.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md b/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md index f487707cd32..c1a4373f7da 100644 --- a/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md +++ b/src/doc/rustc-dev-guide/src/queries/query-evaluation-model-in-detail.md @@ -74,7 +74,7 @@ executed, no results are cached. But the context already provides access to "input" data, i.e. pieces of immutable data that were computed before the context was created and that queries can access to do their computations. -As of August 2025, this input data consists mainly of +As of January 2021, this input data consists mainly of the HIR map, upstream crate metadata, and the command-line options the compiler was invoked with; but in the future inputs will just consist of command-line options and a list of source files -- the HIR map will itself be provided by a diff --git a/src/doc/rustc-dev-guide/src/queries/salsa.md b/src/doc/rustc-dev-guide/src/queries/salsa.md index c0caa201f97..dc7160edc22 100644 --- a/src/doc/rustc-dev-guide/src/queries/salsa.md +++ b/src/doc/rustc-dev-guide/src/queries/salsa.md @@ -7,7 +7,7 @@ want to watch [Salsa In More Depth](https://www.youtube.com/watch?v=i_IhACacPRY), also by Niko Matsakis. -> As of August 2025, although Salsa is inspired by (among +> As of November 2022, although Salsa is inspired by (among > other things) rustc's query system, it is not used directly in rustc. It > _is_ used in [chalk], an implementation of Rust's trait system, and > extensively in [`rust-analyzer`], the official implementation of the language diff --git a/src/doc/rustc-dev-guide/src/query.md b/src/doc/rustc-dev-guide/src/query.md index 0a927319471..8377a7b2f31 100644 --- a/src/doc/rustc-dev-guide/src/query.md +++ b/src/doc/rustc-dev-guide/src/query.md @@ -1,7 +1,7 @@ # Queries: demand-driven compilation As described in [Overview of the compiler], the Rust compiler -is still (as of August 2025) transitioning from a +is still (as of July 2021) transitioning from a traditional "pass-based" setup to a "demand-driven" system. The compiler query system is the key to rustc's demand-driven organization. The idea is pretty simple. Instead of entirely independent passes -- cgit 1.4.1-3-g733a5 From 4ed4837c2bc21ecfc768d1addd9ec7434bdc600e Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 1 Sep 2025 11:19:14 +0200 Subject: Revert "dates: refresh infra/tooling date annotations to Aug 2025" --- src/doc/rustc-dev-guide/src/backend/updating-llvm.md | 4 ++-- src/doc/rustc-dev-guide/src/fuzzing.md | 2 +- src/doc/rustc-dev-guide/src/overview.md | 2 +- src/doc/rustc-dev-guide/src/parallel-rustc.md | 8 ++++---- src/doc/rustc-dev-guide/src/profiling.md | 2 +- src/doc/rustc-dev-guide/src/rustdoc-internals.md | 6 +++--- 6 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md index a4e22b73984..ebef15d40ba 100644 --- a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md +++ b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md @@ -1,6 +1,6 @@ # Updating LLVM - + Rust supports building against multiple LLVM versions: * Tip-of-tree for the current LLVM development branch is usually supported @@ -93,7 +93,7 @@ An example PR: ## New LLVM Release Updates - + Unlike bugfixes, updating to a new release of LLVM typically requires a lot more work. diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 540a8c69061..30005378617 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -1,6 +1,6 @@ # Fuzzing - + For the purposes of this guide, *fuzzing* is any testing methodology that involves compiling a wide variety of programs in an attempt to uncover bugs in diff --git a/src/doc/rustc-dev-guide/src/overview.md b/src/doc/rustc-dev-guide/src/overview.md index 9f0201942d0..378d8c4453f 100644 --- a/src/doc/rustc-dev-guide/src/overview.md +++ b/src/doc/rustc-dev-guide/src/overview.md @@ -304,7 +304,7 @@ Moreover, the compiler wasn't originally built to use a query system; the query system has been retrofitted into the compiler, so parts of it are not query-fied yet. Also, LLVM isn't our code, so that isn't querified either. The plan is to eventually query-fy all of the steps listed in the previous section, -but as of August 2025, only the steps between `HIR` and +but as of November 2022, only the steps between `HIR` and `LLVM-IR` are query-fied. That is, lexing, parsing, name resolution, and macro expansion are done all at once for the whole program. diff --git a/src/doc/rustc-dev-guide/src/parallel-rustc.md b/src/doc/rustc-dev-guide/src/parallel-rustc.md index b448243223f..ce69b66c2da 100644 --- a/src/doc/rustc-dev-guide/src/parallel-rustc.md +++ b/src/doc/rustc-dev-guide/src/parallel-rustc.md @@ -1,14 +1,14 @@ # Parallel compilation
-As of August 2025, +As of November 2024, the parallel front-end is undergoing significant changes, so this page contains quite a bit of outdated information. Tracking issue:
-As of August 2025, most of the rust compiler is now +As of November 2024, most of the rust compiler is now parallelized. - The codegen part is executed concurrently by default. You can use the `-C @@ -104,7 +104,7 @@ when `parallel-compiler` is true. | **ModuleItems::par_foreign_items**(&self, f: impl Fn(ForeignItemId)) | run `f` on all foreign items in the module | rustc_middle::hir | There are a lot of loops in the compiler which can possibly be parallelized -using these functions. As of August 2025, scenarios where +using these functions. As of August 2022, scenarios where the parallel iterator function has been used are as follows: | caller | scenario | callee | @@ -155,7 +155,7 @@ open feature tracking issue][tracking]. ## Rustdoc -As of August 2025, there are still a number of steps to +As of November 2022, there are still a number of steps to complete before `rustdoc` rendering can be made parallel (see a open discussion of [parallel `rustdoc`][parallel-rustdoc]). diff --git a/src/doc/rustc-dev-guide/src/profiling.md b/src/doc/rustc-dev-guide/src/profiling.md index 7dfd74aba3a..de06bd7cda7 100644 --- a/src/doc/rustc-dev-guide/src/profiling.md +++ b/src/doc/rustc-dev-guide/src/profiling.md @@ -108,6 +108,6 @@ The llvm-lines output is affected by several options. MIR optimizations have little impact. Compared to the default `RUSTFLAGS="-Z mir-opt-level=1"`, level 0 adds 0.3GB and level 2 removes 0.2GB. -As of August 2025, +As of July 2022, inlining happens in LLVM and GCC codegen backends, missing only in the Cranelift one. diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals.md b/src/doc/rustc-dev-guide/src/rustdoc-internals.md index 02abce2e63a..4affbafe477 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals.md @@ -99,7 +99,7 @@ regarding dropping private/hidden items can be bypassed by passing `--document-private-items` to `rustdoc`. Note that unlike the previous set of [`AST`][ast] transformations, the passes are run on the _cleaned_ crate. -Here is the list of passes as of August 2025: +Here is the list of passes as of March 2023: - `calculate-doc-coverage` calculates information used for the `--show-coverage` flag. @@ -122,7 +122,7 @@ Here is the list of passes as of August 2025: - `bare_urls` detects links that are not linkified, e.g., in Markdown such as `Go to https://example.com/.` It suggests wrapping the link with angle brackets: `Go to .` to linkify it. This is the code behind the `rustdoc::bare_urls` `lint`. + date-check: may 2022 --> `rustdoc::bare_urls` `lint`. - `check_code_block_syntax` validates syntax inside Rust code blocks (```rust) @@ -212,7 +212,7 @@ directly, even during `HTML` generation. This [didn't used to be the case], and a lot of `rustdoc`'s architecture was designed around not doing that, but a `TyCtxt` is now passed to `formats::renderer::run_format`, which is used to run generation for both `HTML` and the -(unstable as of August 2025) JSON format. +(unstable as of March 2023) JSON format. This change has allowed other changes to remove data from the "clean" [`AST`][ast] that can be easily derived from `TyCtxt` queries, and we'll usually accept -- cgit 1.4.1-3-g733a5 From 2453e05b1d4f0a62b3c2aa85a8ee72b900159127 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 1 Sep 2025 11:21:20 +0200 Subject: Revert "dates: refresh diagnostics/ and tests/ annotated dates to August 2025" --- src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md | 2 +- src/doc/rustc-dev-guide/src/diagnostics/error-codes.md | 2 +- src/doc/rustc-dev-guide/src/diagnostics/lintstore.md | 2 +- src/doc/rustc-dev-guide/src/diagnostics/translation.md | 4 ++-- src/doc/rustc-dev-guide/src/tests/ci.md | 2 +- src/doc/rustc-dev-guide/src/tests/directives.md | 4 ++-- src/doc/rustc-dev-guide/src/tests/misc.md | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md index 4000cbdb8ce..9360427d660 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md @@ -48,7 +48,7 @@ A new diagnostic item can be added with these two steps: For the naming conventions of diagnostic items, please refer to [*Naming Conventions*](#naming-conventions). -2. +2. Diagnostic items in code are accessed via symbols in [`rustc_span::symbol::sym`]. To add your newly-created diagnostic item, diff --git a/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md b/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md index 98d9a7ab0a1..1693432b90d 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/error-codes.md @@ -10,7 +10,7 @@ explanation: new error codes must include them. Note that not all _historical_ The explanations are written in Markdown (see the [CommonMark Spec] for specifics around syntax), and all of them are linked in the [`rustc_error_codes`] crate. Please read [RFC 1567] for details on how to format and write long error -codes. As of August 2025, there is an +codes. As of February 2023, there is an effort[^new-explanations] to replace this largely outdated RFC with a new more flexible standard. diff --git a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md index f0d349c91b9..7b98bc62116 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md @@ -21,7 +21,7 @@ which boils down to a static with type [`&rustc_lint_defs::Lint`] as the macro is somewhat unwieldy to add new fields to, like all macros). -As of Aug 2025, +As of Aug 2022, we lint against direct declarations without the use of the macro. Lint declarations don't carry any "state" - they are merely global identifiers diff --git a/src/doc/rustc-dev-guide/src/diagnostics/translation.md b/src/doc/rustc-dev-guide/src/diagnostics/translation.md index 5d143da2bad..58d75f54a00 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/translation.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/translation.md @@ -2,12 +2,12 @@
rustc's current diagnostics translation infrastructure (as of - August 2025 + October 2024 ) unfortunately causes some friction for compiler contributors, and the current infrastructure is mostly pending a redesign that better addresses needs of both compiler contributors and translation teams. Note that there is no current active redesign proposals (as of - August 2025 + October 2024 )! Please see the tracking issue diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index 95850c07cfe..a8cc959124f 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -22,7 +22,7 @@ jobs](#modifying-ci-jobs). ## CI workflow - + Our CI is primarily executed on [GitHub Actions], with a single workflow defined in [`.github/workflows/ci.yml`], which contains a bunch of steps that are diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index 6cf73909b11..fbbeb7e97d3 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -42,7 +42,7 @@ not be exhaustive. Directives can generally be found by browsing the ### Assembly - + | Directive | Explanation | Supported test suites | Possible values | |-------------------|-------------------------------|-----------------------|----------------------------------------| @@ -113,7 +113,7 @@ for more details. | `known-bug` | No error annotation needed due to known bug | `ui`, `crashes`, `incremental` | Issue number `#123456` | | `compare-output-by-lines` | Compare the output by lines, rather than as a single string | All | N/A | -[^check_stdout]: presently this has a weird quirk +[^check_stdout]: presently this has a weird quirk where the test binary's stdout and stderr gets concatenated and then `error-pattern`s are matched on this combined output, which is ??? slightly questionable to say the least. diff --git a/src/doc/rustc-dev-guide/src/tests/misc.md b/src/doc/rustc-dev-guide/src/tests/misc.md index ed80c6c3479..39f88174879 100644 --- a/src/doc/rustc-dev-guide/src/tests/misc.md +++ b/src/doc/rustc-dev-guide/src/tests/misc.md @@ -2,7 +2,7 @@ ## `RUSTC_BOOTSTRAP` and stability - + This is a bootstrap/compiler implementation detail, but it can also be useful for testing: -- cgit 1.4.1-3-g733a5 From b7f3606a183bcf865dce31bbd76ce6171b062d68 Mon Sep 17 00:00:00 2001 From: Emmet Horgan Date: Wed, 3 Sep 2025 23:29:54 +0100 Subject: Fix some broken links Signed-off-by: Emmet Horgan --- src/doc/rustc-dev-guide/src/appendix/code-index.md | 2 +- src/doc/rustc-dev-guide/src/compiler-debugging.md | 2 +- src/doc/rustc-dev-guide/src/hir.md | 2 +- src/doc/rustc-dev-guide/src/serialization.md | 2 +- src/doc/rustc-dev-guide/src/tests/directives.md | 10 +++++----- 5 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/appendix/code-index.md b/src/doc/rustc-dev-guide/src/appendix/code-index.md index 65fbf752d79..0ad72443935 100644 --- a/src/doc/rustc-dev-guide/src/appendix/code-index.md +++ b/src/doc/rustc-dev-guide/src/appendix/code-index.md @@ -13,7 +13,7 @@ Item | Kind | Short description | Chapter | `DefId` | struct | One of four types of HIR node identifiers | [Identifiers in the HIR] | [compiler/rustc_hir/src/def_id.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefId.html) `Diag` | struct | A struct for a compiler diagnostic, such as an error or lint | [Emitting Diagnostics] | [compiler/rustc_errors/src/diagnostic.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html) `DocContext` | struct | A state container used by rustdoc when crawling through a crate to gather its documentation | [Rustdoc] | [src/librustdoc/core.rs](https://github.com/rust-lang/rust/blob/master/src/librustdoc/core.rs) -`HirId` | struct | One of four types of HIR node identifiers | [Identifiers in the HIR] | [compiler/rustc_hir/src/hir_id.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir_id/struct.HirId.html) +`HirId` | struct | One of four types of HIR node identifiers | [Identifiers in the HIR] | [compiler/rustc_hir/src/hir_id.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/struct.HirId.html) `Lexer` | struct | This is the lexer used during parsing. It consumes characters from the raw source code being compiled and produces a series of tokens for use by the rest of the parser | [The parser] | [compiler/rustc_parse/src/lexer/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.Lexer.html) `NodeId` | struct | One of four types of HIR node identifiers. Being phased out | [Identifiers in the HIR] | [compiler/rustc_ast/src/ast.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/node_id/struct.NodeId.html) `P` | struct | An owned immutable smart pointer. By contrast, `&T` is not owned, and `Box` is not immutable. | None | [compiler/rustc_ast/src/ptr.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ptr/struct.P.html) diff --git a/src/doc/rustc-dev-guide/src/compiler-debugging.md b/src/doc/rustc-dev-guide/src/compiler-debugging.md index edd2aa6c5f6..5ceb5dfe811 100644 --- a/src/doc/rustc-dev-guide/src/compiler-debugging.md +++ b/src/doc/rustc-dev-guide/src/compiler-debugging.md @@ -367,7 +367,7 @@ error: layout_of(&'a u32) = Layout { error: aborting due to previous error ``` -[`Layout`]: https://doc.rust-lang.org/nightly/nightly-rustc/stable_mir/abi/struct.Layout.html +[`Layout`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_abi/struct.Layout.html ## Configuring CodeLLDB for debugging `rustc` diff --git a/src/doc/rustc-dev-guide/src/hir.md b/src/doc/rustc-dev-guide/src/hir.md index 38ba33112f2..0b341a40f1d 100644 --- a/src/doc/rustc-dev-guide/src/hir.md +++ b/src/doc/rustc-dev-guide/src/hir.md @@ -102,7 +102,7 @@ These identifiers can be converted into one another through the `TyCtxt`. [`DefId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefId.html [`LocalDefId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.LocalDefId.html -[`HirId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir_id/struct.HirId.html +[`HirId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/struct.HirId.html [`BodyId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.BodyId.html [Node]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.Node.html [`CrateNum`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.CrateNum.html diff --git a/src/doc/rustc-dev-guide/src/serialization.md b/src/doc/rustc-dev-guide/src/serialization.md index 8eb37bbe20b..702d3cfa6d5 100644 --- a/src/doc/rustc-dev-guide/src/serialization.md +++ b/src/doc/rustc-dev-guide/src/serialization.md @@ -106,7 +106,7 @@ type wrapper, like [`ty::Predicate`] and manually implementing `Encodable` and [`Encodable`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_serialize/trait.Encodable.html [`Encoder`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_serialize/trait.Encoder.html [`RefDecodable`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/codec/trait.RefDecodable.html -[`rustc_middle`]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_type_ir/codec.rs.html#21 +[`rustc_middle`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/index.html [`ty::Predicate`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/predicate/struct.Predicate.html [`TyCtxt`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html [`TyDecodable`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_macros/derive.TyDecodable.html diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index fbbeb7e97d3..c6d83e82ab1 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -38,7 +38,7 @@ sections that describe the command in more detail if available. This list may not be exhaustive. Directives can generally be found by browsing the `TestProps` structure found in [`header.rs`] from the compiletest source. -[`header.rs`]: https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/header.rs +[`header.rs`]: https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/directives.rs ### Assembly @@ -374,7 +374,7 @@ the directive's backing store (holds the command's current value) at runtime. To add a new directive property: 1. Look for the `pub struct TestProps` declaration in - [`src/tools/compiletest/src/header.rs`] and add the new public property to + [`src/tools/compiletest/src/directives.rs`] and add the new public property to the end of the declaration. 2. Look for the `impl TestProps` implementation block immediately following the struct declaration and initialize the new property to its default value. @@ -383,7 +383,7 @@ To add a new directive property: When `compiletest` encounters a test file, it parses the file a line at a time by calling every parser defined in the `Config` struct's implementation block, -also in [`src/tools/compiletest/src/header.rs`] (note that the `Config` struct's +also in [`src/tools/compiletest/src/directives.rs`] (note that the `Config` struct's declaration block is found in [`src/tools/compiletest/src/common.rs`]). `TestProps`'s `load_from()` method will try passing the current line of text to each parser, which, in turn typically checks to see if the line begins with a @@ -406,7 +406,7 @@ and their associated parsers immediately above to see how they are used to avoid writing additional parsing code unnecessarily. As a concrete example, here is the implementation for the -`parse_failure_status()` parser, in [`src/tools/compiletest/src/header.rs`]: +`parse_failure_status()` parser, in [`src/tools/compiletest/src/directives.rs`]: ```diff @@ -232,6 +232,7 @@ pub struct TestProps { @@ -508,6 +508,6 @@ example, `//@ failure-status: 1`, `self.props.failure_status` will evaluate to 1, as `parse_failure_status()` will have overridden the `TestProps` default value, for that test specifically. -[`src/tools/compiletest/src/header.rs`]: https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/header.rs +[`src/tools/compiletest/src/directives.rs`]: https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/directives.rs [`src/tools/compiletest/src/common.rs`]: https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/common.rs [`src/tools/compiletest/src/runtest.rs`]: https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/runtest.rs -- cgit 1.4.1-3-g733a5 From 07ae014a929344156e0fc4abbe7841fb770a71e4 Mon Sep 17 00:00:00 2001 From: emmet-horgan <80120110+emmet-horgan@users.noreply.github.com> Date: Thu, 4 Sep 2025 10:56:58 +0100 Subject: Update src/appendix/code-index.md Fix display string Co-authored-by: Tshepang Mbambo --- src/doc/rustc-dev-guide/src/appendix/code-index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/appendix/code-index.md b/src/doc/rustc-dev-guide/src/appendix/code-index.md index 0ad72443935..4ddb58b0c39 100644 --- a/src/doc/rustc-dev-guide/src/appendix/code-index.md +++ b/src/doc/rustc-dev-guide/src/appendix/code-index.md @@ -13,7 +13,7 @@ Item | Kind | Short description | Chapter | `DefId` | struct | One of four types of HIR node identifiers | [Identifiers in the HIR] | [compiler/rustc_hir/src/def_id.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefId.html) `Diag` | struct | A struct for a compiler diagnostic, such as an error or lint | [Emitting Diagnostics] | [compiler/rustc_errors/src/diagnostic.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diag.html) `DocContext` | struct | A state container used by rustdoc when crawling through a crate to gather its documentation | [Rustdoc] | [src/librustdoc/core.rs](https://github.com/rust-lang/rust/blob/master/src/librustdoc/core.rs) -`HirId` | struct | One of four types of HIR node identifiers | [Identifiers in the HIR] | [compiler/rustc_hir/src/hir_id.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/struct.HirId.html) +`HirId` | struct | One of four types of HIR node identifiers | [Identifiers in the HIR] | [compiler/rustc_hir_id/src/lib.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/struct.HirId.html) `Lexer` | struct | This is the lexer used during parsing. It consumes characters from the raw source code being compiled and produces a series of tokens for use by the rest of the parser | [The parser] | [compiler/rustc_parse/src/lexer/mod.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/lexer/struct.Lexer.html) `NodeId` | struct | One of four types of HIR node identifiers. Being phased out | [Identifiers in the HIR] | [compiler/rustc_ast/src/ast.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/node_id/struct.NodeId.html) `P` | struct | An owned immutable smart pointer. By contrast, `&T` is not owned, and `Box` is not immutable. | None | [compiler/rustc_ast/src/ptr.rs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ptr/struct.P.html) -- cgit 1.4.1-3-g733a5 From 7ad4c6ac02e9bbb93f7c89809be37f7e7d684b9c Mon Sep 17 00:00:00 2001 From: emmet-horgan <80120110+emmet-horgan@users.noreply.github.com> Date: Thu, 4 Sep 2025 11:00:25 +0100 Subject: Update src/compiler-debugging.md Change to public abi Co-authored-by: Tshepang Mbambo --- src/doc/rustc-dev-guide/src/compiler-debugging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/compiler-debugging.md b/src/doc/rustc-dev-guide/src/compiler-debugging.md index 5ceb5dfe811..f4514470418 100644 --- a/src/doc/rustc-dev-guide/src/compiler-debugging.md +++ b/src/doc/rustc-dev-guide/src/compiler-debugging.md @@ -367,7 +367,7 @@ error: layout_of(&'a u32) = Layout { error: aborting due to previous error ``` -[`Layout`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_abi/struct.Layout.html +[`Layout`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_public/abi/struct.Layout.html ## Configuring CodeLLDB for debugging `rustc` -- cgit 1.4.1-3-g733a5 From 2a7331a80d1d4b312fec16e6f1d186f77259c6db Mon Sep 17 00:00:00 2001 From: Emmet Horgan Date: Thu, 4 Sep 2025 12:46:12 +0100 Subject: Fix user facing string Signed-off-by: Emmet Horgan --- src/doc/rustc-dev-guide/src/tests/directives.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index c6d83e82ab1..f58ee669a25 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -36,9 +36,9 @@ directive. The following is a list of compiletest directives. Directives are linked to sections that describe the command in more detail if available. This list may not be exhaustive. Directives can generally be found by browsing the -`TestProps` structure found in [`header.rs`] from the compiletest source. +`TestProps` structure found in [`directives.rs`] from the compiletest source. -[`header.rs`]: https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/directives.rs +[`directives.rs`]: https://github.com/rust-lang/rust/tree/master/src/tools/compiletest/src/directives.rs ### Assembly -- cgit 1.4.1-3-g733a5 From f374dce1d9dad014a79637af20ce551da79fd60d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Fri, 5 Sep 2025 10:21:25 +0200 Subject: clarify typo pr guidance --- src/doc/rustc-dev-guide/src/contributing.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 1ade4953d2e..8b1e05e1cf4 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -370,8 +370,10 @@ You can also use `rustdoc` directly to check small fixes. For example, `rustdoc src/doc/reference.md` will render reference to `doc/reference.html`. The CSS might be messed up, but you can verify that the HTML is right. -Please notice that at this time we don't accept typography/spellcheck fixes to **internal documentation** (example: -tests, library or compiler code) as it's usually not worth the churn or the review time. +Please notice that we don't accept typography/spellcheck fixes to **internal documentation** +as it's usually not worth the churn or the review time. +Examples of internal documentation is code comments and rustc api docs. +However, feel free to fix those if accompanied by other improvements in the same PR. ### Contributing to rustc-dev-guide -- cgit 1.4.1-3-g733a5 From b76461678a24c6e40effe9b7d6aa0cccca13d09d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Fri, 5 Sep 2025 10:28:12 +0200 Subject: sembr --- src/doc/rustc-dev-guide/src/contributing.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 1ade4953d2e..af4de28ab09 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -154,9 +154,14 @@ The CI in rust-lang/rust applies your patches directly against the current maste not against the commit your branch is based on. This can lead to unexpected failures if your branch is outdated, even when there are no explicit merge conflicts. -Update your branch only when needed: when you have merge conflicts, upstream CI is broken and blocking your green PR, or a maintainer requests it. Avoid updating an already-green PR under review unless necessary. During review, make incremental commits to address feedback. Prefer to squash or rebase only at the end, or when a reviewer requests it. +Update your branch only when needed: when you have merge conflicts, upstream CI is broken and blocking your green PR, or a maintainer requests it. +Avoid updating an already-green PR under review unless necessary. +During review, make incremental commits to address feedback. +Prefer to squash or rebase only at the end, or when a reviewer requests it. -When updating, use `git push --force-with-lease` and leave a brief comment explaining what changed. Some repos prefer merging from `upstream/master` instead of rebasing; follow the project's conventions. See [keeping things up to date](git.md#keeping-things-up-to-date) for detailed instructions. +When updating, use `git push --force-with-lease` and leave a brief comment explaining what changed. +Some repos prefer merging from `upstream/master` instead of rebasing; follow the project's conventions. +See [keeping things up to date](git.md#keeping-things-up-to-date) for detailed instructions. After rebasing, it's recommended to [run the relevant tests locally](tests/intro.md) to catch any issues before CI runs. @@ -435,7 +440,8 @@ Just a few things to keep in mind: #### ⚠️ Note: Where to contribute `rustc-dev-guide` changes -For detailed information about where to contribute rustc-dev-guide changes and the benefits of doing so, see [the rustc-dev-guide working group documentation](https://forge.rust-lang.org/wg-rustc-dev-guide/index.html#where-to-contribute-rustc-dev-guide-changes). +For detailed information about where to contribute rustc-dev-guide changes and the benefits of doing so, +see [the rustc-dev-guide working group documentation](https://forge.rust-lang.org/wg-rustc-dev-guide/index.html#where-to-contribute-rustc-dev-guide-changes). ## Issue triage -- cgit 1.4.1-3-g733a5 From 4d69a29e447059f2477f5976904af69682388603 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Fri, 5 Sep 2025 10:41:14 +0200 Subject: avoid inline external links --- src/doc/rustc-dev-guide/src/contributing.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index af4de28ab09..18f2dcb21ba 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -26,8 +26,7 @@ conditions that trigger the bug, or part of the error message if there is any. An example could be: **"impossible case reached" on lifetime inference for impl Trait in return position**. -Opening an issue is as easy as following [this -link](https://github.com/rust-lang/rust/issues/new/choose) and filling out the fields +Opening an issue is as easy as following [thi link][create an issue] and filling out the fields in the appropriate provided template. ## Bug fixes or "normal" code changes @@ -441,7 +440,7 @@ Just a few things to keep in mind: #### ⚠️ Note: Where to contribute `rustc-dev-guide` changes For detailed information about where to contribute rustc-dev-guide changes and the benefits of doing so, -see [the rustc-dev-guide working group documentation](https://forge.rust-lang.org/wg-rustc-dev-guide/index.html#where-to-contribute-rustc-dev-guide-changes). +see [the rustc-dev-guide working group documentation]. ## Issue triage @@ -458,6 +457,7 @@ Please see . [regression-]: https://github.com/rust-lang/rust/labels?q=regression [relnotes]: https://github.com/rust-lang/rust/labels/relnotes [S-tracking-]: https://github.com/rust-lang/rust/labels?q=s-tracking +[the rustc-dev-guide working group documentation]: https://forge.rust-lang.org/wg-rustc-dev-guide/index.html#where-to-contribute-rustc-dev-guide-changes ### Rfcbot labels @@ -505,3 +505,4 @@ This section has moved to the ["About this guide"] chapter. [RFC 1574]: https://github.com/rust-lang/rfcs/blob/master/text/1574-more-api-documentation-conventions.md#appendix-a-full-conventions-text [rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/ [rdgrepo]: https://github.com/rust-lang/rustc-dev-guide +[create an issue]: https://github.com/rust-lang/rust/issues/new/choose -- cgit 1.4.1-3-g733a5 From 951733c1b99286fe417f0fbea8cb20c1a97f8b13 Mon Sep 17 00:00:00 2001 From: Ada Alakbarova <58857108+ada4a@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:10:50 +0200 Subject: Update link to `resolve_regions_and_report_errors` Moved into `ObligationCtxt` in https://github.com/rust-lang/rust/commit/a19adefa0e5aca0aabca2430530577ee140e4efa --- src/doc/rustc-dev-guide/src/type-inference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/type-inference.md b/src/doc/rustc-dev-guide/src/type-inference.md index 2243205f129..4c51eed4e8e 100644 --- a/src/doc/rustc-dev-guide/src/type-inference.md +++ b/src/doc/rustc-dev-guide/src/type-inference.md @@ -242,7 +242,7 @@ as the NLL solver must not only know *what* regions outlive each other, but also *where*. Finally, the NLL solver invokes [`take_region_var_origins`], providing all region variables to the solver. -[`resolve_regions_and_report_errors`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html#method.resolve_regions_and_report_errors +[`resolve_regions_and_report_errors`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/struct.ObligationCtxt.html#method.resolve_regions_and_report_errors [`lexical_region_resolve`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/lexical_region_resolve/index.html [`take_and_reset_region_constraints`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html#method.take_and_reset_region_constraints [`take_region_var_origins`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html#method.take_region_var_origins -- cgit 1.4.1-3-g733a5 From 6907e64ffb80b82e519b6bab9da7c1b7941700dd Mon Sep 17 00:00:00 2001 From: Ada Alakbarova <58857108+ada4a@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:35:10 +0200 Subject: Update renamed `take_region_var_origins` This was first renamed to `get_region_var_origins` in https://github.com/rust-lang/rust/pull/109753, and then to `get_region_var_infos` in https://github.com/rust-lang/rust/commit/b0fc1d47d5dcffb5d516059d4a5af3b6843132d5 --- src/doc/rustc-dev-guide/src/type-inference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/type-inference.md b/src/doc/rustc-dev-guide/src/type-inference.md index 4c51eed4e8e..24982a209fd 100644 --- a/src/doc/rustc-dev-guide/src/type-inference.md +++ b/src/doc/rustc-dev-guide/src/type-inference.md @@ -239,13 +239,13 @@ differently. It uses canonical queries for trait solving which use [`take_and_reset_region_constraints`] at the end. This extracts all of the outlives constraints added during the canonical query. This is required as the NLL solver must not only know *what* regions outlive each other, -but also *where*. Finally, the NLL solver invokes [`take_region_var_origins`], +but also *where*. Finally, the NLL solver invokes [`get_region_var_infos`], providing all region variables to the solver. [`resolve_regions_and_report_errors`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/struct.ObligationCtxt.html#method.resolve_regions_and_report_errors [`lexical_region_resolve`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/lexical_region_resolve/index.html [`take_and_reset_region_constraints`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html#method.take_and_reset_region_constraints -[`take_region_var_origins`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html#method.take_region_var_origins +[`get_region_var_infos`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html#method.get_region_var_infos ## Lexical region resolution -- cgit 1.4.1-3-g733a5 From 095fa86a3ba30f4198c88ef300354391d3ab97e1 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 18 Aug 2025 16:42:21 -0400 Subject: compiler: Add Windows resources to rustc-main and rustc_driver Adds Windows resources with the rust version information to rustc-main.exe and rustc_driver.dll Sets the product description to "Rust Compiler" or "Rust Compiler (channel)" for non-stable channels --- Cargo.lock | 9 ++ compiler/rustc/Cargo.toml | 5 + compiler/rustc/build.rs | 16 +++- compiler/rustc_codegen_ssa/Cargo.toml | 2 +- compiler/rustc_driver/Cargo.toml | 5 + compiler/rustc_driver/build.rs | 21 +++++ compiler/rustc_llvm/Cargo.toml | 2 +- compiler/rustc_windows_rc/Cargo.toml | 11 +++ compiler/rustc_windows_rc/rustc.rc.in | 40 ++++++++ compiler/rustc_windows_rc/src/lib.rs | 158 ++++++++++++++++++++++++++++++++ src/bootstrap/src/core/builder/tests.rs | 10 +- 11 files changed, 271 insertions(+), 8 deletions(-) create mode 100644 compiler/rustc_driver/build.rs create mode 100644 compiler/rustc_windows_rc/Cargo.toml create mode 100644 compiler/rustc_windows_rc/rustc.rc.in create mode 100644 compiler/rustc_windows_rc/src/lib.rs (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index 8b9c243879c..03bda287c49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3248,6 +3248,7 @@ dependencies = [ "rustc_driver_impl", "rustc_public", "rustc_public_bridge", + "rustc_windows_rc", "tikv-jemalloc-sys", ] @@ -3623,6 +3624,7 @@ name = "rustc_driver" version = "0.0.0" dependencies = [ "rustc_driver_impl", + "rustc_windows_rc", ] [[package]] @@ -4718,6 +4720,13 @@ dependencies = [ "semver", ] +[[package]] +name = "rustc_windows_rc" +version = "0.0.0" +dependencies = [ + "cc", +] + [[package]] name = "rustdoc" version = "0.0.0" diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index 3ca75235446..e3214d1ab9c 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -33,3 +33,8 @@ llvm = ['rustc_driver_impl/llvm'] max_level_info = ['rustc_driver_impl/max_level_info'] rustc_randomized_layouts = ['rustc_driver_impl/rustc_randomized_layouts'] # tidy-alphabetical-end + +[build-dependencies] +# tidy-alphabetical-start +rustc_windows_rc = { path = "../rustc_windows_rc" } +# tidy-alphabetical-end diff --git a/compiler/rustc/build.rs b/compiler/rustc/build.rs index 8b7d28d2b8a..9b5def53e3c 100644 --- a/compiler/rustc/build.rs +++ b/compiler/rustc/build.rs @@ -1,4 +1,6 @@ -use std::env; +use std::{env, path}; + +use rustc_windows_rc::{VersionInfoFileType, compile_windows_resource_file}; fn main() { let target_os = env::var("CARGO_CFG_TARGET_OS"); @@ -13,6 +15,18 @@ fn main() { // Add a manifest file to rustc.exe. fn set_windows_exe_options() { + set_windows_resource(); + set_windows_manifest(); +} + +fn set_windows_resource() { + let stem = path::PathBuf::from("rustc_main_resource"); + let file_description = "rustc"; + let res_file = compile_windows_resource_file(&stem, file_description, VersionInfoFileType::App); + println!("cargo:rustc-link-arg={}", res_file.display()); +} + +fn set_windows_manifest() { static WINDOWS_MANIFEST_FILE: &str = "Windows Manifest.xml"; let mut manifest = env::current_dir().unwrap(); diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 57e1fee2c0a..afcfe82d68d 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -9,7 +9,7 @@ ar_archive_writer = "0.4.2" bitflags.workspace = true bstr = "1.11.3" # `cc` updates often break things, so we pin it here. Cargo enforces "max 1 semver-compat version -# per crate", so if you change this, you need to also change it in `rustc_llvm`. +# per crate", so if you change this, you need to also change it in `rustc_llvm` and `rustc_windows_rc`. cc = "=1.2.16" itertools.workspace = true pathdiff = "0.2.0" diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml index e3ee8351295..51909719827 100644 --- a/compiler/rustc_driver/Cargo.toml +++ b/compiler/rustc_driver/Cargo.toml @@ -10,3 +10,8 @@ crate-type = ["dylib"] # tidy-alphabetical-start rustc_driver_impl = { path = "../rustc_driver_impl" } # tidy-alphabetical-end + +[build-dependencies] +# tidy-alphabetical-start +rustc_windows_rc = { path = "../rustc_windows_rc" } +# tidy-alphabetical-end diff --git a/compiler/rustc_driver/build.rs b/compiler/rustc_driver/build.rs new file mode 100644 index 00000000000..ba44fe7a86e --- /dev/null +++ b/compiler/rustc_driver/build.rs @@ -0,0 +1,21 @@ +use std::{env, path}; + +use rustc_windows_rc::{VersionInfoFileType, compile_windows_resource_file}; + +fn main() { + let target_os = env::var("CARGO_CFG_TARGET_OS"); + let target_env = env::var("CARGO_CFG_TARGET_ENV"); + if Ok("windows") == target_os.as_deref() && Ok("msvc") == target_env.as_deref() { + set_windows_dll_options(); + } else { + // Avoid rerunning the build script every time. + println!("cargo:rerun-if-changed=build.rs"); + } +} + +fn set_windows_dll_options() { + let stem = path::PathBuf::from("rustc_driver_resource"); + let file_description = "rustc_driver"; + let res_file = compile_windows_resource_file(&stem, file_description, VersionInfoFileType::Dll); + println!("cargo:rustc-link-arg={}", res_file.display()); +} diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index e74de453be2..6321104ee3e 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -11,7 +11,7 @@ libc.workspace = true [build-dependencies] # tidy-alphabetical-start # `cc` updates often break things, so we pin it here. Cargo enforces "max 1 semver-compat version -# per crate", so if you change this, you need to also change it in `rustc_codegen_ssa`. +# per crate", so if you change this, you need to also change it in `rustc_codegen_ssa` and `rustc_windows_rc`. cc = "=1.2.16" # tidy-alphabetical-end diff --git a/compiler/rustc_windows_rc/Cargo.toml b/compiler/rustc_windows_rc/Cargo.toml new file mode 100644 index 00000000000..080acd35c38 --- /dev/null +++ b/compiler/rustc_windows_rc/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "rustc_windows_rc" +version = "0.0.0" +edition = "2024" + +[dependencies] +#tidy-alphabetical-start +# `cc` updates often break things, so we pin it here. Cargo enforces "max 1 semver-compat version +# per crate", so if you change this, you need to also change it in `rustc_llvm` and `rustc_codegen_ssa`. +cc = "=1.2.16" +#tidy-alphabetical-end diff --git a/compiler/rustc_windows_rc/rustc.rc.in b/compiler/rustc_windows_rc/rustc.rc.in new file mode 100644 index 00000000000..10a00b9bd4e --- /dev/null +++ b/compiler/rustc_windows_rc/rustc.rc.in @@ -0,0 +1,40 @@ +// A template for the rustc_driver and rustc Windows resource files. +// This file is processed by the build script to produce rustc.rc and rustc_driver.rc +// with the appropriate version information filled in. + +// All the strings are in UTF-8 +#pragma code_page(65001) + +#define RUSTC_FILEDESCRIPTION_STR "@RUSTC_FILEDESCRIPTION_STR@" +#define RUSTC_FILETYPE @RUSTC_FILETYPE@ +#define RUSTC_FILEVERSION_QUAD @RUSTC_FILEVERSION_QUAD@ +#define RUSTC_FILEVERSION_STR "@RUSTC_FILEVERSION_STR@" + +#define RUSTC_PRODUCTNAME_STR "@RUSTC_PRODUCTNAME_STR@" +#define RUSTC_PRODUCTVERSION_QUAD @RUSTC_PRODUCTVERSION_QUAD@ +#define RUSTC_PRODUCTVERSION_STR "@RUSTC_PRODUCTVERSION_STR@" + + +1 VERSIONINFO +FILEVERSION RUSTC_FILEVERSION_QUAD +PRODUCTVERSION RUSTC_PRODUCTVERSION_QUAD +FILEOS 0x00040004 +FILETYPE RUSTC_FILETYPE +FILESUBTYPE 0 +FILEFLAGSMASK 0x3f +FILEFLAGS 0x0 +{ + BLOCK "StringFileInfo" + { + BLOCK "000004b0" + { + VALUE "FileDescription", RUSTC_FILEDESCRIPTION_STR + VALUE "FileVersion", RUSTC_FILEVERSION_STR + VALUE "ProductVersion", RUSTC_PRODUCTVERSION_STR + VALUE "ProductName", RUSTC_PRODUCTNAME_STR + } + } + BLOCK "VarFileInfo" { + VALUE "Translation", 0x0, 0x04b0 + } +} diff --git a/compiler/rustc_windows_rc/src/lib.rs b/compiler/rustc_windows_rc/src/lib.rs new file mode 100644 index 00000000000..caa5e5ef276 --- /dev/null +++ b/compiler/rustc_windows_rc/src/lib.rs @@ -0,0 +1,158 @@ +//! A build script dependency to create a Windows resource file for the compiler +//! +//! Uses values from the `CFG_VERSION` and `CFG_RELEASE` environment variables +//! to set the product and file version information in the Windows resource file. +use std::{env, ffi, fs, path, process}; + +use cc::windows_registry; + +/// The template for the Windows resource file. +const RESOURCE_TEMPLATE: &str = include_str!("../rustc.rc.in"); + +/// A subset of the possible values for the `FILETYPE` field in a Windows resource file +/// +/// See the `dwFileType` member of [VS_FIXEDFILEINFO](https://learn.microsoft.com/en-us/windows/win32/api/verrsrc/ns-verrsrc-vs_fixedfileinfo#members) +#[derive(Debug, Clone, Copy)] +#[repr(u32)] +pub enum VersionInfoFileType { + /// `VFT_APP` - The file is an application. + App = 0x00000001, + /// `VFT_DLL` - The file is a dynamic link library. + Dll = 0x00000002, +} + +/// Create and compile a Windows resource file with the product and file version information for the rust compiler. +/// +/// Returns the path to the compiled resource file +/// +/// Does not emit any cargo directives, the caller is responsible for that. +pub fn compile_windows_resource_file( + file_stem: &path::Path, + file_description: &str, + filetype: VersionInfoFileType, +) -> path::PathBuf { + let mut resources_dir = path::PathBuf::from(env::var_os("OUT_DIR").unwrap()); + resources_dir.push("resources"); + fs::create_dir_all(&resources_dir).unwrap(); + + let resource_compiler = + find_resource_compiler(&env::var("CARGO_CFG_TARGET_ARCH").unwrap()).expect("found rc.exe"); + + let rc_path = resources_dir.join(file_stem.with_extension("rc")); + + write_resource_script_file(&rc_path, file_description, filetype); + + let res_path = resources_dir.join(file_stem.with_extension("res")); + + let status = process::Command::new(resource_compiler) + .arg("/fo") + .arg(&res_path) + .arg(&rc_path) + .status() + .expect("can execute resource compiler"); + assert!(status.success(), "rc.exe failed with status {}", status); + assert!( + res_path.try_exists().unwrap_or(false), + "resource file {} was not created", + res_path.display() + ); + res_path +} + +/// Writes a Windows resource script file for the rust compiler with the product and file version information +/// into `rc_path` +fn write_resource_script_file( + rc_path: &path::Path, + file_description: &str, + filetype: VersionInfoFileType, +) { + let mut resource_script = RESOURCE_TEMPLATE.to_string(); + + // Set the string product and file version to the same thing as `rustc --version` + let descriptive_version = env::var("CFG_VERSION").unwrap_or("unknown".to_string()); + + // Set the product name to "Rust Compiler" or "Rust Compiler (nightly)" etc + let product_name = product_name(env::var("CFG_RELEASE_CHANNEL").unwrap()); + + // For the numeric version we need `major,minor,patch,build`. + // Extract them from `CFG_RELEASE` which is "major.minor.patch" and a "-dev", "-nightly" or similar suffix + let cfg_release = env::var("CFG_RELEASE").unwrap(); + // remove the suffix, if present and parse into [`ResourceVersion`] + let version = parse_version(cfg_release.split("-").next().unwrap_or("0.0.0")) + .expect("valid CFG_RELEASE version"); + + resource_script = resource_script + .replace("@RUSTC_FILEDESCRIPTION_STR@", file_description) + .replace("@RUSTC_FILETYPE@", &format!("{}", filetype as u32)) + .replace("@RUSTC_FILEVERSION_QUAD@", &version.to_quad_string()) + .replace("@RUSTC_FILEVERSION_STR@", &descriptive_version) + .replace("@RUSTC_PRODUCTNAME_STR@", &product_name) + .replace("@RUSTC_PRODUCTVERSION_QUAD@", &version.to_quad_string()) + .replace("@RUSTC_PRODUCTVERSION_STR@", &descriptive_version); + + fs::write(&rc_path, resource_script) + .unwrap_or_else(|_| panic!("failed to write resource file {}", rc_path.display())); +} + +fn product_name(channel: String) -> String { + format!( + "Rust Compiler{}", + if channel == "stable" { "".to_string() } else { format!(" ({})", channel) } + ) +} + +/// Windows resources store versions as four 16-bit integers. +struct ResourceVersion { + major: u16, + minor: u16, + patch: u16, + build: u16, +} + +impl ResourceVersion { + /// Format the version as a comma-separated string of four integers + /// as expected by Windows resource scripts for the `FILEVERSION` and `PRODUCTVERSION` fields. + fn to_quad_string(&self) -> String { + format!("{},{},{},{}", self.major, self.minor, self.patch, self.build) + } +} + +/// Parse a string in the format "major.minor.patch" into a [`ResourceVersion`]. +/// The build is set to 0. +/// Returns `None` if the version string is not in the expected format. +fn parse_version(version: &str) -> Option { + let mut parts = version.split('.'); + let major = parts.next()?.parse::().ok()?; + let minor = parts.next()?.parse::().ok()?; + let patch = parts.next()?.parse::().ok()?; + if parts.next().is_some() { + None + } else { + Some(ResourceVersion { major, minor, patch, build: 0 }) + } +} + +/// Find the Windows SDK resource compiler `rc.exe` for the given architecture or target triple. +/// Returns `None` if the tool could not be found. +fn find_resource_compiler(arch_or_target: &str) -> Option { + find_windows_sdk_tool(arch_or_target, "rc.exe") +} + +/// Find a Windows SDK tool for the given architecture or target triple. +/// Returns `None` if the tool could not be found. +fn find_windows_sdk_tool(arch_or_target: &str, tool_name: &str) -> Option { + // windows_registry::find_tool can only find MSVC tools, not Windows SDK tools, but + // cc does include the Windows SDK tools in the PATH environment of MSVC tools. + + let msvc_linker = windows_registry::find_tool(arch_or_target, "link.exe")?; + let path = &msvc_linker.env().iter().find(|(k, _)| k == "PATH")?.1; + find_tool_in_path(tool_name, path) +} + +/// Find a tool in the directories in a given PATH-like string. +fn find_tool_in_path>(tool_name: &str, path: P) -> Option { + env::split_paths(path.as_ref()).find_map(|p| { + let tool_path = p.join(tool_name); + if tool_path.try_exists().unwrap_or(false) { Some(tool_path) } else { None } + }) +} diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index b079117c5a7..9d6382cb4e3 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1777,7 +1777,7 @@ mod snapshot { insta::assert_snapshot!( ctx.config("check") .path("compiler") - .render_steps(), @"[check] rustc 0 -> rustc 1 (74 crates)"); + .render_steps(), @"[check] rustc 0 -> rustc 1 (75 crates)"); } #[test] @@ -1803,7 +1803,7 @@ mod snapshot { ctx.config("check") .path("compiler") .stage(1) - .render_steps(), @"[check] rustc 0 -> rustc 1 (74 crates)"); + .render_steps(), @"[check] rustc 0 -> rustc 1 (75 crates)"); } #[test] @@ -1817,7 +1817,7 @@ mod snapshot { [build] llvm [build] rustc 0 -> rustc 1 [build] rustc 1 -> std 1 - [check] rustc 1 -> rustc 2 (74 crates) + [check] rustc 1 -> rustc 2 (75 crates) "); } @@ -1833,7 +1833,7 @@ mod snapshot { [build] rustc 0 -> rustc 1 [build] rustc 1 -> std 1 [check] rustc 1 -> std 1 - [check] rustc 1 -> rustc 2 (74 crates) + [check] rustc 1 -> rustc 2 (75 crates) [check] rustc 1 -> rustc 2 [check] rustc 1 -> Rustdoc 2 [check] rustc 1 -> rustc_codegen_cranelift 2 @@ -1929,7 +1929,7 @@ mod snapshot { ctx.config("check") .paths(&["library", "compiler"]) .args(&args) - .render_steps(), @"[check] rustc 0 -> rustc 1 (74 crates)"); + .render_steps(), @"[check] rustc 0 -> rustc 1 (75 crates)"); } #[test] -- cgit 1.4.1-3-g733a5 From cd9917208fc29c4e3f7f174c32443f1875a0173d Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Fri, 5 Sep 2025 20:35:51 +0100 Subject: Make footnote render correctly in github --- .../rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md index efc576cc900..2d48878b05a 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md @@ -63,13 +63,13 @@ Arguments to directives are split using the [shlex] crate, which implements POSI This is because both `` and `` arguments to [directives](#directives) frequently have both whitespace and quote marks. -To use the `@ is` with a `` of `$.index[?(@.docs == "foo")].some.field` and a value of `"bar"` [^why quote], you'd write: +To use the `@ is` with a `` of `$.index[?(@.docs == "foo")].some.field` and a value of `"bar"` [^why_quote], you'd write: ```rust //@ is '$.is[?(@.docs == "foo")].some.field' '"bar"' ``` -[^why quote]: The value needs to be `"bar"` *after* shlex splitting, because we +[^why_quote]: The value needs to be `"bar"` *after* shlex splitting, because we it needs to be a JSON string value. [json output]: https://doc.rust-lang.org/nightly/rustdoc/unstable-features.html#json-output -- cgit 1.4.1-3-g733a5 From 1d2457b04898edb898850e87f4fe57e5598dbdf6 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Fri, 5 Sep 2025 20:39:14 +0100 Subject: Consistent punctuation --- .../src/rustdoc-internals/rustdoc-json-test-suite.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md index 2d48878b05a..3044136c146 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md @@ -30,16 +30,16 @@ It uses [JSONPath] as a query language, which takes a path, and returns a *list* ### Directives -- `//@ has `:: Checks `` exists, i.e. matches at least 1 value. -- `//@ !has `:: Checks `` doesn't exist, i.e. matches 0 values. +- `//@ has `: Checks `` exists, i.e. matches at least 1 value. +- `//@ !has `: Checks `` doesn't exist, i.e. matches 0 values. - `//@ has `: Check `` exists, and at least 1 of the matches is equal to the given `` - `//@ !has `: Checks `` exists, but none of the matches equal the given ``. - `//@ is `: Check `` matches exactly one value, and it's equal to the given ``. - `//@ is ...`: Check that `` matches to exactly every given ``. Ordering doesn't matter here. - `//@ !is `: Check `` matches exactly one value, and that value is not equal to the given ``. -- `//@ count ` Check that `` matches to `` of values. -- `//@ set = `, Check that `` matches exactly one value, and store that value to the variable called `` +- `//@ count `: Check that `` matches to `` of values. +- `//@ set = `: Check that `` matches exactly one value, and store that value to the variable called ``. These are defined in [`directive.rs`]. -- cgit 1.4.1-3-g733a5 From d7f27bf9e03c8fbeb37104be2d99ba5b2397e51e Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Fri, 5 Sep 2025 20:41:43 +0100 Subject: Better link --- .../rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md index 3044136c146..10e9452eda3 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md +++ b/src/doc/rustc-dev-guide/src/rustdoc-internals/rustdoc-json-test-suite.md @@ -1,7 +1,7 @@ # The `rustdoc-json` test suite This page is specifically about the test suite named `rustdoc-json`, which tests rustdoc's [json output]. -For other test suites used for testing rustdoc, see [Rustdoc tests](../rustdoc.md#tests). +For other test suites used for testing rustdoc, see [§Rustdoc test suites](../tests/compiletest.md#rustdoc-test-suites). Tests are run with compiletest, and have access to the usual set of [directives](../tests/directives.md). Frequenly used directives here are: -- cgit 1.4.1-3-g733a5 From 4e18796882880e9465d43f29c697aef311c6bb36 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 6 Sep 2025 05:11:47 +0200 Subject: Zulip streams have been renamed to channels https://blog.zulip.com/2024/07/25/zulip-9-0-released --- src/doc/rustc-dev-guide/src/backend/debugging.md | 2 +- src/doc/rustc-dev-guide/src/compiler-team.md | 2 +- src/doc/rustc-dev-guide/src/notification-groups/arm.md | 2 +- src/doc/rustc-dev-guide/src/notification-groups/emscripten.md | 2 +- src/doc/rustc-dev-guide/src/notification-groups/risc-v.md | 2 +- src/doc/rustc-dev-guide/src/notification-groups/rust-for-linux.md | 2 +- src/doc/rustc-dev-guide/src/notification-groups/wasi.md | 2 +- src/doc/rustc-dev-guide/src/notification-groups/wasm.md | 2 +- src/doc/rustc-dev-guide/src/notification-groups/windows.md | 2 +- src/doc/rustc-dev-guide/src/traits/chalk.md | 2 +- src/doc/rustc-dev-guide/src/typing_parameter_envs.md | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/backend/debugging.md b/src/doc/rustc-dev-guide/src/backend/debugging.md index 4f8712dfaf3..3dc95f25d4a 100644 --- a/src/doc/rustc-dev-guide/src/backend/debugging.md +++ b/src/doc/rustc-dev-guide/src/backend/debugging.md @@ -183,7 +183,7 @@ The quick summary is: ### Getting help and asking questions If you have some questions, head over to the [rust-lang Zulip] and -specifically the `#t-compiler/wg-llvm` stream. +specifically the `#t-compiler/wg-llvm` channel. [rust-lang Zulip]: https://rust-lang.zulipchat.com/ diff --git a/src/doc/rustc-dev-guide/src/compiler-team.md b/src/doc/rustc-dev-guide/src/compiler-team.md index 9922ee7ddf2..6be52833f39 100644 --- a/src/doc/rustc-dev-guide/src/compiler-team.md +++ b/src/doc/rustc-dev-guide/src/compiler-team.md @@ -12,7 +12,7 @@ contributions to rustc and its design. Currently the compiler team chats in Zulip: - Team chat occurs in the [`t-compiler`][zulip-t-compiler] stream on the Zulip instance -- There are also a number of other associated Zulip streams, +- There are also a number of other associated Zulip channels, such as [`t-compiler/help`][zulip-help], where people can ask for help with rustc development, or [`t-compiler/meetings`][zulip-meetings], where the team holds their weekly triage and steering meetings. diff --git a/src/doc/rustc-dev-guide/src/notification-groups/arm.md b/src/doc/rustc-dev-guide/src/notification-groups/arm.md index 3abc32c6888..5b79030d20d 100644 --- a/src/doc/rustc-dev-guide/src/notification-groups/arm.md +++ b/src/doc/rustc-dev-guide/src/notification-groups/arm.md @@ -9,7 +9,7 @@ This list will be used to ask for help both in diagnosing and testing ARM-related issues as well as suggestions on how to resolve interesting questions regarding our ARM support. -The group also has an associated Zulip stream ([`#t-compiler/arm`]) +The group also has an associated Zulip channel ([`#t-compiler/arm`]) where people can go to pose questions and discuss ARM-specific topics. diff --git a/src/doc/rustc-dev-guide/src/notification-groups/emscripten.md b/src/doc/rustc-dev-guide/src/notification-groups/emscripten.md index 100dbdf9f2b..9e4086c884e 100644 --- a/src/doc/rustc-dev-guide/src/notification-groups/emscripten.md +++ b/src/doc/rustc-dev-guide/src/notification-groups/emscripten.md @@ -9,7 +9,7 @@ This list will be used to ask for help both in diagnosing and testing Emscripten-related issues as well as suggestions on how to resolve interesting questions regarding our Emscripten support. -The group also has an associated Zulip stream ([`#t-compiler/wasm`]) +The group also has an associated Zulip channel ([`#t-compiler/wasm`]) where people can go to pose questions and discuss Emscripten-specific topics. diff --git a/src/doc/rustc-dev-guide/src/notification-groups/risc-v.md b/src/doc/rustc-dev-guide/src/notification-groups/risc-v.md index 1b31297b600..7c8a3cdf8a6 100644 --- a/src/doc/rustc-dev-guide/src/notification-groups/risc-v.md +++ b/src/doc/rustc-dev-guide/src/notification-groups/risc-v.md @@ -9,7 +9,7 @@ This list will be used to ask for help both in diagnosing and testing RISC-V-related issues as well as suggestions on how to resolve interesting questions regarding our RISC-V support. -The group also has an associated Zulip stream ([`#t-compiler/risc-v`]) +The group also has an associated Zulip channel ([`#t-compiler/risc-v`]) where people can go to pose questions and discuss RISC-V-specific topics. diff --git a/src/doc/rustc-dev-guide/src/notification-groups/rust-for-linux.md b/src/doc/rustc-dev-guide/src/notification-groups/rust-for-linux.md index 696f2038e1a..ed1de9196de 100644 --- a/src/doc/rustc-dev-guide/src/notification-groups/rust-for-linux.md +++ b/src/doc/rustc-dev-guide/src/notification-groups/rust-for-linux.md @@ -12,7 +12,7 @@ and features. The RfL maintainers should then ideally provide support for resolving the breakage or decide to temporarily accept the breakage and unblock CI by temporarily removing the RfL CI jobs. -The group also has an associated Zulip stream ([`#rust-for-linux`]) +The group also has an associated Zulip channel ([`#rust-for-linux`]) where people can go to ask questions and discuss topics related to Rust for Linux. diff --git a/src/doc/rustc-dev-guide/src/notification-groups/wasi.md b/src/doc/rustc-dev-guide/src/notification-groups/wasi.md index e438ee4bd09..88b9465be01 100644 --- a/src/doc/rustc-dev-guide/src/notification-groups/wasi.md +++ b/src/doc/rustc-dev-guide/src/notification-groups/wasi.md @@ -9,7 +9,7 @@ This list will be used to ask for help both in diagnosing and testing WASI-related issues as well as suggestions on how to resolve interesting questions regarding our WASI support. -The group also has an associated Zulip stream ([`#t-compiler/wasm`]) +The group also has an associated Zulip channel ([`#t-compiler/wasm`]) where people can go to pose questions and discuss WASI-specific topics. diff --git a/src/doc/rustc-dev-guide/src/notification-groups/wasm.md b/src/doc/rustc-dev-guide/src/notification-groups/wasm.md index c8b674cb93f..6f52b04251f 100644 --- a/src/doc/rustc-dev-guide/src/notification-groups/wasm.md +++ b/src/doc/rustc-dev-guide/src/notification-groups/wasm.md @@ -9,7 +9,7 @@ This list will be used to ask for help both in diagnosing and testing WebAssembly-related issues as well as suggestions on how to resolve interesting questions regarding our WASM support. -The group also has an associated Zulip stream ([`#t-compiler/wasm`]) +The group also has an associated Zulip channel ([`#t-compiler/wasm`]) where people can go to pose questions and discuss WASM-specific topics. diff --git a/src/doc/rustc-dev-guide/src/notification-groups/windows.md b/src/doc/rustc-dev-guide/src/notification-groups/windows.md index e615a2cbd8d..d245208e2ab 100644 --- a/src/doc/rustc-dev-guide/src/notification-groups/windows.md +++ b/src/doc/rustc-dev-guide/src/notification-groups/windows.md @@ -9,7 +9,7 @@ This list will be used to ask for help both in diagnosing and testing Windows-related issues as well as suggestions on how to resolve interesting questions regarding our Windows support. -The group also has an associated Zulip stream ([`#t-compiler/windows`]) +The group also has an associated Zulip channel ([`#t-compiler/windows`]) where people can go to pose questions and discuss Windows-specific topics. diff --git a/src/doc/rustc-dev-guide/src/traits/chalk.md b/src/doc/rustc-dev-guide/src/traits/chalk.md index 844f42b9879..ca5ed525917 100644 --- a/src/doc/rustc-dev-guide/src/traits/chalk.md +++ b/src/doc/rustc-dev-guide/src/traits/chalk.md @@ -5,7 +5,7 @@ Its goal is to enable a lot of trait system features and bug fixes that are hard to implement (e.g. GATs or specialization). If you would like to help in hacking on the new solver, drop by on the rust-lang Zulip in the [`#t-types`] -stream and say hello! +channel and say hello! [Types team]: https://github.com/rust-lang/types-team [`#t-types`]: https://rust-lang.zulipchat.com/#narrow/stream/144729-t-types diff --git a/src/doc/rustc-dev-guide/src/typing_parameter_envs.md b/src/doc/rustc-dev-guide/src/typing_parameter_envs.md index db15467a47a..fd77f42ba7e 100644 --- a/src/doc/rustc-dev-guide/src/typing_parameter_envs.md +++ b/src/doc/rustc-dev-guide/src/typing_parameter_envs.md @@ -82,7 +82,7 @@ In the large majority of cases, when a `ParamEnv` is required it either already - In the next-gen trait solver all `Goal`s have a [`param_env` field][goal_param_env] specifying what environment to prove the goal in - When editing an existing [`TypeRelation`][typerelation] if it implements [`PredicateEmittingRelation`][predicate_emitting_relation] then a [`param_env` method][typerelation_param_env] will be available. -If you aren't sure if there's a `ParamEnv` in scope somewhere that can be used it can be worth opening a thread in the [`#t-compiler/help`][compiler_help] zulip stream where someone may be able to point out where a `ParamEnv` can be acquired from. +If you aren't sure if there's a `ParamEnv` in scope somewhere that can be used it can be worth opening a thread in the [`#t-compiler/help`][compiler_help] zulip channel where someone may be able to point out where a `ParamEnv` can be acquired from. Manually constructing a `ParamEnv` is typically only needed at the start of some kind of top level analysis (e.g. hir typeck or borrow checking). In such cases there are three ways it can be done: - Calling the [`tcx.param_env(def_id)` query][param_env_query] which returns the environment associated with a given definition. -- cgit 1.4.1-3-g733a5 From 55f913cf1b4eb55ab2252421a28100288b8feec8 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 6 Sep 2025 05:25:38 +0200 Subject: capitalize "zulip" --- src/doc/rustc-dev-guide/src/about-this-guide.md | 2 +- src/doc/rustc-dev-guide/src/contributing.md | 4 ++-- src/doc/rustc-dev-guide/src/rustdoc.md | 2 +- src/doc/rustc-dev-guide/src/solve/caching.md | 2 +- src/doc/rustc-dev-guide/src/solve/the-solver.md | 2 +- src/doc/rustc-dev-guide/src/typing_parameter_envs.md | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/about-this-guide.md b/src/doc/rustc-dev-guide/src/about-this-guide.md index f3957724967..f1a406a1c29 100644 --- a/src/doc/rustc-dev-guide/src/about-this-guide.md +++ b/src/doc/rustc-dev-guide/src/about-this-guide.md @@ -73,7 +73,7 @@ You might also find the following sites useful: - [compiler-team] -- the home-base for the Rust compiler team, with description of the team procedures, active working groups, and the team calendar. - [std-dev-guide] -- a similar guide for developing the standard library. -- [The t-compiler zulip][z] +- [The t-compiler Zulip][z] - The [Rust Internals forum][rif], a place to ask questions and discuss Rust's internals - The [Rust reference][rr], even though it doesn't specifically talk about diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 18f2dcb21ba..347608d305a 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -74,7 +74,7 @@ Example of things that might require MCPs include major refactorings, changes to important types, or important changes to how the compiler does something, or smaller user-facing changes. -**When in doubt, ask on [zulip]. It would be a shame to put a lot of work +**When in doubt, ask on [Zulip]. It would be a shame to put a lot of work into a PR that ends up not getting merged!** [See this document][mcpinfo] for more info on MCPs. @@ -126,7 +126,7 @@ when contributing to Rust under [the git section](./git.md). > from), and work with the compiler team to see if we can help you **break down a large potentially > unreviewable PR into a series of smaller more individually reviewable PRs**. > -> You can communicate with the compiler team by creating a [#t-compiler thread on zulip][t-compiler] +> You can communicate with the compiler team by creating a [#t-compiler thread on Zulip][t-compiler] > to discuss your proposed changes. > > Communicating with the compiler team beforehand helps in several ways: diff --git a/src/doc/rustc-dev-guide/src/rustdoc.md b/src/doc/rustc-dev-guide/src/rustdoc.md index 9290fcd3b41..6127a894a0f 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc.md +++ b/src/doc/rustc-dev-guide/src/rustdoc.md @@ -107,7 +107,7 @@ This comes with several caveats: in particular, rustdoc *cannot* run any parts o require type-checking bodies; for example it cannot generate `.rlib` files or run most lints. We want to move away from this model eventually, but we need some alternative for [the people using it][async-std]; see [various][zulip stop accepting broken code] -[previous][rustdoc meeting 2024-07-08] [zulip][compiler meeting 2023-01-26] [discussion][notriddle rfc]. +[previous][rustdoc meeting 2024-07-08] [Zulip][compiler meeting 2023-01-26] [discussion][notriddle rfc]. For examples of code that breaks if this hack is removed, see [`tests/rustdoc-ui/error-in-impl-trait`]. diff --git a/src/doc/rustc-dev-guide/src/solve/caching.md b/src/doc/rustc-dev-guide/src/solve/caching.md index e568d47ca25..cb7403de4e0 100644 --- a/src/doc/rustc-dev-guide/src/solve/caching.md +++ b/src/doc/rustc-dev-guide/src/solve/caching.md @@ -106,7 +106,7 @@ We can implement this optimization in the future. [`provisional_result`]: https://github.com/rust-lang/rust/blob/7606c13961ddc1174b70638e934df0439b7dc515/compiler/rustc_trait_selection/src/solve/search_graph.rs#L57 [initial-prov-result]: https://github.com/rust-lang/rust/blob/7606c13961ddc1174b70638e934df0439b7dc515/compiler/rustc_trait_selection/src/solve/search_graph.rs#L366-L370 [fixpoint]: https://github.com/rust-lang/rust/blob/7606c13961ddc1174b70638e934df0439b7dc515/compiler/rustc_trait_selection/src/solve/search_graph.rs#L425-L446 -[^2]: summarizing the relevant [zulip thread] +[^2]: summarizing the relevant [Zulip thread] [zulip thread]: https://rust-lang.zulipchat.com/#narrow/stream/364551-t-types.2Ftrait-system-refactor/topic/global.20cache [unstable-result-ex]: https://github.com/rust-lang/rust/blob/7606c13961ddc1174b70638e934df0439b7dc515/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs#L4-L16 diff --git a/src/doc/rustc-dev-guide/src/solve/the-solver.md b/src/doc/rustc-dev-guide/src/solve/the-solver.md index 006fb649d22..0e095b55437 100644 --- a/src/doc/rustc-dev-guide/src/solve/the-solver.md +++ b/src/doc/rustc-dev-guide/src/solve/the-solver.md @@ -71,6 +71,6 @@ fails. ## Learning more The solver should be fairly self-contained. I hope that the above information provides a -good foundation when looking at the code itself. Please reach out on zulip if you get stuck +good foundation when looking at the code itself. Please reach out on Zulip if you get stuck while doing so or there are some quirks and design decisions which were unclear and deserve better comments or should be mentioned here. diff --git a/src/doc/rustc-dev-guide/src/typing_parameter_envs.md b/src/doc/rustc-dev-guide/src/typing_parameter_envs.md index fd77f42ba7e..35e62f195f9 100644 --- a/src/doc/rustc-dev-guide/src/typing_parameter_envs.md +++ b/src/doc/rustc-dev-guide/src/typing_parameter_envs.md @@ -82,7 +82,7 @@ In the large majority of cases, when a `ParamEnv` is required it either already - In the next-gen trait solver all `Goal`s have a [`param_env` field][goal_param_env] specifying what environment to prove the goal in - When editing an existing [`TypeRelation`][typerelation] if it implements [`PredicateEmittingRelation`][predicate_emitting_relation] then a [`param_env` method][typerelation_param_env] will be available. -If you aren't sure if there's a `ParamEnv` in scope somewhere that can be used it can be worth opening a thread in the [`#t-compiler/help`][compiler_help] zulip channel where someone may be able to point out where a `ParamEnv` can be acquired from. +If you aren't sure if there's a `ParamEnv` in scope somewhere that can be used it can be worth opening a thread in the [`#t-compiler/help`][compiler_help] Zulip channel where someone may be able to point out where a `ParamEnv` can be acquired from. Manually constructing a `ParamEnv` is typically only needed at the start of some kind of top level analysis (e.g. hir typeck or borrow checking). In such cases there are three ways it can be done: - Calling the [`tcx.param_env(def_id)` query][param_env_query] which returns the environment associated with a given definition. -- cgit 1.4.1-3-g733a5 From 4156ed61065205b47680a3650f50995cac3fef8d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 6 Sep 2025 05:44:29 +0200 Subject: reduce overlong physical lines (sembr) --- .../rustc-dev-guide/src/typing_parameter_envs.md | 71 ++++++++++++++++------ 1 file changed, 51 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/src/typing_parameter_envs.md b/src/doc/rustc-dev-guide/src/typing_parameter_envs.md index 35e62f195f9..45635ebfa15 100644 --- a/src/doc/rustc-dev-guide/src/typing_parameter_envs.md +++ b/src/doc/rustc-dev-guide/src/typing_parameter_envs.md @@ -2,11 +2,14 @@ ## Typing Environments -When interacting with the type system there are a few variables to consider that can affect the results of trait solving. The set of in-scope where clauses, and what phase of the compiler type system operations are being performed in (the [`ParamEnv`][penv] and [`TypingMode`][tmode] structs respectively). +When interacting with the type system there are a few variables to consider that can affect the results of trait solving. +The set of in-scope where clauses, and what phase of the compiler type system operations are being performed in (the [`ParamEnv`][penv] and [`TypingMode`][tmode] structs respectively). -When an environment to perform type system operations in has not yet been created, the [`TypingEnv`][tenv] can be used to bundle all of the external context required into a single type. +When an environment to perform type system operations in has not yet been created, +the [`TypingEnv`][tenv] can be used to bundle all of the external context required into a single type. -Once a context to perform type system operations in has been created (e.g. an [`ObligationCtxt`][ocx] or [`FnCtxt`][fnctxt]) a `TypingEnv` is typically not stored anywhere as only the `TypingMode` is a property of the whole environment, whereas different `ParamEnv`s can be used on a per-goal basis. +Once a context to perform type system operations in has been created (e.g. an [`ObligationCtxt`][ocx] or [`FnCtxt`][fnctxt]) a `TypingEnv` is typically not stored anywhere as only the `TypingMode` is a property of the whole environment, +whereas different `ParamEnv`s can be used on a per-goal basis. [ocx]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/struct.ObligationCtxt.html [fnctxt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html @@ -15,9 +18,14 @@ Once a context to perform type system operations in has been created (e.g. an [` ### What is a `ParamEnv` -The [`ParamEnv`][penv] is a list of in-scope where-clauses, it typically corresponds to a specific item's where clauses. Some clauses are not explicitly written but are instead implicitly added in the [`predicates_of`][predicates_of] query, such as `ConstArgHasType` or (some) implied bounds. +The [`ParamEnv`][penv] is a list of in-scope where-clauses, +it typically corresponds to a specific item's where clauses. +Some clauses are not explicitly written but are instead implicitly added in the [`predicates_of`][predicates_of] query, +such as `ConstArgHasType` or (some) implied bounds. -In most cases `ParamEnv`s are initially created via the [`param_env` query][query] which returns a `ParamEnv` derived from the provided item's where clauses. A `ParamEnv` can also be created with arbitrary sets of clauses that are not derived from a specific item, such as in [`compare_method_predicate_entailment`][method_pred_entailment] where we create a hybrid `ParamEnv` consisting of the impl's where clauses and the trait definition's function's where clauses. +In most cases `ParamEnv`s are initially created via the [`param_env` query][query] which returns a `ParamEnv` derived from the provided item's where clauses. +A `ParamEnv` can also be created with arbitrary sets of clauses that are not derived from a specific item, +such as in [`compare_method_predicate_entailment`][method_pred_entailment] where we create a hybrid `ParamEnv` consisting of the impl's where clauses and the trait definition's function's where clauses. --- @@ -30,7 +38,9 @@ where ::Assoc: Clone, {} ``` -If we were conceptually inside of `foo` (for example, type-checking or linting it) we would use this `ParamEnv` everywhere that we interact with the type system. This would allow things such as [normalization], evaluating generic constants, and proving where clauses/goals, to rely on `T` being sized, implementing `Trait`, etc. +If we were conceptually inside of `foo` (for example, type-checking or linting it) we would use this `ParamEnv` everywhere that we interact with the type system. +This would allow things such as [normalization], evaluating generic constants, +and proving where clauses/goals, to rely on `T` being sized, implementing `Trait`, etc. A more concrete example: ```rust @@ -72,9 +82,13 @@ fn foo2(a: T) { ### Acquiring a `ParamEnv` -Using the wrong [`ParamEnv`][penv] when interacting with the type system can lead to ICEs, illformed programs compiling, or erroring when we shouldn't. See [#82159](https://github.com/rust-lang/rust/pull/82159) and [#82067](https://github.com/rust-lang/rust/pull/82067) as examples of PRs that modified the compiler to use the correct param env and in the process fixed ICEs. +Using the wrong [`ParamEnv`][penv] when interacting with the type system can lead to ICEs, +illformed programs compiling, or erroring when we shouldn't. +See [#82159](https://github.com/rust-lang/rust/pull/82159) and [#82067](https://github.com/rust-lang/rust/pull/82067) as examples of PRs that modified the compiler to use the correct param env and in the process fixed ICEs. -In the large majority of cases, when a `ParamEnv` is required it either already exists somewhere in scope, or above in the call stack and should be passed down. A non exhaustive list of places where you might find an existing `ParamEnv`: +In the large majority of cases, when a `ParamEnv` is required it either already exists somewhere in scope, +or above in the call stack and should be passed down. +A non exhaustive list of places where you might find an existing `ParamEnv`: - During typeck `FnCtxt` has a [`param_env` field][fnctxt_param_env] - When writing late lints the `LateContext` has a [`param_env` field][latectxt_param_env] - During well formedness checking the `WfCheckingCtxt` has a [`param_env` field][wfckctxt_param_env] @@ -84,14 +98,18 @@ In the large majority of cases, when a `ParamEnv` is required it either already If you aren't sure if there's a `ParamEnv` in scope somewhere that can be used it can be worth opening a thread in the [`#t-compiler/help`][compiler_help] Zulip channel where someone may be able to point out where a `ParamEnv` can be acquired from. -Manually constructing a `ParamEnv` is typically only needed at the start of some kind of top level analysis (e.g. hir typeck or borrow checking). In such cases there are three ways it can be done: +Manually constructing a `ParamEnv` is typically only needed at the start of some kind of top level analysis (e.g. hir typeck or borrow checking). +In such cases there are three ways it can be done: - Calling the [`tcx.param_env(def_id)` query][param_env_query] which returns the environment associated with a given definition. - Creating an empty environment with [`ParamEnv::empty`][env_empty]. -- Using [`ParamEnv::new`][param_env_new] to construct an env with an arbitrary set of where clauses. Then calling [`traits::normalize_param_env_or_error`][normalize_env_or_error] to handle normalizing and elaborating all the where clauses in the env. +- Using [`ParamEnv::new`][param_env_new] to construct an env with an arbitrary set of where clauses. + Then calling [`traits::normalize_param_env_or_error`][normalize_env_or_error] to handle normalizing and elaborating all the where clauses in the env. Using the `param_env` query is by far the most common way to construct a `ParamEnv` as most of the time the compiler is performing an analysis as part of some specific definition. -Creating an empty environment with `ParamEnv::empty` is typically only done either in codegen (indirectly via [`TypingEnv::fully_monomorphized`][tenv_mono]), or as part of some analysis that do not expect to ever encounter generic parameters (e.g. various parts of coherence/orphan check). +Creating an empty environment with `ParamEnv::empty` is typically only done either in codegen (indirectly via [`TypingEnv::fully_monomorphized`][tenv_mono]), +or as part of some analysis that do not expect to ever encounter generic parameters +(e.g. various parts of coherence/orphan check). Creating an env from an arbitrary set of where clauses is usually unnecessary and should only be done if the environment you need does not correspond to an actual item in the source code (e.g. [`compare_method_predicate_entailment`][method_pred_entailment]). @@ -113,11 +131,14 @@ Creating an env from an arbitrary set of where clauses is usually unnecessary an ### How are `ParamEnv`s constructed -Creating a [`ParamEnv`][pe] is more complicated than simply using the list of where clauses defined on an item as written by the user. We need to both elaborate supertraits into the env and fully normalize all aliases. This logic is handled by [`traits::normalize_param_env_or_error`][normalize_env_or_error] (even though it does not mention anything about elaboration). +Creating a [`ParamEnv`][pe] is more complicated than simply using the list of where clauses defined on an item as written by the user. +We need to both elaborate supertraits into the env and fully normalize all aliases. +This logic is handled by [`traits::normalize_param_env_or_error`][normalize_env_or_error] (even though it does not mention anything about elaboration). #### Elaborating supertraits -When we have a function such as `fn foo()` we would like to be able to prove `T: Clone` inside of the function as the `Copy` trait has a `Clone` supertrait. Constructing a `ParamEnv` looks at all of the trait bounds in the env and explicitly adds new where clauses to the `ParamEnv` for any supertraits found on the traits. +When we have a function such as `fn foo()` we would like to be able to prove `T: Clone` inside of the function as the `Copy` trait has a `Clone` supertrait. +Constructing a `ParamEnv` looks at all of the trait bounds in the env and explicitly adds new where clauses to the `ParamEnv` for any supertraits found on the traits. A concrete example would be the following function: ```rust @@ -133,13 +154,16 @@ fn bar(a: T) { fn requires_impl(a: T) {} ``` -If we did not elaborate the env then the `requires_impl` call would fail to typecheck as we would not be able to prove `T: Clone` or `T: SuperSuperTrait`. In practice we elaborate the env which means that `bar`'s `ParamEnv` is actually: +If we did not elaborate the env then the `requires_impl` call would fail to typecheck as we would not be able to prove `T: Clone` or `T: SuperSuperTrait`. +In practice we elaborate the env which means that `bar`'s `ParamEnv` is actually: `[T: Sized, T: Copy, T: Clone, T: Trait, T: SuperTrait, T: SuperSuperTrait]` This allows us to prove `T: Clone` and `T: SuperSuperTrait` when type checking `bar`. The `Clone` trait has a `Sized` supertrait however we do not end up with two `T: Sized` bounds in the env (one for the supertrait and one for the implicitly added `T: Sized` bound) as the elaboration process (implemented via [`util::elaborate`][elaborate]) deduplicates where clauses. -A side effect of this is that even if no actual elaboration of supertraits takes place, the existing where clauses in the env are _also_ deduplicated. See the following example: +A side effect of this is that even if no actual elaboration of supertraits takes place, +the existing where clauses in the env are _also_ deduplicated. +See the following example: ```rust trait Trait {} // The unelaborated `ParamEnv` would be: @@ -156,7 +180,8 @@ The [next-gen trait solver][next-gen-solver] also requires this elaboration to t #### Normalizing all bounds -In the old trait solver the where clauses stored in `ParamEnv` are required to be fully normalized as otherwise the trait solver will not function correctly. A concrete example of needing to normalize the `ParamEnv` is the following: +In the old trait solver the where clauses stored in `ParamEnv` are required to be fully normalized as otherwise the trait solver will not function correctly. +A concrete example of needing to normalize the `ParamEnv` is the following: ```rust trait Trait { type Assoc; @@ -182,11 +207,14 @@ where fn requires_impl>(_: U) {} ``` -As humans we can tell that `::Bar` is equal to `u32` so the trait bound on `U` is equivalent to `U: Trait`. In practice trying to prove `U: Trait` in the old solver in this environment would fail as it is unable to determine that `::Bar` is equal to `u32`. +As humans we can tell that `::Bar` is equal to `u32` so the trait bound on `U` is equivalent to `U: Trait`. +In practice trying to prove `U: Trait` in the old solver in this environment would fail as it is unable to determine that `::Bar` is equal to `u32`. To work around this we normalize `ParamEnv`'s after constructing them so that `foo`'s `ParamEnv` is actually: `[T: Sized, U: Sized, U: Trait]` which means the trait solver is now able to use the `U: Trait` in the `ParamEnv` to determine that the trait bound `U: Trait` holds. -This workaround does not work in all cases as normalizing associated types requires a `ParamEnv` which introduces a bootstrapping problem. We need a normalized `ParamEnv` in order for normalization to give correct results, but we need to normalize to get that `ParamEnv`. Currently we normalize the `ParamEnv` once using the unnormalized param env and it tends to give okay results in practice even though there are some examples where this breaks ([example]). +This workaround does not work in all cases as normalizing associated types requires a `ParamEnv` which introduces a bootstrapping problem. +We need a normalized `ParamEnv` in order for normalization to give correct results, but we need to normalize to get that `ParamEnv`. +Currently we normalize the `ParamEnv` once using the unnormalized param env and it tends to give okay results in practice even though there are some examples where this breaks ([example]). In the next-gen trait solver the requirement for all where clauses in the `ParamEnv` to be fully normalized is not present and so we do not normalize when constructing `ParamEnv`s. @@ -196,9 +224,12 @@ In the next-gen trait solver the requirement for all where clauses in the `Param ## Typing Modes -Depending on what context we are performing type system operations in, different behaviour may be required. For example during coherence there are stronger requirements about when we can consider goals to not hold or when we can consider types to be unequal. +Depending on what context we are performing type system operations in, +different behaviour may be required. +For example during coherence there are stronger requirements about when we can consider goals to not hold or when we can consider types to be unequal. -Tracking which "phase" of the compiler type system operations are being performed in is done by the [`TypingMode`][tmode] enum. The documentation on the `TypingMode` enum is quite good so instead of repeating it here verbatim we would recommend reading the API documentation directly. +Tracking which "phase" of the compiler type system operations are being performed in is done by the [`TypingMode`][tmode] enum. +The documentation on the `TypingMode` enum is quite good so instead of repeating it here verbatim we would recommend reading the API documentation directly. [penv]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html [tenv]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypingEnv.html -- cgit 1.4.1-3-g733a5 From a8c669461f0c71985c72dd5b05f70b8d4d149e3b Mon Sep 17 00:00:00 2001 From: Karl Meakin Date: Sat, 2 Aug 2025 23:32:10 +0100 Subject: optimization: Don't include ASCII characters in Unicode tables The ASCII subset of Unicode is fixed and will never change, so we don't need to generate tables for it with every new Unicode version. This saves a few bytes of static data and speeds up `char::is_control` and `char::is_grapheme_extended` on ASCII inputs. Since the table lookup functions exported from the `unicode` module will give nonsensical errors on ASCII input (and in fact will panic in debug mode), I had to add some private wrapper methods to `char` which check for ASCII-ness first. --- library/alloc/src/str.rs | 5 +- library/core/src/char/methods.rs | 38 +- library/core/src/unicode/unicode_data.rs | 519 +++++++++++---------- .../unicode-table-generator/src/cascading_map.rs | 1 + src/tools/unicode-table-generator/src/main.rs | 1 + .../unicode-table-generator/src/raw_emitter.rs | 1 + src/tools/unicode-table-generator/src/skiplist.rs | 2 + 7 files changed, 320 insertions(+), 247 deletions(-) (limited to 'src') diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index 22cdd8ecde0..e772ac25a95 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -418,9 +418,8 @@ impl str { } fn case_ignorable_then_cased>(iter: I) -> bool { - use core::unicode::{Case_Ignorable, Cased}; - match iter.skip_while(|&c| Case_Ignorable(c)).next() { - Some(c) => Cased(c), + match iter.skip_while(|&c| c.is_case_ignorable()).next() { + Some(c) => c.is_cased(), None => false, } } diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 3336d028e27..76f54db2870 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -969,7 +969,43 @@ impl char { #[must_use] #[inline] pub(crate) fn is_grapheme_extended(self) -> bool { - unicode::Grapheme_Extend(self) + !self.is_ascii() && unicode::Grapheme_Extend(self) + } + + /// Returns `true` if this `char` has the `Cased` property. + /// + /// `Cased` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and + /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`]. + /// + /// [Unicode Standard]: https://www.unicode.org/versions/latest/ + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt + #[must_use] + #[inline] + #[doc(hidden)] + #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")] + pub fn is_cased(self) -> bool { + if self.is_ascii() { self.is_ascii_alphabetic() } else { unicode::Cased(self) } + } + + /// Returns `true` if this `char` has the `Case_Ignorable` property. + /// + /// `Case_Ignorable` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and + /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`]. + /// + /// [Unicode Standard]: https://www.unicode.org/versions/latest/ + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt + #[must_use] + #[inline] + #[doc(hidden)] + #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")] + pub fn is_case_ignorable(self) -> bool { + if self.is_ascii() { + matches!(self, '\'' | '.' | ':' | '^' | '`') + } else { + unicode::Case_Ignorable(self) + } } /// Returns `true` if this `char` has one of the general categories for numbers. diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs index 0bf2f948e85..2f53de183f6 100644 --- a/library/core/src/unicode/unicode_data.rs +++ b/library/core/src/unicode/unicode_data.rs @@ -1,16 +1,15 @@ //! This file is generated by `./x run src/tools/unicode-table-generator`; do not edit manually! -// Alphabetic : 1727 bytes, 142759 codepoints in 757 ranges (U+000041 - U+0323B0) using skiplist -// Case_Ignorable : 1053 bytes, 2749 codepoints in 452 ranges (U+000027 - U+0E01F0) using skiplist -// Cased : 407 bytes, 4578 codepoints in 159 ranges (U+000041 - U+01F18A) using skiplist -// Cc : 9 bytes, 65 codepoints in 2 ranges (U+000000 - U+0000A0) using skiplist +// Alphabetic : 1723 bytes, 142707 codepoints in 755 ranges (U+0000AA - U+0323B0) using skiplist +// Case_Ignorable : 1043 bytes, 2744 codepoints in 447 ranges (U+0000A8 - U+0E01F0) using skiplist +// Cased : 403 bytes, 4526 codepoints in 157 ranges (U+0000AA - U+01F18A) using skiplist // Grapheme_Extend : 887 bytes, 2193 codepoints in 375 ranges (U+000300 - U+0E01F0) using skiplist -// Lowercase : 935 bytes, 2569 codepoints in 675 ranges (U+000061 - U+01E944) using bitset -// N : 457 bytes, 1911 codepoints in 144 ranges (U+000030 - U+01FBFA) using skiplist -// Uppercase : 799 bytes, 1978 codepoints in 656 ranges (U+000041 - U+01F18A) using bitset -// White_Space : 256 bytes, 25 codepoints in 10 ranges (U+000009 - U+003001) using cascading +// Lowercase : 933 bytes, 2543 codepoints in 674 ranges (U+0000AA - U+01E944) using bitset +// N : 455 bytes, 1901 codepoints in 143 ranges (U+0000B2 - U+01FBFA) using skiplist +// Uppercase : 797 bytes, 1952 codepoints in 655 ranges (U+0000C0 - U+01F18A) using bitset +// White_Space : 256 bytes, 19 codepoints in 8 ranges (U+000085 - U+003001) using cascading // to_lower : 11484 bytes // to_upper : 13432 bytes -// Total : 31446 bytes +// Total : 31413 bytes #[inline(always)] const fn bitset_search< @@ -148,93 +147,100 @@ pub mod alphabetic { use super::ShortOffsetRunHeader; static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 53] = [ - ShortOffsetRunHeader::new(0, 706), ShortOffsetRunHeader::new(16, 4681), - ShortOffsetRunHeader::new(418, 5741), ShortOffsetRunHeader::new(456, 7958), - ShortOffsetRunHeader::new(556, 9398), ShortOffsetRunHeader::new(627, 11264), - ShortOffsetRunHeader::new(629, 12293), ShortOffsetRunHeader::new(667, 13312), - ShortOffsetRunHeader::new(691, 19904), ShortOffsetRunHeader::new(692, 42125), - ShortOffsetRunHeader::new(694, 42509), ShortOffsetRunHeader::new(698, 55204), - ShortOffsetRunHeader::new(788, 63744), ShortOffsetRunHeader::new(793, 64110), - ShortOffsetRunHeader::new(794, 64830), ShortOffsetRunHeader::new(816, 66176), - ShortOffsetRunHeader::new(857, 67383), ShortOffsetRunHeader::new(904, 73440), - ShortOffsetRunHeader::new(1221, 74650), ShortOffsetRunHeader::new(1232, 77712), - ShortOffsetRunHeader::new(1237, 78896), ShortOffsetRunHeader::new(1240, 82939), - ShortOffsetRunHeader::new(1244, 83527), ShortOffsetRunHeader::new(1246, 90368), - ShortOffsetRunHeader::new(1247, 92160), ShortOffsetRunHeader::new(1249, 92729), - ShortOffsetRunHeader::new(1250, 93504), ShortOffsetRunHeader::new(1265, 100344), - ShortOffsetRunHeader::new(1282, 101590), ShortOffsetRunHeader::new(1284, 110576), - ShortOffsetRunHeader::new(1287, 110883), ShortOffsetRunHeader::new(1294, 111356), - ShortOffsetRunHeader::new(1304, 113664), ShortOffsetRunHeader::new(1305, 119808), - ShortOffsetRunHeader::new(1315, 120486), ShortOffsetRunHeader::new(1352, 122624), - ShortOffsetRunHeader::new(1375, 123536), ShortOffsetRunHeader::new(1399, 124112), - ShortOffsetRunHeader::new(1403, 124896), ShortOffsetRunHeader::new(1409, 126464), - ShortOffsetRunHeader::new(1425, 127280), ShortOffsetRunHeader::new(1491, 131072), - ShortOffsetRunHeader::new(1497, 173792), ShortOffsetRunHeader::new(1498, 177978), - ShortOffsetRunHeader::new(1500, 183970), ShortOffsetRunHeader::new(1504, 191457), - ShortOffsetRunHeader::new(1506, 192094), ShortOffsetRunHeader::new(1508, 194560), - ShortOffsetRunHeader::new(1509, 195102), ShortOffsetRunHeader::new(1510, 196608), - ShortOffsetRunHeader::new(1511, 201547), ShortOffsetRunHeader::new(1512, 205744), - ShortOffsetRunHeader::new(1514, 1319856), + ShortOffsetRunHeader::new(0, 706), ShortOffsetRunHeader::new(12, 4681), + ShortOffsetRunHeader::new(414, 5741), ShortOffsetRunHeader::new(452, 7958), + ShortOffsetRunHeader::new(552, 9398), ShortOffsetRunHeader::new(623, 11264), + ShortOffsetRunHeader::new(625, 12293), ShortOffsetRunHeader::new(663, 13312), + ShortOffsetRunHeader::new(687, 19904), ShortOffsetRunHeader::new(688, 42125), + ShortOffsetRunHeader::new(690, 42509), ShortOffsetRunHeader::new(694, 55204), + ShortOffsetRunHeader::new(784, 63744), ShortOffsetRunHeader::new(789, 64110), + ShortOffsetRunHeader::new(790, 64830), ShortOffsetRunHeader::new(812, 66176), + ShortOffsetRunHeader::new(853, 67383), ShortOffsetRunHeader::new(900, 73440), + ShortOffsetRunHeader::new(1217, 74650), ShortOffsetRunHeader::new(1228, 77712), + ShortOffsetRunHeader::new(1233, 78896), ShortOffsetRunHeader::new(1236, 82939), + ShortOffsetRunHeader::new(1240, 83527), ShortOffsetRunHeader::new(1242, 90368), + ShortOffsetRunHeader::new(1243, 92160), ShortOffsetRunHeader::new(1245, 92729), + ShortOffsetRunHeader::new(1246, 93504), ShortOffsetRunHeader::new(1261, 100344), + ShortOffsetRunHeader::new(1278, 101590), ShortOffsetRunHeader::new(1280, 110576), + ShortOffsetRunHeader::new(1283, 110883), ShortOffsetRunHeader::new(1290, 111356), + ShortOffsetRunHeader::new(1300, 113664), ShortOffsetRunHeader::new(1301, 119808), + ShortOffsetRunHeader::new(1311, 120486), ShortOffsetRunHeader::new(1348, 122624), + ShortOffsetRunHeader::new(1371, 123536), ShortOffsetRunHeader::new(1395, 124112), + ShortOffsetRunHeader::new(1399, 124896), ShortOffsetRunHeader::new(1405, 126464), + ShortOffsetRunHeader::new(1421, 127280), ShortOffsetRunHeader::new(1487, 131072), + ShortOffsetRunHeader::new(1493, 173792), ShortOffsetRunHeader::new(1494, 177978), + ShortOffsetRunHeader::new(1496, 183970), ShortOffsetRunHeader::new(1500, 191457), + ShortOffsetRunHeader::new(1502, 192094), ShortOffsetRunHeader::new(1504, 194560), + ShortOffsetRunHeader::new(1505, 195102), ShortOffsetRunHeader::new(1506, 196608), + ShortOffsetRunHeader::new(1507, 201547), ShortOffsetRunHeader::new(1508, 205744), + ShortOffsetRunHeader::new(1510, 1319856), ]; - static OFFSETS: [u8; 1515] = [ - 65, 26, 6, 26, 47, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 0, 4, 12, 14, 5, 7, 1, 1, 1, 86, 1, 29, - 18, 1, 2, 2, 4, 1, 1, 6, 1, 1, 3, 1, 1, 1, 20, 1, 83, 1, 139, 8, 166, 1, 38, 2, 1, 6, 41, - 39, 14, 1, 1, 1, 2, 1, 2, 1, 1, 8, 27, 4, 4, 29, 11, 5, 56, 1, 7, 14, 102, 1, 8, 4, 8, 4, 3, - 10, 3, 2, 1, 16, 48, 13, 101, 24, 33, 9, 2, 4, 1, 5, 24, 2, 19, 19, 25, 7, 11, 5, 24, 1, 6, - 8, 1, 8, 42, 10, 12, 3, 7, 6, 76, 1, 16, 1, 3, 4, 15, 13, 19, 1, 8, 2, 2, 2, 22, 1, 7, 1, 1, - 3, 4, 3, 8, 2, 2, 2, 2, 1, 1, 8, 1, 4, 2, 1, 5, 12, 2, 10, 1, 4, 3, 1, 6, 4, 2, 2, 22, 1, 7, - 1, 2, 1, 2, 1, 2, 4, 5, 4, 2, 2, 2, 4, 1, 7, 4, 1, 1, 17, 6, 11, 3, 1, 9, 1, 3, 1, 22, 1, 7, - 1, 2, 1, 5, 3, 9, 1, 3, 1, 2, 3, 1, 15, 4, 21, 4, 4, 3, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, - 3, 8, 2, 2, 2, 2, 9, 2, 4, 2, 1, 5, 13, 1, 16, 2, 1, 6, 3, 3, 1, 4, 3, 2, 1, 1, 1, 2, 3, 2, - 3, 3, 3, 12, 4, 5, 3, 3, 1, 3, 3, 1, 6, 1, 40, 13, 1, 3, 1, 23, 1, 16, 3, 8, 1, 3, 1, 3, 8, - 2, 1, 3, 2, 1, 2, 4, 28, 4, 1, 8, 1, 3, 1, 23, 1, 10, 1, 5, 3, 8, 1, 3, 1, 3, 8, 2, 6, 2, 1, - 4, 13, 3, 12, 13, 1, 3, 1, 41, 2, 8, 1, 3, 1, 3, 1, 1, 5, 4, 7, 5, 22, 6, 1, 3, 1, 18, 3, - 24, 1, 9, 1, 1, 2, 7, 8, 6, 1, 1, 1, 8, 18, 2, 13, 58, 5, 7, 6, 1, 51, 2, 1, 1, 1, 5, 1, 24, - 1, 1, 1, 19, 1, 3, 2, 5, 1, 1, 6, 1, 14, 4, 32, 1, 63, 8, 1, 36, 4, 19, 4, 16, 1, 36, 67, - 55, 1, 1, 2, 5, 16, 64, 10, 4, 2, 38, 1, 1, 5, 1, 2, 43, 1, 0, 1, 4, 2, 7, 1, 1, 1, 4, 2, - 41, 1, 4, 2, 33, 1, 4, 2, 7, 1, 1, 1, 4, 2, 15, 1, 57, 1, 4, 2, 67, 37, 16, 16, 86, 2, 6, 3, - 0, 2, 17, 1, 26, 5, 75, 3, 11, 7, 20, 11, 21, 12, 20, 12, 13, 1, 3, 1, 2, 12, 52, 2, 19, 14, - 1, 4, 1, 67, 89, 7, 43, 5, 70, 10, 31, 1, 12, 4, 9, 23, 30, 2, 5, 11, 44, 4, 26, 54, 28, 4, - 63, 2, 20, 50, 1, 23, 2, 11, 3, 49, 52, 1, 15, 1, 8, 51, 42, 2, 4, 10, 44, 1, 11, 14, 55, - 22, 3, 10, 36, 2, 11, 5, 43, 2, 3, 41, 4, 1, 6, 1, 2, 3, 1, 5, 192, 19, 34, 11, 0, 2, 6, 2, - 38, 2, 6, 2, 8, 1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13, - 5, 3, 1, 7, 116, 1, 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4, - 1, 11, 2, 4, 5, 5, 4, 1, 17, 41, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1, 2, 56, 7, 1, - 16, 23, 9, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 32, 47, 1, 0, 3, 25, 9, 7, 5, 2, - 5, 4, 86, 6, 3, 1, 90, 1, 4, 5, 43, 1, 94, 17, 32, 48, 16, 0, 0, 64, 0, 67, 46, 2, 0, 3, 16, - 10, 2, 20, 47, 5, 8, 3, 113, 39, 9, 2, 103, 2, 67, 2, 2, 1, 1, 1, 8, 21, 20, 1, 33, 24, 52, - 12, 68, 1, 1, 44, 6, 3, 1, 1, 3, 10, 33, 5, 35, 13, 29, 3, 51, 1, 12, 15, 1, 16, 16, 10, 5, - 1, 55, 9, 14, 18, 23, 3, 69, 1, 1, 1, 1, 24, 3, 2, 16, 2, 4, 11, 6, 2, 6, 2, 6, 9, 7, 1, 7, - 1, 43, 1, 14, 6, 123, 21, 0, 12, 23, 4, 49, 0, 0, 2, 106, 38, 7, 12, 5, 5, 12, 1, 13, 1, 5, - 1, 1, 1, 2, 1, 2, 1, 108, 33, 0, 18, 64, 2, 54, 40, 12, 116, 5, 1, 135, 36, 26, 6, 26, 11, - 89, 3, 6, 2, 6, 2, 6, 2, 3, 35, 12, 1, 26, 1, 19, 1, 2, 1, 15, 2, 14, 34, 123, 69, 53, 0, - 29, 3, 49, 47, 32, 13, 30, 5, 43, 5, 30, 2, 36, 4, 8, 1, 5, 42, 158, 18, 36, 4, 36, 4, 40, - 8, 52, 12, 11, 1, 15, 1, 7, 1, 2, 1, 11, 1, 15, 1, 7, 1, 2, 3, 52, 12, 0, 9, 22, 10, 8, 24, - 6, 1, 42, 1, 9, 69, 6, 2, 1, 1, 44, 1, 2, 3, 1, 2, 23, 10, 23, 9, 31, 65, 19, 1, 2, 10, 22, - 10, 26, 70, 56, 6, 2, 64, 4, 1, 2, 5, 8, 1, 3, 1, 29, 42, 29, 3, 29, 35, 8, 1, 28, 27, 54, - 10, 22, 10, 19, 13, 18, 110, 73, 55, 51, 13, 51, 13, 40, 34, 28, 3, 1, 5, 23, 250, 42, 1, 2, - 3, 2, 16, 3, 55, 1, 3, 29, 10, 1, 8, 22, 42, 18, 46, 21, 27, 23, 9, 70, 43, 5, 10, 57, 9, 1, - 13, 25, 23, 51, 17, 4, 8, 35, 3, 1, 9, 64, 1, 4, 9, 2, 10, 1, 1, 1, 35, 18, 1, 34, 2, 1, 6, - 4, 62, 7, 1, 1, 1, 4, 1, 15, 1, 10, 7, 57, 23, 4, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, - 2, 2, 2, 2, 3, 1, 6, 1, 5, 7, 28, 10, 1, 1, 2, 1, 1, 38, 1, 10, 1, 1, 2, 1, 1, 4, 1, 2, 3, - 1, 1, 1, 44, 66, 1, 3, 1, 4, 20, 3, 30, 66, 2, 2, 1, 1, 184, 54, 2, 7, 25, 6, 34, 63, 1, 1, - 3, 1, 59, 54, 2, 1, 71, 27, 2, 14, 21, 7, 185, 57, 103, 64, 31, 8, 2, 1, 2, 8, 1, 2, 1, 30, - 1, 2, 2, 2, 2, 4, 93, 8, 2, 46, 2, 6, 1, 1, 1, 2, 27, 51, 2, 10, 17, 72, 5, 1, 18, 73, 199, - 33, 31, 9, 1, 45, 1, 7, 1, 1, 49, 30, 2, 22, 1, 14, 73, 7, 1, 2, 1, 44, 3, 1, 1, 2, 1, 3, 1, - 1, 2, 2, 24, 6, 1, 2, 1, 37, 1, 2, 1, 4, 1, 1, 0, 23, 9, 17, 1, 41, 3, 3, 111, 1, 79, 0, - 102, 111, 17, 196, 0, 97, 15, 0, 17, 6, 25, 0, 5, 0, 0, 47, 0, 0, 7, 31, 17, 79, 17, 30, 18, - 48, 16, 4, 31, 21, 5, 19, 0, 45, 211, 64, 128, 75, 4, 57, 7, 17, 64, 2, 1, 1, 12, 2, 14, 0, - 8, 0, 41, 10, 0, 4, 1, 7, 1, 2, 1, 0, 15, 1, 29, 3, 2, 1, 14, 4, 8, 0, 0, 107, 5, 13, 3, 9, - 7, 10, 4, 1, 0, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, - 7, 1, 28, 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2, 25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, - 25, 1, 31, 1, 25, 1, 8, 0, 31, 6, 6, 213, 7, 1, 17, 2, 7, 1, 2, 1, 5, 5, 62, 33, 1, 112, 45, - 10, 7, 16, 1, 0, 30, 18, 44, 0, 28, 228, 30, 2, 1, 0, 7, 1, 4, 1, 2, 1, 15, 1, 197, 59, 68, - 3, 1, 3, 1, 0, 4, 1, 27, 1, 2, 1, 1, 2, 1, 1, 10, 1, 4, 1, 1, 1, 1, 6, 1, 4, 1, 1, 1, 1, 1, - 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 4, 1, 7, 1, 4, 1, 4, 1, 1, 1, - 10, 1, 17, 5, 3, 1, 5, 1, 17, 0, 26, 6, 26, 6, 26, 0, 0, 32, 0, 6, 222, 2, 0, 14, 0, 15, 0, - 0, 0, 0, 0, 5, 0, 0, + static OFFSETS: [u8; 1511] = [ + 170, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 0, 4, 12, 14, 5, 7, 1, 1, 1, 86, 1, 29, 18, 1, 2, 2, + 4, 1, 1, 6, 1, 1, 3, 1, 1, 1, 20, 1, 83, 1, 139, 8, 166, 1, 38, 2, 1, 6, 41, 39, 14, 1, 1, + 1, 2, 1, 2, 1, 1, 8, 27, 4, 4, 29, 11, 5, 56, 1, 7, 14, 102, 1, 8, 4, 8, 4, 3, 10, 3, 2, 1, + 16, 48, 13, 101, 24, 33, 9, 2, 4, 1, 5, 24, 2, 19, 19, 25, 7, 11, 5, 24, 1, 6, 8, 1, 8, 42, + 10, 12, 3, 7, 6, 76, 1, 16, 1, 3, 4, 15, 13, 19, 1, 8, 2, 2, 2, 22, 1, 7, 1, 1, 3, 4, 3, 8, + 2, 2, 2, 2, 1, 1, 8, 1, 4, 2, 1, 5, 12, 2, 10, 1, 4, 3, 1, 6, 4, 2, 2, 22, 1, 7, 1, 2, 1, 2, + 1, 2, 4, 5, 4, 2, 2, 2, 4, 1, 7, 4, 1, 1, 17, 6, 11, 3, 1, 9, 1, 3, 1, 22, 1, 7, 1, 2, 1, 5, + 3, 9, 1, 3, 1, 2, 3, 1, 15, 4, 21, 4, 4, 3, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2, 2, + 2, 2, 9, 2, 4, 2, 1, 5, 13, 1, 16, 2, 1, 6, 3, 3, 1, 4, 3, 2, 1, 1, 1, 2, 3, 2, 3, 3, 3, 12, + 4, 5, 3, 3, 1, 3, 3, 1, 6, 1, 40, 13, 1, 3, 1, 23, 1, 16, 3, 8, 1, 3, 1, 3, 8, 2, 1, 3, 2, + 1, 2, 4, 28, 4, 1, 8, 1, 3, 1, 23, 1, 10, 1, 5, 3, 8, 1, 3, 1, 3, 8, 2, 6, 2, 1, 4, 13, 3, + 12, 13, 1, 3, 1, 41, 2, 8, 1, 3, 1, 3, 1, 1, 5, 4, 7, 5, 22, 6, 1, 3, 1, 18, 3, 24, 1, 9, 1, + 1, 2, 7, 8, 6, 1, 1, 1, 8, 18, 2, 13, 58, 5, 7, 6, 1, 51, 2, 1, 1, 1, 5, 1, 24, 1, 1, 1, 19, + 1, 3, 2, 5, 1, 1, 6, 1, 14, 4, 32, 1, 63, 8, 1, 36, 4, 19, 4, 16, 1, 36, 67, 55, 1, 1, 2, 5, + 16, 64, 10, 4, 2, 38, 1, 1, 5, 1, 2, 43, 1, 0, 1, 4, 2, 7, 1, 1, 1, 4, 2, 41, 1, 4, 2, 33, + 1, 4, 2, 7, 1, 1, 1, 4, 2, 15, 1, 57, 1, 4, 2, 67, 37, 16, 16, 86, 2, 6, 3, 0, 2, 17, 1, 26, + 5, 75, 3, 11, 7, 20, 11, 21, 12, 20, 12, 13, 1, 3, 1, 2, 12, 52, 2, 19, 14, 1, 4, 1, 67, 89, + 7, 43, 5, 70, 10, 31, 1, 12, 4, 9, 23, 30, 2, 5, 11, 44, 4, 26, 54, 28, 4, 63, 2, 20, 50, 1, + 23, 2, 11, 3, 49, 52, 1, 15, 1, 8, 51, 42, 2, 4, 10, 44, 1, 11, 14, 55, 22, 3, 10, 36, 2, + 11, 5, 43, 2, 3, 41, 4, 1, 6, 1, 2, 3, 1, 5, 192, 19, 34, 11, 0, 2, 6, 2, 38, 2, 6, 2, 8, 1, + 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13, 5, 3, 1, 7, 116, 1, + 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4, 1, 11, 2, 4, 5, 5, + 4, 1, 17, 41, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1, 2, 56, 7, 1, 16, 23, 9, 7, 1, + 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 32, 47, 1, 0, 3, 25, 9, 7, 5, 2, 5, 4, 86, 6, 3, + 1, 90, 1, 4, 5, 43, 1, 94, 17, 32, 48, 16, 0, 0, 64, 0, 67, 46, 2, 0, 3, 16, 10, 2, 20, 47, + 5, 8, 3, 113, 39, 9, 2, 103, 2, 67, 2, 2, 1, 1, 1, 8, 21, 20, 1, 33, 24, 52, 12, 68, 1, 1, + 44, 6, 3, 1, 1, 3, 10, 33, 5, 35, 13, 29, 3, 51, 1, 12, 15, 1, 16, 16, 10, 5, 1, 55, 9, 14, + 18, 23, 3, 69, 1, 1, 1, 1, 24, 3, 2, 16, 2, 4, 11, 6, 2, 6, 2, 6, 9, 7, 1, 7, 1, 43, 1, 14, + 6, 123, 21, 0, 12, 23, 4, 49, 0, 0, 2, 106, 38, 7, 12, 5, 5, 12, 1, 13, 1, 5, 1, 1, 1, 2, 1, + 2, 1, 108, 33, 0, 18, 64, 2, 54, 40, 12, 116, 5, 1, 135, 36, 26, 6, 26, 11, 89, 3, 6, 2, 6, + 2, 6, 2, 3, 35, 12, 1, 26, 1, 19, 1, 2, 1, 15, 2, 14, 34, 123, 69, 53, 0, 29, 3, 49, 47, 32, + 13, 30, 5, 43, 5, 30, 2, 36, 4, 8, 1, 5, 42, 158, 18, 36, 4, 36, 4, 40, 8, 52, 12, 11, 1, + 15, 1, 7, 1, 2, 1, 11, 1, 15, 1, 7, 1, 2, 3, 52, 12, 0, 9, 22, 10, 8, 24, 6, 1, 42, 1, 9, + 69, 6, 2, 1, 1, 44, 1, 2, 3, 1, 2, 23, 10, 23, 9, 31, 65, 19, 1, 2, 10, 22, 10, 26, 70, 56, + 6, 2, 64, 4, 1, 2, 5, 8, 1, 3, 1, 29, 42, 29, 3, 29, 35, 8, 1, 28, 27, 54, 10, 22, 10, 19, + 13, 18, 110, 73, 55, 51, 13, 51, 13, 40, 34, 28, 3, 1, 5, 23, 250, 42, 1, 2, 3, 2, 16, 3, + 55, 1, 3, 29, 10, 1, 8, 22, 42, 18, 46, 21, 27, 23, 9, 70, 43, 5, 10, 57, 9, 1, 13, 25, 23, + 51, 17, 4, 8, 35, 3, 1, 9, 64, 1, 4, 9, 2, 10, 1, 1, 1, 35, 18, 1, 34, 2, 1, 6, 4, 62, 7, 1, + 1, 1, 4, 1, 15, 1, 10, 7, 57, 23, 4, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2, 2, 2, 2, + 3, 1, 6, 1, 5, 7, 28, 10, 1, 1, 2, 1, 1, 38, 1, 10, 1, 1, 2, 1, 1, 4, 1, 2, 3, 1, 1, 1, 44, + 66, 1, 3, 1, 4, 20, 3, 30, 66, 2, 2, 1, 1, 184, 54, 2, 7, 25, 6, 34, 63, 1, 1, 3, 1, 59, 54, + 2, 1, 71, 27, 2, 14, 21, 7, 185, 57, 103, 64, 31, 8, 2, 1, 2, 8, 1, 2, 1, 30, 1, 2, 2, 2, 2, + 4, 93, 8, 2, 46, 2, 6, 1, 1, 1, 2, 27, 51, 2, 10, 17, 72, 5, 1, 18, 73, 199, 33, 31, 9, 1, + 45, 1, 7, 1, 1, 49, 30, 2, 22, 1, 14, 73, 7, 1, 2, 1, 44, 3, 1, 1, 2, 1, 3, 1, 1, 2, 2, 24, + 6, 1, 2, 1, 37, 1, 2, 1, 4, 1, 1, 0, 23, 9, 17, 1, 41, 3, 3, 111, 1, 79, 0, 102, 111, 17, + 196, 0, 97, 15, 0, 17, 6, 25, 0, 5, 0, 0, 47, 0, 0, 7, 31, 17, 79, 17, 30, 18, 48, 16, 4, + 31, 21, 5, 19, 0, 45, 211, 64, 128, 75, 4, 57, 7, 17, 64, 2, 1, 1, 12, 2, 14, 0, 8, 0, 41, + 10, 0, 4, 1, 7, 1, 2, 1, 0, 15, 1, 29, 3, 2, 1, 14, 4, 8, 0, 0, 107, 5, 13, 3, 9, 7, 10, 4, + 1, 0, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1, 28, + 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2, 25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, + 1, 25, 1, 8, 0, 31, 6, 6, 213, 7, 1, 17, 2, 7, 1, 2, 1, 5, 5, 62, 33, 1, 112, 45, 10, 7, 16, + 1, 0, 30, 18, 44, 0, 28, 228, 30, 2, 1, 0, 7, 1, 4, 1, 2, 1, 15, 1, 197, 59, 68, 3, 1, 3, 1, + 0, 4, 1, 27, 1, 2, 1, 1, 2, 1, 1, 10, 1, 4, 1, 1, 1, 1, 6, 1, 4, 1, 1, 1, 1, 1, 1, 3, 1, 2, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 4, 1, 7, 1, 4, 1, 4, 1, 1, 1, 10, 1, 17, + 5, 3, 1, 5, 1, 17, 0, 26, 6, 26, 6, 26, 0, 0, 32, 0, 6, 222, 2, 0, 14, 0, 15, 0, 0, 0, 0, 0, + 5, 0, 0, ]; + #[inline] pub fn lookup(c: char) -> bool { + debug_assert!(!c.is_ascii()); + (c as u32) >= 0xaa && lookup_slow(c) + } + + #[inline(never)] + fn lookup_slow(c: char) -> bool { const { assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32); let mut i = 0; @@ -254,62 +260,69 @@ pub mod case_ignorable { use super::ShortOffsetRunHeader; static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 37] = [ - ShortOffsetRunHeader::new(0, 688), ShortOffsetRunHeader::new(21, 4957), - ShortOffsetRunHeader::new(273, 5906), ShortOffsetRunHeader::new(275, 8125), - ShortOffsetRunHeader::new(385, 11388), ShortOffsetRunHeader::new(419, 12293), - ShortOffsetRunHeader::new(431, 40981), ShortOffsetRunHeader::new(443, 42232), - ShortOffsetRunHeader::new(445, 42508), ShortOffsetRunHeader::new(447, 64286), - ShortOffsetRunHeader::new(543, 65024), ShortOffsetRunHeader::new(547, 66045), - ShortOffsetRunHeader::new(577, 67456), ShortOffsetRunHeader::new(583, 68097), - ShortOffsetRunHeader::new(589, 68900), ShortOffsetRunHeader::new(601, 69291), - ShortOffsetRunHeader::new(609, 71727), ShortOffsetRunHeader::new(733, 71995), - ShortOffsetRunHeader::new(737, 72752), ShortOffsetRunHeader::new(765, 73459), - ShortOffsetRunHeader::new(795, 78896), ShortOffsetRunHeader::new(807, 90398), - ShortOffsetRunHeader::new(811, 92912), ShortOffsetRunHeader::new(815, 93504), - ShortOffsetRunHeader::new(821, 94031), ShortOffsetRunHeader::new(825, 110576), - ShortOffsetRunHeader::new(833, 113821), ShortOffsetRunHeader::new(839, 118528), - ShortOffsetRunHeader::new(843, 119143), ShortOffsetRunHeader::new(847, 121344), - ShortOffsetRunHeader::new(857, 122880), ShortOffsetRunHeader::new(869, 123566), - ShortOffsetRunHeader::new(885, 124139), ShortOffsetRunHeader::new(889, 125136), - ShortOffsetRunHeader::new(893, 127995), ShortOffsetRunHeader::new(897, 917505), - ShortOffsetRunHeader::new(899, 2032112), + ShortOffsetRunHeader::new(0, 688), ShortOffsetRunHeader::new(11, 4957), + ShortOffsetRunHeader::new(263, 5906), ShortOffsetRunHeader::new(265, 8125), + ShortOffsetRunHeader::new(375, 11388), ShortOffsetRunHeader::new(409, 12293), + ShortOffsetRunHeader::new(421, 40981), ShortOffsetRunHeader::new(433, 42232), + ShortOffsetRunHeader::new(435, 42508), ShortOffsetRunHeader::new(437, 64286), + ShortOffsetRunHeader::new(533, 65024), ShortOffsetRunHeader::new(537, 66045), + ShortOffsetRunHeader::new(567, 67456), ShortOffsetRunHeader::new(573, 68097), + ShortOffsetRunHeader::new(579, 68900), ShortOffsetRunHeader::new(591, 69291), + ShortOffsetRunHeader::new(599, 71727), ShortOffsetRunHeader::new(723, 71995), + ShortOffsetRunHeader::new(727, 72752), ShortOffsetRunHeader::new(755, 73459), + ShortOffsetRunHeader::new(785, 78896), ShortOffsetRunHeader::new(797, 90398), + ShortOffsetRunHeader::new(801, 92912), ShortOffsetRunHeader::new(805, 93504), + ShortOffsetRunHeader::new(811, 94031), ShortOffsetRunHeader::new(815, 110576), + ShortOffsetRunHeader::new(823, 113821), ShortOffsetRunHeader::new(829, 118528), + ShortOffsetRunHeader::new(833, 119143), ShortOffsetRunHeader::new(837, 121344), + ShortOffsetRunHeader::new(847, 122880), ShortOffsetRunHeader::new(859, 123566), + ShortOffsetRunHeader::new(875, 124139), ShortOffsetRunHeader::new(879, 125136), + ShortOffsetRunHeader::new(883, 127995), ShortOffsetRunHeader::new(887, 917505), + ShortOffsetRunHeader::new(889, 2032112), ]; - static OFFSETS: [u8; 905] = [ - 39, 1, 6, 1, 11, 1, 35, 1, 1, 1, 71, 1, 4, 1, 1, 1, 4, 1, 2, 2, 0, 192, 4, 2, 4, 1, 9, 2, - 1, 1, 251, 7, 207, 1, 5, 1, 49, 45, 1, 1, 1, 2, 1, 2, 1, 1, 44, 1, 11, 6, 10, 11, 1, 1, 35, - 1, 10, 21, 16, 1, 101, 8, 1, 10, 1, 4, 33, 1, 1, 1, 30, 27, 91, 11, 58, 11, 4, 1, 2, 1, 24, - 24, 43, 3, 44, 1, 7, 2, 5, 9, 41, 58, 55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 13, 1, 15, 1, - 58, 1, 4, 4, 8, 1, 20, 2, 26, 1, 2, 2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, - 57, 1, 4, 5, 1, 2, 4, 1, 20, 2, 22, 6, 1, 1, 58, 1, 2, 1, 1, 4, 8, 1, 7, 2, 11, 2, 30, 1, - 61, 1, 12, 1, 50, 1, 3, 1, 55, 1, 1, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 6, 1, - 5, 2, 20, 2, 28, 2, 57, 2, 4, 4, 8, 1, 20, 2, 29, 1, 72, 1, 7, 3, 1, 1, 90, 1, 2, 7, 11, 9, - 98, 1, 2, 9, 9, 1, 1, 7, 73, 2, 27, 1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1, - 102, 4, 1, 6, 1, 2, 2, 2, 25, 2, 4, 3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 94, 1, 0, 3, 0, 3, - 29, 2, 30, 2, 30, 2, 64, 2, 1, 7, 8, 1, 2, 11, 3, 1, 5, 1, 45, 5, 51, 1, 65, 2, 34, 1, 118, - 3, 4, 2, 9, 1, 6, 3, 219, 2, 2, 1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 39, 1, 8, 31, - 49, 4, 48, 1, 1, 5, 1, 1, 5, 1, 40, 9, 12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3, - 58, 8, 2, 2, 64, 6, 82, 3, 1, 13, 1, 7, 4, 1, 6, 1, 3, 2, 50, 63, 13, 1, 34, 101, 0, 1, 1, - 3, 11, 3, 13, 3, 13, 3, 13, 2, 12, 5, 8, 2, 10, 1, 2, 1, 2, 5, 49, 5, 1, 10, 1, 1, 13, 1, - 16, 13, 51, 33, 0, 2, 113, 3, 125, 1, 15, 1, 96, 32, 47, 1, 0, 1, 36, 4, 3, 5, 5, 1, 93, 6, - 93, 3, 0, 1, 0, 6, 0, 1, 98, 4, 1, 10, 1, 1, 28, 4, 80, 2, 14, 34, 78, 1, 23, 3, 103, 3, 3, - 2, 8, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, 2, 26, 18, 13, 1, 38, 8, 25, 11, 46, 3, 48, 1, 2, 4, - 2, 2, 17, 1, 21, 2, 66, 6, 2, 2, 2, 2, 12, 1, 8, 1, 35, 1, 11, 1, 51, 1, 1, 3, 2, 2, 5, 2, - 1, 1, 27, 1, 14, 2, 5, 2, 1, 1, 100, 5, 9, 3, 121, 1, 2, 1, 4, 1, 0, 1, 147, 17, 0, 16, 3, - 1, 12, 16, 34, 1, 2, 1, 169, 1, 7, 1, 6, 1, 11, 1, 35, 1, 1, 1, 47, 1, 45, 2, 67, 1, 21, 3, - 0, 1, 226, 1, 149, 5, 0, 6, 1, 42, 1, 9, 0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 38, 1, - 26, 5, 1, 1, 0, 2, 79, 4, 70, 11, 49, 4, 123, 1, 54, 15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 2, - 1, 4, 1, 10, 1, 50, 3, 36, 5, 1, 8, 62, 1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3, 2, 1, 1, 2, 6, - 1, 2, 1, 157, 1, 3, 8, 21, 2, 57, 2, 3, 1, 37, 7, 3, 5, 70, 6, 13, 1, 1, 1, 1, 1, 14, 2, 85, - 8, 2, 3, 1, 1, 23, 1, 84, 6, 1, 1, 4, 2, 1, 2, 238, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2, - 106, 1, 1, 1, 2, 6, 1, 1, 101, 1, 1, 1, 2, 4, 1, 5, 0, 9, 1, 2, 0, 2, 1, 1, 4, 1, 144, 4, 2, - 2, 4, 1, 32, 10, 40, 6, 2, 4, 8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 0, 7, 1, 6, 1, 1, 82, 22, 2, - 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, 1, 1, 1, 0, 2, 11, 2, 52, 5, 5, 1, - 1, 1, 23, 1, 0, 17, 6, 15, 0, 12, 3, 3, 0, 5, 59, 7, 9, 4, 0, 3, 40, 2, 0, 1, 63, 17, 64, 2, - 1, 2, 0, 4, 1, 7, 1, 2, 0, 2, 1, 4, 0, 46, 2, 23, 0, 3, 9, 16, 2, 7, 30, 4, 148, 3, 0, 55, - 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, 7, 1, 17, 2, 7, 1, 2, 1, 5, 5, 62, 33, 1, 160, 14, 0, - 1, 61, 4, 0, 5, 254, 2, 0, 7, 109, 8, 0, 5, 0, 1, 30, 96, 128, 240, 0, + static OFFSETS: [u8; 895] = [ + 168, 1, 4, 1, 1, 1, 4, 1, 2, 2, 0, 192, 4, 2, 4, 1, 9, 2, 1, 1, 251, 7, 207, 1, 5, 1, 49, + 45, 1, 1, 1, 2, 1, 2, 1, 1, 44, 1, 11, 6, 10, 11, 1, 1, 35, 1, 10, 21, 16, 1, 101, 8, 1, 10, + 1, 4, 33, 1, 1, 1, 30, 27, 91, 11, 58, 11, 4, 1, 2, 1, 24, 24, 43, 3, 44, 1, 7, 2, 5, 9, 41, + 58, 55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 13, 1, 15, 1, 58, 1, 4, 4, 8, 1, 20, 2, 26, 1, 2, + 2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, 20, 2, 22, 6, + 1, 1, 58, 1, 2, 1, 1, 4, 8, 1, 7, 2, 11, 2, 30, 1, 61, 1, 12, 1, 50, 1, 3, 1, 55, 1, 1, 3, + 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 6, 1, 5, 2, 20, 2, 28, 2, 57, 2, 4, 4, 8, 1, + 20, 2, 29, 1, 72, 1, 7, 3, 1, 1, 90, 1, 2, 7, 11, 9, 98, 1, 2, 9, 9, 1, 1, 7, 73, 2, 27, 1, + 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1, 102, 4, 1, 6, 1, 2, 2, 2, 25, 2, 4, 3, + 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 94, 1, 0, 3, 0, 3, 29, 2, 30, 2, 30, 2, 64, 2, 1, 7, 8, 1, + 2, 11, 3, 1, 5, 1, 45, 5, 51, 1, 65, 2, 34, 1, 118, 3, 4, 2, 9, 1, 6, 3, 219, 2, 2, 1, 58, + 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 39, 1, 8, 31, 49, 4, 48, 1, 1, 5, 1, 1, 5, 1, 40, 9, + 12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3, 58, 8, 2, 2, 64, 6, 82, 3, 1, 13, 1, 7, + 4, 1, 6, 1, 3, 2, 50, 63, 13, 1, 34, 101, 0, 1, 1, 3, 11, 3, 13, 3, 13, 3, 13, 2, 12, 5, 8, + 2, 10, 1, 2, 1, 2, 5, 49, 5, 1, 10, 1, 1, 13, 1, 16, 13, 51, 33, 0, 2, 113, 3, 125, 1, 15, + 1, 96, 32, 47, 1, 0, 1, 36, 4, 3, 5, 5, 1, 93, 6, 93, 3, 0, 1, 0, 6, 0, 1, 98, 4, 1, 10, 1, + 1, 28, 4, 80, 2, 14, 34, 78, 1, 23, 3, 103, 3, 3, 2, 8, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, 2, + 26, 18, 13, 1, 38, 8, 25, 11, 46, 3, 48, 1, 2, 4, 2, 2, 17, 1, 21, 2, 66, 6, 2, 2, 2, 2, 12, + 1, 8, 1, 35, 1, 11, 1, 51, 1, 1, 3, 2, 2, 5, 2, 1, 1, 27, 1, 14, 2, 5, 2, 1, 1, 100, 5, 9, + 3, 121, 1, 2, 1, 4, 1, 0, 1, 147, 17, 0, 16, 3, 1, 12, 16, 34, 1, 2, 1, 169, 1, 7, 1, 6, 1, + 11, 1, 35, 1, 1, 1, 47, 1, 45, 2, 67, 1, 21, 3, 0, 1, 226, 1, 149, 5, 0, 6, 1, 42, 1, 9, 0, + 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 38, 1, 26, 5, 1, 1, 0, 2, 79, 4, 70, 11, 49, 4, + 123, 1, 54, 15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 2, 1, 4, 1, 10, 1, 50, 3, 36, 5, 1, 8, 62, + 1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3, 2, 1, 1, 2, 6, 1, 2, 1, 157, 1, 3, 8, 21, 2, 57, 2, 3, + 1, 37, 7, 3, 5, 70, 6, 13, 1, 1, 1, 1, 1, 14, 2, 85, 8, 2, 3, 1, 1, 23, 1, 84, 6, 1, 1, 4, + 2, 1, 2, 238, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2, 106, 1, 1, 1, 2, 6, 1, 1, 101, 1, 1, + 1, 2, 4, 1, 5, 0, 9, 1, 2, 0, 2, 1, 1, 4, 1, 144, 4, 2, 2, 4, 1, 32, 10, 40, 6, 2, 4, 8, 1, + 9, 6, 2, 3, 46, 13, 1, 2, 0, 7, 1, 6, 1, 1, 82, 22, 2, 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1, + 7, 1, 1, 72, 2, 3, 1, 1, 1, 0, 2, 11, 2, 52, 5, 5, 1, 1, 1, 23, 1, 0, 17, 6, 15, 0, 12, 3, + 3, 0, 5, 59, 7, 9, 4, 0, 3, 40, 2, 0, 1, 63, 17, 64, 2, 1, 2, 0, 4, 1, 7, 1, 2, 0, 2, 1, 4, + 0, 46, 2, 23, 0, 3, 9, 16, 2, 7, 30, 4, 148, 3, 0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, + 7, 1, 17, 2, 7, 1, 2, 1, 5, 5, 62, 33, 1, 160, 14, 0, 1, 61, 4, 0, 5, 254, 2, 0, 7, 109, 8, + 0, 5, 0, 1, 30, 96, 128, 240, 0, ]; + #[inline] pub fn lookup(c: char) -> bool { + debug_assert!(!c.is_ascii()); + (c as u32) >= 0xa8 && lookup_slow(c) + } + + #[inline(never)] + fn lookup_slow(c: char) -> bool { const { assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32); let mut i = 0; @@ -329,33 +342,40 @@ pub mod cased { use super::ShortOffsetRunHeader; static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 22] = [ - ShortOffsetRunHeader::new(0, 4256), ShortOffsetRunHeader::new(55, 5024), - ShortOffsetRunHeader::new(65, 7296), ShortOffsetRunHeader::new(69, 7958), - ShortOffsetRunHeader::new(78, 9398), ShortOffsetRunHeader::new(153, 11264), - ShortOffsetRunHeader::new(155, 42560), ShortOffsetRunHeader::new(167, 43824), - ShortOffsetRunHeader::new(187, 64256), ShortOffsetRunHeader::new(193, 65313), - ShortOffsetRunHeader::new(197, 66560), ShortOffsetRunHeader::new(201, 67456), - ShortOffsetRunHeader::new(223, 68736), ShortOffsetRunHeader::new(231, 71840), - ShortOffsetRunHeader::new(239, 93760), ShortOffsetRunHeader::new(241, 119808), - ShortOffsetRunHeader::new(243, 120486), ShortOffsetRunHeader::new(280, 122624), - ShortOffsetRunHeader::new(303, 122928), ShortOffsetRunHeader::new(309, 125184), - ShortOffsetRunHeader::new(311, 127280), ShortOffsetRunHeader::new(313, 1241482), + ShortOffsetRunHeader::new(0, 4256), ShortOffsetRunHeader::new(51, 5024), + ShortOffsetRunHeader::new(61, 7296), ShortOffsetRunHeader::new(65, 7958), + ShortOffsetRunHeader::new(74, 9398), ShortOffsetRunHeader::new(149, 11264), + ShortOffsetRunHeader::new(151, 42560), ShortOffsetRunHeader::new(163, 43824), + ShortOffsetRunHeader::new(183, 64256), ShortOffsetRunHeader::new(189, 65313), + ShortOffsetRunHeader::new(193, 66560), ShortOffsetRunHeader::new(197, 67456), + ShortOffsetRunHeader::new(219, 68736), ShortOffsetRunHeader::new(227, 71840), + ShortOffsetRunHeader::new(235, 93760), ShortOffsetRunHeader::new(237, 119808), + ShortOffsetRunHeader::new(239, 120486), ShortOffsetRunHeader::new(276, 122624), + ShortOffsetRunHeader::new(299, 122928), ShortOffsetRunHeader::new(305, 125184), + ShortOffsetRunHeader::new(307, 127280), ShortOffsetRunHeader::new(309, 1241482), ]; - static OFFSETS: [u8; 319] = [ - 65, 26, 6, 26, 47, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 195, 1, 4, 4, 208, 1, 36, 7, 2, 30, 5, - 96, 1, 42, 4, 2, 2, 2, 4, 1, 1, 6, 1, 1, 3, 1, 1, 1, 20, 1, 83, 1, 139, 8, 166, 1, 38, 9, - 41, 0, 38, 1, 1, 5, 1, 2, 43, 1, 4, 0, 86, 2, 6, 0, 11, 5, 43, 2, 3, 64, 192, 64, 0, 2, 6, - 2, 38, 2, 6, 2, 8, 1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, - 13, 5, 3, 1, 7, 116, 1, 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, - 4, 1, 6, 4, 1, 2, 4, 5, 5, 4, 1, 17, 32, 3, 2, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, - 1, 0, 46, 18, 30, 132, 102, 3, 4, 1, 62, 2, 2, 1, 1, 1, 8, 21, 5, 1, 3, 0, 43, 1, 14, 6, 80, - 0, 7, 12, 5, 0, 26, 6, 26, 0, 80, 96, 36, 4, 36, 116, 11, 1, 15, 1, 7, 1, 2, 1, 11, 1, 15, - 1, 7, 1, 2, 0, 1, 2, 3, 1, 42, 1, 9, 0, 51, 13, 51, 93, 22, 10, 22, 0, 64, 0, 64, 0, 85, 1, - 71, 1, 2, 2, 1, 2, 2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1, 28, 1, 4, 1, 5, - 1, 1, 3, 7, 1, 0, 2, 25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, - 8, 0, 10, 1, 20, 6, 6, 0, 62, 0, 68, 0, 26, 6, 26, 6, 26, 0, + static OFFSETS: [u8; 315] = [ + 170, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 195, 1, 4, 4, 208, 1, 36, 7, 2, 30, 5, 96, 1, 42, 4, + 2, 2, 2, 4, 1, 1, 6, 1, 1, 3, 1, 1, 1, 20, 1, 83, 1, 139, 8, 166, 1, 38, 9, 41, 0, 38, 1, 1, + 5, 1, 2, 43, 1, 4, 0, 86, 2, 6, 0, 11, 5, 43, 2, 3, 64, 192, 64, 0, 2, 6, 2, 38, 2, 6, 2, 8, + 1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13, 5, 3, 1, 7, 116, + 1, 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4, 1, 6, 4, 1, 2, 4, + 5, 5, 4, 1, 17, 32, 3, 2, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1, 0, 46, 18, 30, 132, + 102, 3, 4, 1, 62, 2, 2, 1, 1, 1, 8, 21, 5, 1, 3, 0, 43, 1, 14, 6, 80, 0, 7, 12, 5, 0, 26, 6, + 26, 0, 80, 96, 36, 4, 36, 116, 11, 1, 15, 1, 7, 1, 2, 1, 11, 1, 15, 1, 7, 1, 2, 0, 1, 2, 3, + 1, 42, 1, 9, 0, 51, 13, 51, 93, 22, 10, 22, 0, 64, 0, 64, 0, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2, + 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1, 28, 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2, 25, + 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 8, 0, 10, 1, 20, 6, 6, 0, + 62, 0, 68, 0, 26, 6, 26, 6, 26, 0, ]; + #[inline] pub fn lookup(c: char) -> bool { + debug_assert!(!c.is_ascii()); + (c as u32) >= 0xaa && lookup_slow(c) + } + + #[inline(never)] + fn lookup_slow(c: char) -> bool { const { assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32); let mut i = 0; @@ -424,6 +444,7 @@ pub mod grapheme_extend { ]; #[inline] pub fn lookup(c: char) -> bool { + debug_assert!(!c.is_ascii()); (c as u32) >= 0x300 && lookup_slow(c) } @@ -446,7 +467,7 @@ pub mod grapheme_extend { #[rustfmt::skip] pub mod lowercase { static BITSET_CHUNKS_MAP: [u8; 123] = [ - 14, 17, 0, 0, 9, 0, 0, 12, 13, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 12, 17, 0, 0, 9, 0, 0, 13, 14, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 15, 0, 8, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, @@ -458,37 +479,37 @@ pub mod lowercase { [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 14, 56, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 43, 0, 52, 48, 50, 33], - [0, 0, 0, 0, 10, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 9, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 3, 0, 16, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27], [0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 34, 17, 23, 53, 54, 49, 47, 7, 35, 42, 0, 28, 12, 31], [0, 0, 46, 0, 56, 56, 56, 0, 22, 22, 69, 22, 36, 25, 24, 37], [0, 5, 70, 0, 29, 15, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 66, 34, 17, 23, 53, 54, 49, 47, 8, 35, 42, 0, 28, 13, 31], - [11, 60, 0, 6, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 32, 0], + [10, 60, 0, 6, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 32, 0], [16, 26, 22, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [16, 51, 2, 21, 68, 9, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [16, 51, 2, 21, 68, 8, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0], [16, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [65, 41, 55, 12, 77, 63, 18, 1, 7, 64, 76, 20, 73, 74, 4, 45], + [65, 41, 55, 11, 66, 63, 18, 13, 1, 64, 76, 20, 73, 74, 4, 45], ]; static BITSET_CANONICAL: [u64; 56] = [ 0b0000000000000000000000000000000000000000000000000000000000000000, - 0b1111111111111111110000000000000000000000000011111111111111111111, + 0b0000111111111111111111111111110000000000000000000000000011111111, 0b1010101010101010101010101010101010101010101010101010100000000010, 0b0000000000000111111111111111111111111111111111111111111111111111, 0b1111111111111111111111000000000000000000000000001111110111111111, 0b1000000000000010000000000000000000000000000000000000000000000000, 0b0000111111111111111111111111111111111111000000000000000000000000, - 0b0000111111111111111111111111110000000000000000000000000011111111, 0b1111111111111111111111111111111111111111111111111010101010000101, 0b1111111111111111111111111111111100000000000000000000000000000000, 0b1111111111111111111111111111110000000000000000000000000000000000, 0b1111111111111111111111110000000000000000000000000000000000000000, 0b1111111111111111111111000000000000000000000000001111111111101111, 0b1111111111111111111100000000000000000000000000010000000000000000, + 0b1111111111111111110000000000000000000000000011111111111111111111, 0b1111111111111111000000111111111111110111111111111111111111111111, 0b1111111111111111000000000000000000000000000000000100001111000000, 0b1111111111111111000000000000000000000000000000000000000000000000, @@ -532,13 +553,15 @@ pub mod lowercase { 0b1110011001010001001011010010101001001110001001000011000100101001, 0b1110101111000000000000000000000000001111111111111111111111111100, ]; - static BITSET_MAPPING: [(u8, u8); 22] = [ - (0, 64), (1, 188), (1, 186), (1, 183), (1, 176), (1, 109), (1, 124), (1, 126), (1, 66), - (1, 70), (1, 77), (2, 146), (2, 144), (2, 83), (3, 93), (3, 147), (3, 133), (4, 12), (4, 6), - (5, 187), (6, 78), (7, 132), + static BITSET_MAPPING: [(u8, u8); 21] = [ + (0, 64), (1, 184), (1, 182), (1, 179), (1, 172), (1, 161), (1, 146), (1, 144), (1, 140), + (1, 136), (1, 132), (2, 146), (2, 144), (2, 83), (3, 93), (3, 147), (3, 133), (4, 12), + (4, 6), (5, 187), (6, 78), ]; pub const fn lookup(c: char) -> bool { + debug_assert!(!c.is_ascii()); + (c as u32) >= 0xaa && super::bitset_search( c as u32, &BITSET_CHUNKS_MAP, @@ -554,43 +577,50 @@ pub mod n { use super::ShortOffsetRunHeader; static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 42] = [ - ShortOffsetRunHeader::new(0, 1632), ShortOffsetRunHeader::new(9, 2406), - ShortOffsetRunHeader::new(15, 4160), ShortOffsetRunHeader::new(49, 4969), - ShortOffsetRunHeader::new(53, 5870), ShortOffsetRunHeader::new(55, 6470), - ShortOffsetRunHeader::new(63, 8304), ShortOffsetRunHeader::new(79, 9312), - ShortOffsetRunHeader::new(89, 10102), ShortOffsetRunHeader::new(93, 11517), - ShortOffsetRunHeader::new(95, 12295), ShortOffsetRunHeader::new(97, 12690), - ShortOffsetRunHeader::new(103, 42528), ShortOffsetRunHeader::new(115, 43056), - ShortOffsetRunHeader::new(119, 44016), ShortOffsetRunHeader::new(131, 65296), - ShortOffsetRunHeader::new(133, 65799), ShortOffsetRunHeader::new(135, 66273), - ShortOffsetRunHeader::new(141, 67672), ShortOffsetRunHeader::new(153, 68858), - ShortOffsetRunHeader::new(183, 69216), ShortOffsetRunHeader::new(189, 70736), - ShortOffsetRunHeader::new(209, 71248), ShortOffsetRunHeader::new(213, 71904), - ShortOffsetRunHeader::new(221, 72688), ShortOffsetRunHeader::new(225, 73552), - ShortOffsetRunHeader::new(233, 74752), ShortOffsetRunHeader::new(237, 90416), - ShortOffsetRunHeader::new(239, 92768), ShortOffsetRunHeader::new(241, 93552), - ShortOffsetRunHeader::new(249, 93824), ShortOffsetRunHeader::new(251, 118000), - ShortOffsetRunHeader::new(253, 119488), ShortOffsetRunHeader::new(255, 120782), - ShortOffsetRunHeader::new(261, 123200), ShortOffsetRunHeader::new(263, 123632), - ShortOffsetRunHeader::new(265, 124144), ShortOffsetRunHeader::new(267, 125127), - ShortOffsetRunHeader::new(271, 126065), ShortOffsetRunHeader::new(275, 127232), - ShortOffsetRunHeader::new(285, 130032), ShortOffsetRunHeader::new(287, 1244154), + ShortOffsetRunHeader::new(0, 1632), ShortOffsetRunHeader::new(7, 2406), + ShortOffsetRunHeader::new(13, 4160), ShortOffsetRunHeader::new(47, 4969), + ShortOffsetRunHeader::new(51, 5870), ShortOffsetRunHeader::new(53, 6470), + ShortOffsetRunHeader::new(61, 8304), ShortOffsetRunHeader::new(77, 9312), + ShortOffsetRunHeader::new(87, 10102), ShortOffsetRunHeader::new(91, 11517), + ShortOffsetRunHeader::new(93, 12295), ShortOffsetRunHeader::new(95, 12690), + ShortOffsetRunHeader::new(101, 42528), ShortOffsetRunHeader::new(113, 43056), + ShortOffsetRunHeader::new(117, 44016), ShortOffsetRunHeader::new(129, 65296), + ShortOffsetRunHeader::new(131, 65799), ShortOffsetRunHeader::new(133, 66273), + ShortOffsetRunHeader::new(139, 67672), ShortOffsetRunHeader::new(151, 68858), + ShortOffsetRunHeader::new(181, 69216), ShortOffsetRunHeader::new(187, 70736), + ShortOffsetRunHeader::new(207, 71248), ShortOffsetRunHeader::new(211, 71904), + ShortOffsetRunHeader::new(219, 72688), ShortOffsetRunHeader::new(223, 73552), + ShortOffsetRunHeader::new(231, 74752), ShortOffsetRunHeader::new(235, 90416), + ShortOffsetRunHeader::new(237, 92768), ShortOffsetRunHeader::new(239, 93552), + ShortOffsetRunHeader::new(247, 93824), ShortOffsetRunHeader::new(249, 118000), + ShortOffsetRunHeader::new(251, 119488), ShortOffsetRunHeader::new(253, 120782), + ShortOffsetRunHeader::new(259, 123200), ShortOffsetRunHeader::new(261, 123632), + ShortOffsetRunHeader::new(263, 124144), ShortOffsetRunHeader::new(265, 125127), + ShortOffsetRunHeader::new(269, 126065), ShortOffsetRunHeader::new(273, 127232), + ShortOffsetRunHeader::new(283, 130032), ShortOffsetRunHeader::new(285, 1244154), ]; - static OFFSETS: [u8; 289] = [ - 48, 10, 120, 2, 5, 1, 2, 3, 0, 10, 134, 10, 198, 10, 0, 10, 118, 10, 4, 6, 108, 10, 118, - 10, 118, 10, 2, 6, 110, 13, 115, 10, 8, 7, 103, 10, 104, 7, 7, 19, 109, 10, 96, 10, 118, 10, - 70, 20, 0, 10, 70, 10, 0, 20, 0, 3, 239, 10, 6, 10, 22, 10, 0, 10, 128, 11, 165, 10, 6, 10, - 182, 10, 86, 10, 134, 10, 6, 10, 0, 1, 3, 6, 6, 10, 198, 51, 2, 5, 0, 60, 78, 22, 0, 30, 0, - 1, 0, 1, 25, 9, 14, 3, 0, 4, 138, 10, 30, 8, 1, 15, 32, 10, 39, 15, 0, 10, 188, 10, 0, 6, - 154, 10, 38, 10, 198, 10, 22, 10, 86, 10, 0, 10, 0, 10, 0, 45, 12, 57, 17, 2, 0, 27, 36, 4, - 29, 1, 8, 1, 134, 5, 202, 10, 0, 8, 25, 7, 39, 9, 75, 5, 22, 6, 160, 2, 2, 16, 2, 46, 64, 9, - 52, 2, 30, 3, 75, 5, 104, 8, 24, 8, 41, 7, 0, 6, 48, 10, 6, 10, 0, 31, 158, 10, 42, 4, 112, - 7, 134, 30, 128, 10, 60, 10, 144, 10, 7, 20, 251, 10, 0, 10, 118, 10, 0, 10, 102, 10, 6, 20, - 76, 12, 0, 19, 93, 10, 0, 10, 86, 29, 227, 10, 70, 10, 0, 10, 102, 21, 0, 111, 0, 10, 0, 10, - 86, 10, 134, 10, 1, 7, 0, 10, 0, 23, 0, 10, 0, 20, 12, 20, 108, 25, 0, 50, 0, 10, 0, 10, 0, - 10, 247, 10, 0, 9, 128, 10, 0, 59, 1, 3, 1, 4, 76, 45, 1, 15, 0, 13, 0, 10, 0, + static OFFSETS: [u8; 287] = [ + 178, 2, 5, 1, 2, 3, 0, 10, 134, 10, 198, 10, 0, 10, 118, 10, 4, 6, 108, 10, 118, 10, 118, + 10, 2, 6, 110, 13, 115, 10, 8, 7, 103, 10, 104, 7, 7, 19, 109, 10, 96, 10, 118, 10, 70, 20, + 0, 10, 70, 10, 0, 20, 0, 3, 239, 10, 6, 10, 22, 10, 0, 10, 128, 11, 165, 10, 6, 10, 182, 10, + 86, 10, 134, 10, 6, 10, 0, 1, 3, 6, 6, 10, 198, 51, 2, 5, 0, 60, 78, 22, 0, 30, 0, 1, 0, 1, + 25, 9, 14, 3, 0, 4, 138, 10, 30, 8, 1, 15, 32, 10, 39, 15, 0, 10, 188, 10, 0, 6, 154, 10, + 38, 10, 198, 10, 22, 10, 86, 10, 0, 10, 0, 10, 0, 45, 12, 57, 17, 2, 0, 27, 36, 4, 29, 1, 8, + 1, 134, 5, 202, 10, 0, 8, 25, 7, 39, 9, 75, 5, 22, 6, 160, 2, 2, 16, 2, 46, 64, 9, 52, 2, + 30, 3, 75, 5, 104, 8, 24, 8, 41, 7, 0, 6, 48, 10, 6, 10, 0, 31, 158, 10, 42, 4, 112, 7, 134, + 30, 128, 10, 60, 10, 144, 10, 7, 20, 251, 10, 0, 10, 118, 10, 0, 10, 102, 10, 6, 20, 76, 12, + 0, 19, 93, 10, 0, 10, 86, 29, 227, 10, 70, 10, 0, 10, 102, 21, 0, 111, 0, 10, 0, 10, 86, 10, + 134, 10, 1, 7, 0, 10, 0, 23, 0, 10, 0, 20, 12, 20, 108, 25, 0, 50, 0, 10, 0, 10, 0, 10, 247, + 10, 0, 9, 128, 10, 0, 59, 1, 3, 1, 4, 76, 45, 1, 15, 0, 13, 0, 10, 0, ]; + #[inline] pub fn lookup(c: char) -> bool { + debug_assert!(!c.is_ascii()); + (c as u32) >= 0xb2 && lookup_slow(c) + } + + #[inline(never)] + fn lookup_slow(c: char) -> bool { const { assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32); let mut i = 0; @@ -608,34 +638,34 @@ pub mod n { #[rustfmt::skip] pub mod uppercase { static BITSET_CHUNKS_MAP: [u8; 125] = [ - 12, 15, 6, 6, 0, 6, 6, 2, 4, 11, 6, 16, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 5, 6, 14, 6, 10, 6, 6, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 13, 6, 6, - 6, 6, 9, 6, 3, + 3, 14, 6, 6, 0, 6, 6, 2, 5, 12, 6, 15, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 9, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 7, 6, 13, 6, 11, 6, 6, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 16, 6, 6, + 6, 6, 10, 6, 4, ]; static BITSET_INDEX_CHUNKS: [[u8; 16]; 17] = [ - [44, 44, 5, 35, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 5, 1], + [44, 44, 5, 35, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 5, 0], [44, 44, 5, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44], - [44, 44, 40, 44, 44, 44, 44, 44, 17, 17, 63, 17, 43, 29, 24, 23], + [44, 44, 40, 44, 44, 44, 44, 44, 17, 17, 62, 17, 43, 29, 24, 23], + [44, 44, 44, 32, 36, 21, 22, 15, 13, 34, 44, 44, 44, 11, 30, 39], [44, 44, 44, 44, 9, 8, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44], - [44, 44, 44, 44, 37, 28, 67, 44, 44, 44, 44, 44, 44, 44, 44, 44], - [44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 44, 44, 44], + [44, 44, 44, 44, 37, 28, 66, 44, 44, 44, 44, 44, 44, 44, 44, 44], [44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44], - [44, 44, 44, 44, 44, 44, 44, 44, 44, 55, 44, 44, 44, 44, 44, 44], - [44, 44, 44, 44, 44, 44, 44, 44, 44, 62, 61, 44, 20, 14, 16, 4], - [44, 44, 44, 44, 56, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44], - [44, 44, 59, 44, 44, 31, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44], - [44, 44, 60, 46, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44], - [44, 49, 44, 32, 36, 21, 22, 15, 13, 34, 44, 44, 44, 11, 30, 39], - [52, 54, 26, 50, 12, 7, 25, 51, 41, 53, 6, 3, 66, 65, 64, 68], - [57, 44, 9, 47, 44, 42, 33, 44, 44, 44, 44, 44, 44, 44, 44, 44], - [58, 19, 2, 18, 10, 48, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44], - [58, 38, 17, 27, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44], + [44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 57, 44, 44, 44], + [44, 44, 44, 44, 44, 44, 44, 44, 44, 49, 44, 44, 44, 44, 44, 44], + [44, 44, 44, 44, 44, 44, 44, 44, 44, 61, 60, 44, 20, 14, 16, 4], + [44, 44, 44, 44, 50, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44], + [44, 44, 53, 44, 44, 31, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44], + [44, 44, 54, 46, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44], + [51, 44, 9, 47, 44, 42, 33, 44, 44, 44, 44, 44, 44, 44, 44, 44], + [52, 19, 2, 18, 10, 48, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44], + [52, 38, 17, 27, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44], + [58, 1, 26, 55, 12, 7, 25, 56, 41, 59, 6, 3, 65, 64, 63, 67], ]; static BITSET_CANONICAL: [u64; 44] = [ - 0b0000011111111111111111111111111000000000000000000000000000000000, 0b0000000000111111111111111111111111111111111111111111111111111111, + 0b1111111111111111111111110000000000000000000000000011111111111111, 0b0101010101010101010101010101010101010101010101010101010000000001, 0b0000011111111111111111111111110000000000000000000000000000000001, 0b0000000000100000000000000000000000010101010000010001101011110101, @@ -679,13 +709,15 @@ pub mod uppercase { 0b1111011111111111000000000000000000000000000000000000000000000000, 0b1111111100000000111111110000000000111111000000001111111100000000, ]; - static BITSET_MAPPING: [(u8, u8); 25] = [ - (0, 187), (0, 177), (0, 171), (0, 167), (0, 164), (0, 32), (0, 47), (0, 51), (0, 121), - (0, 117), (0, 109), (1, 150), (1, 148), (1, 142), (1, 134), (1, 131), (1, 64), (2, 164), - (2, 146), (2, 20), (3, 146), (3, 140), (3, 134), (4, 178), (4, 171), + static BITSET_MAPPING: [(u8, u8); 24] = [ + (0, 182), (0, 74), (0, 166), (0, 162), (0, 159), (0, 150), (0, 148), (0, 142), (0, 134), + (0, 131), (0, 64), (1, 66), (1, 70), (1, 83), (1, 12), (1, 8), (2, 164), (2, 146), (2, 20), + (3, 146), (3, 140), (3, 134), (4, 178), (4, 171), ]; pub const fn lookup(c: char) -> bool { + debug_assert!(!c.is_ascii()); + (c as u32) >= 0xc0 && super::bitset_search( c as u32, &BITSET_CHUNKS_MAP, @@ -699,8 +731,8 @@ pub mod uppercase { #[rustfmt::skip] pub mod white_space { static WHITESPACE_MAP: [u8; 256] = [ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -711,6 +743,7 @@ pub mod white_space { ]; #[inline] pub const fn lookup(c: char) -> bool { + debug_assert!(!c.is_ascii()); match c as u32 >> 8 { 0 => WHITESPACE_MAP[c as usize & 0xff] & 1 != 0, 22 => c as u32 == 0x1680, diff --git a/src/tools/unicode-table-generator/src/cascading_map.rs b/src/tools/unicode-table-generator/src/cascading_map.rs index 78a7bba3208..56e6401908d 100644 --- a/src/tools/unicode-table-generator/src/cascading_map.rs +++ b/src/tools/unicode-table-generator/src/cascading_map.rs @@ -64,6 +64,7 @@ impl RawEmitter { writeln!(&mut self.file, "#[inline]").unwrap(); writeln!(&mut self.file, "pub const fn lookup(c: char) -> bool {{").unwrap(); + writeln!(&mut self.file, " debug_assert!(!c.is_ascii());").unwrap(); writeln!(&mut self.file, " match c as u32 >> 8 {{").unwrap(); for arm in arms { writeln!(&mut self.file, " {arm},").unwrap(); diff --git a/src/tools/unicode-table-generator/src/main.rs b/src/tools/unicode-table-generator/src/main.rs index aa7d97f7f3d..ded9205ffc4 100644 --- a/src/tools/unicode-table-generator/src/main.rs +++ b/src/tools/unicode-table-generator/src/main.rs @@ -195,6 +195,7 @@ fn load_data() -> UnicodeData { .into_iter() .flatten() .flat_map(|cp| cp.scalar()) + .filter(|c| !c.is_ascii()) .map(u32::from) .collect::>(); (prop, ranges_from_set(&codepoints)) diff --git a/src/tools/unicode-table-generator/src/raw_emitter.rs b/src/tools/unicode-table-generator/src/raw_emitter.rs index 03ed9499e26..297965615c1 100644 --- a/src/tools/unicode-table-generator/src/raw_emitter.rs +++ b/src/tools/unicode-table-generator/src/raw_emitter.rs @@ -98,6 +98,7 @@ impl RawEmitter { self.blank_line(); writeln!(&mut self.file, "pub const fn lookup(c: char) -> bool {{").unwrap(); + writeln!(&mut self.file, " debug_assert!(!c.is_ascii());").unwrap(); if first_code_point > 0x7f { writeln!(&mut self.file, " (c as u32) >= {first_code_point:#04x} &&").unwrap(); } diff --git a/src/tools/unicode-table-generator/src/skiplist.rs b/src/tools/unicode-table-generator/src/skiplist.rs index 34c9802e122..660a8f342f7 100644 --- a/src/tools/unicode-table-generator/src/skiplist.rs +++ b/src/tools/unicode-table-generator/src/skiplist.rs @@ -99,6 +99,7 @@ impl RawEmitter { if first_code_point > 0x7f { writeln!(&mut self.file, "#[inline]").unwrap(); writeln!(&mut self.file, "pub fn lookup(c: char) -> bool {{").unwrap(); + writeln!(&mut self.file, " debug_assert!(!c.is_ascii());").unwrap(); writeln!(&mut self.file, " (c as u32) >= {first_code_point:#04x} && lookup_slow(c)") .unwrap(); writeln!(&mut self.file, "}}").unwrap(); @@ -107,6 +108,7 @@ impl RawEmitter { writeln!(&mut self.file, "fn lookup_slow(c: char) -> bool {{").unwrap(); } else { writeln!(&mut self.file, "pub fn lookup(c: char) -> bool {{").unwrap(); + writeln!(&mut self.file, " debug_assert!(!c.is_ascii());").unwrap(); } writeln!(&mut self.file, " const {{").unwrap(); writeln!( -- cgit 1.4.1-3-g733a5 From cfc73b5c94243ef41eb705f7de49eb8a1efabdc6 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Mon, 8 Sep 2025 04:10:15 +0000 Subject: Prepare for merging from rust-lang/rust This updates the rust-version file to 2f3f27bf79ec147fec9d2e7980605307a74067f4. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index f412399cc8c..df2bac877b6 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -a1dbb443527bd126452875eb5d5860c1d001d761 +2f3f27bf79ec147fec9d2e7980605307a74067f4 -- cgit 1.4.1-3-g733a5 From edc94e61841506c6957e1ee0ed57a2232fe339c4 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Sun, 7 Sep 2025 23:20:40 +0200 Subject: mark `format_args_nl!` as `#[doc(hidden)]` --- library/core/src/macros/mod.rs | 1 + src/librustdoc/html/highlight.rs | 2 +- src/librustdoc/lib.rs | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index ccf41dfb01d..3f58fc448aa 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1017,6 +1017,7 @@ pub(crate) mod builtin { )] #[allow_internal_unstable(fmt_internals)] #[rustc_builtin_macro] + #[doc(hidden)] #[macro_export] macro_rules! format_args_nl { ($fmt:expr) => {{ /* compiler built-in */ }}; diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index feafb41dc99..0e06361024b 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -578,7 +578,7 @@ pub(super) fn write_code( } fn write_footer(out: &mut String, playground_button: Option<&str>) { - write_str(out, format_args_nl!("{}
", playground_button.unwrap_or_default())); + write_str(out, format_args!("{}
", playground_button.unwrap_or_default())); } /// How a span of text is classified. Mostly corresponds to token kinds. diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index f62eba4b3c1..9871066b9eb 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -10,7 +10,6 @@ #![feature(box_patterns)] #![feature(debug_closure_helpers)] #![feature(file_buffered)] -#![feature(format_args_nl)] #![feature(if_let_guard)] #![feature(iter_advance_by)] #![feature(iter_intersperse)] -- cgit 1.4.1-3-g733a5 From f7dbd752fd9abcd419ee6bdf1cccd5e806e2d6e7 Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Mon, 8 Sep 2025 19:01:31 +0200 Subject: Update books --- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/doc/nomicon b/src/doc/nomicon index 57ed4473660..f17a018b998 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 57ed4473660565d9357fcae176b358d7e8724ebf +Subproject commit f17a018b9989430967d1c58e9a12c51169abc744 diff --git a/src/doc/reference b/src/doc/reference index 89f67b3c1b9..b3ce60628c6 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 89f67b3c1b904cbcd9ed55e443d6fc67c8ca2769 +Subproject commit b3ce60628c6f55ab8ff3dba9f3d20203df1c0dee diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index ad27f82c184..dd26bc8e726 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit ad27f82c18464525c761a4a8db2e01785da59e1f +Subproject commit dd26bc8e726dc2e73534c8972d4dccd1bed7495f -- cgit 1.4.1-3-g733a5 From 8b58777968a4c663d6c1293bacff6da99e6e5203 Mon Sep 17 00:00:00 2001 From: nixxo Date: Thu, 4 Sep 2025 09:33:11 +0200 Subject: fix partial urlencoded link support - added full urlencoding to properly check urlencoded anchor links against non-urlencoded heading IDs - added tests urlecoding provided by https://crates.io/crates/urlencoding --- Cargo.lock | 7 +++++++ src/tools/linkchecker/Cargo.toml | 1 + src/tools/linkchecker/main.rs | 13 +------------ src/tools/linkchecker/tests/valid/inner/bar.html | 3 +++ src/tools/linkchecker/tests/valid/inner/foo.html | 8 ++++++++ src/tools/linkchecker/tests/valid/inner/redir-target.html | 3 +++ 6 files changed, 23 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index 52f50481157..fd4b661c40d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2167,6 +2167,7 @@ version = "0.1.0" dependencies = [ "html5ever", "regex", + "urlencoding", ] [[package]] @@ -5825,6 +5826,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf-8" version = "0.7.6" diff --git a/src/tools/linkchecker/Cargo.toml b/src/tools/linkchecker/Cargo.toml index fb5bff3fe63..f0886e31b24 100644 --- a/src/tools/linkchecker/Cargo.toml +++ b/src/tools/linkchecker/Cargo.toml @@ -10,3 +10,4 @@ path = "main.rs" [dependencies] regex = "1" html5ever = "0.29.0" +urlencoding = "2.1.3" diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 1dc45728c90..e07a0784cdb 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -232,18 +232,7 @@ enum FileEntry { type Cache = HashMap; fn small_url_encode(s: &str) -> String { - s.replace('<', "%3C") - .replace('>', "%3E") - .replace(' ', "%20") - .replace('?', "%3F") - .replace('\'', "%27") - .replace('&', "%26") - .replace(',', "%2C") - .replace(':', "%3A") - .replace(';', "%3B") - .replace('[', "%5B") - .replace(']', "%5D") - .replace('\"', "%22") + urlencoding::encode(s).to_string() } impl Checker { diff --git a/src/tools/linkchecker/tests/valid/inner/bar.html b/src/tools/linkchecker/tests/valid/inner/bar.html index 4b500d78b76..6ffda259c40 100644 --- a/src/tools/linkchecker/tests/valid/inner/bar.html +++ b/src/tools/linkchecker/tests/valid/inner/bar.html @@ -3,5 +3,8 @@

Bar

+ +

Bar

+ diff --git a/src/tools/linkchecker/tests/valid/inner/foo.html b/src/tools/linkchecker/tests/valid/inner/foo.html index 3c6a7483bcd..f30bf718205 100644 --- a/src/tools/linkchecker/tests/valid/inner/foo.html +++ b/src/tools/linkchecker/tests/valid/inner/foo.html @@ -8,7 +8,15 @@ external links not validated Redirect + + + + +

Local

+ +

Local

+ diff --git a/src/tools/linkchecker/tests/valid/inner/redir-target.html b/src/tools/linkchecker/tests/valid/inner/redir-target.html index bd59884a01e..ac1dec6d5b4 100644 --- a/src/tools/linkchecker/tests/valid/inner/redir-target.html +++ b/src/tools/linkchecker/tests/valid/inner/redir-target.html @@ -1,5 +1,8 @@

Redir

+ + +

Redir

-- cgit 1.4.1-3-g733a5 From 8d0c07f1a1ccc46f58d2c6dbf0dbf32dc0b0d6b9 Mon Sep 17 00:00:00 2001 From: Jeremy Smart Date: Thu, 31 Jul 2025 23:27:02 -0400 Subject: change end to last --- compiler/rustc_ast_lowering/src/expr.rs | 29 ++++- compiler/rustc_hir/src/hir.rs | 15 ++- compiler/rustc_hir/src/lang_items.rs | 1 + compiler/rustc_index/src/idx.rs | 15 +++ compiler/rustc_span/src/symbol.rs | 2 + library/core/src/range.rs | 140 ++++++++++++++++++--- library/core/src/range/iter.rs | 2 +- library/core/src/range/legacy.rs | 4 +- library/core/src/slice/index.rs | 41 ++++++ library/core/src/str/traits.rs | 8 +- src/tools/clippy/clippy_utils/src/sym.rs | 1 - .../std/const-generics-range.full.stderr | 2 +- .../std/const-generics-range.min.stderr | 2 +- .../ui/const-generics/std/const-generics-range.rs | 14 +-- tests/ui/iterators/ranges.stderr | 6 +- tests/ui/new-range/disabled.rs | 4 +- tests/ui/new-range/enabled.rs | 4 +- tests/ui/range/issue-54505-no-literals.stderr | 4 +- tests/ui/range/issue-54505-no-std.stderr | 2 +- tests/ui/range/issue-54505.stderr | 2 +- 20 files changed, 245 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 3674814b796..bb6b25baf01 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1536,7 +1536,13 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::LangItem::Range } } - (None, Some(..), Closed) => hir::LangItem::RangeToInclusive, + (None, Some(..), Closed) => { + if self.tcx.features().new_range() { + hir::LangItem::RangeToInclusiveCopy + } else { + hir::LangItem::RangeToInclusive + } + } (Some(e1), Some(e2), Closed) => { if self.tcx.features().new_range() { hir::LangItem::RangeInclusiveCopy @@ -1560,13 +1566,26 @@ impl<'hir> LoweringContext<'_, 'hir> { }; let fields = self.arena.alloc_from_iter( - e1.iter().map(|e| (sym::start, e)).chain(e2.iter().map(|e| (sym::end, e))).map( - |(s, e)| { + e1.iter() + .map(|e| (sym::start, e)) + .chain(e2.iter().map(|e| { + ( + if matches!( + lang_item, + hir::LangItem::RangeInclusiveCopy | hir::LangItem::RangeToInclusiveCopy + ) { + sym::last + } else { + sym::end + }, + e, + ) + })) + .map(|(s, e)| { let expr = self.lower_expr(e); let ident = Ident::new(s, self.lower_span(e.span)); self.expr_field(ident, expr, e.span) - }, - ), + }), ); hir::ExprKind::Struct( diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index ae03121e5f7..75551fe4c19 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2614,6 +2614,18 @@ impl Expr<'_> { StructTailExpr::None, ), ) + | ( + ExprKind::Struct( + QPath::LangItem(LangItem::RangeToInclusiveCopy, _), + [val1], + StructTailExpr::None, + ), + ExprKind::Struct( + QPath::LangItem(LangItem::RangeToInclusiveCopy, _), + [val2], + StructTailExpr::None, + ), + ) | ( ExprKind::Struct( QPath::LangItem(LangItem::RangeFrom, _), @@ -2705,7 +2717,8 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool { | LangItem::RangeToInclusive | LangItem::RangeCopy | LangItem::RangeFromCopy - | LangItem::RangeInclusiveCopy, + | LangItem::RangeInclusiveCopy + | LangItem::RangeToInclusiveCopy, .. ) ), diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 0464665b41f..67d2f15d414 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -422,6 +422,7 @@ language_item_table! { RangeFromCopy, sym::RangeFromCopy, range_from_copy_struct, Target::Struct, GenericRequirement::None; RangeCopy, sym::RangeCopy, range_copy_struct, Target::Struct, GenericRequirement::None; RangeInclusiveCopy, sym::RangeInclusiveCopy, range_inclusive_copy_struct, Target::Struct, GenericRequirement::None; + RangeToInclusiveCopy, sym::RangeToInclusiveCopy, range_to_inclusive_copy_struct, Target::Struct, GenericRequirement::None; String, sym::String, string, Target::Struct, GenericRequirement::None; CStr, sym::CStr, c_str, Target::Struct, GenericRequirement::None; diff --git a/compiler/rustc_index/src/idx.rs b/compiler/rustc_index/src/idx.rs index 33f406e2113..9cd7134659c 100644 --- a/compiler/rustc_index/src/idx.rs +++ b/compiler/rustc_index/src/idx.rs @@ -130,7 +130,22 @@ impl IntoSliceIdx for core::range::RangeFrom { impl IntoSliceIdx for core::range::RangeInclusive { type Output = core::range::RangeInclusive; #[inline] + #[cfg(bootstrap)] fn into_slice_idx(self) -> Self::Output { core::range::RangeInclusive { start: self.start.index(), end: self.end.index() } } + #[inline] + #[cfg(not(bootstrap))] + fn into_slice_idx(self) -> Self::Output { + core::range::RangeInclusive { start: self.start.index(), last: self.last.index() } + } +} + +#[cfg(all(feature = "nightly", not(bootstrap)))] +impl IntoSliceIdx for core::range::RangeToInclusive { + type Output = core::range::RangeToInclusive; + #[inline] + fn into_slice_idx(self) -> Self::Output { + core::range::RangeToInclusive { last: self.last.index() } + } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 77260d07c99..f6bb5be025f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -326,6 +326,7 @@ symbols! { RangeSub, RangeTo, RangeToInclusive, + RangeToInclusiveCopy, Rc, RcWeak, Ready, @@ -1280,6 +1281,7 @@ symbols! { lang, lang_items, large_assignments, + last, lateout, lazy_normalization_consts, lazy_type_alias, diff --git a/library/core/src/range.rs b/library/core/src/range.rs index 7158fa0fcf0..cca7f47d9b9 100644 --- a/library/core/src/range.rs +++ b/library/core/src/range.rs @@ -31,9 +31,7 @@ pub use iter::{IterRange, IterRangeFrom, IterRangeInclusive}; #[doc(inline)] pub use crate::iter::Step; #[doc(inline)] -pub use crate::ops::{ - Bound, IntoBounds, OneSidedRange, RangeBounds, RangeFull, RangeTo, RangeToInclusive, -}; +pub use crate::ops::{Bound, IntoBounds, OneSidedRange, RangeBounds, RangeFull, RangeTo}; /// A (half-open) range bounded inclusively below and exclusively above /// (`start..end` in a future edition). @@ -209,20 +207,20 @@ impl const From> for Range { } } -/// A range bounded inclusively below and above (`start..=end`). +/// A range bounded inclusively below and above (`start..=last`). /// -/// The `RangeInclusive` `start..=end` contains all values with `x >= start` -/// and `x <= end`. It is empty unless `start <= end`. +/// The `RangeInclusive` `start..=last` contains all values with `x >= start` +/// and `x <= last`. It is empty unless `start <= last`. /// /// # Examples /// -/// The `start..=end` syntax is a `RangeInclusive`: +/// The `start..=last` syntax is a `RangeInclusive`: /// /// ``` /// #![feature(new_range_api)] /// use core::range::RangeInclusive; /// -/// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, end: 5 }); +/// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, last: 5 }); /// assert_eq!(3 + 4 + 5, RangeInclusive::from(3..=5).into_iter().sum()); /// ``` #[lang = "RangeInclusiveCopy"] @@ -234,7 +232,7 @@ pub struct RangeInclusive { pub start: Idx, /// The upper bound of the range (inclusive). #[unstable(feature = "new_range_api", issue = "125687")] - pub end: Idx, + pub last: Idx, } #[unstable(feature = "new_range_api", issue = "125687")] @@ -242,7 +240,7 @@ impl fmt::Debug for RangeInclusive { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { self.start.fmt(fmt)?; write!(fmt, "..=")?; - self.end.fmt(fmt)?; + self.last.fmt(fmt)?; Ok(()) } } @@ -306,7 +304,7 @@ impl> RangeInclusive { #[unstable(feature = "new_range_api", issue = "125687")] #[inline] pub fn is_empty(&self) -> bool { - !(self.start <= self.end) + !(self.start <= self.last) } } @@ -335,10 +333,10 @@ impl RangeInclusive { impl RangeInclusive { /// Converts to an exclusive `Range` for `SliceIndex` implementations. - /// The caller is responsible for dealing with `end == usize::MAX`. + /// The caller is responsible for dealing with `last == usize::MAX`. #[inline] pub(crate) const fn into_slice_range(self) -> Range { - Range { start: self.start, end: self.end + 1 } + Range { start: self.start, end: self.last + 1 } } } @@ -348,7 +346,7 @@ impl RangeBounds for RangeInclusive { Included(&self.start) } fn end_bound(&self) -> Bound<&T> { - Included(&self.end) + Included(&self.last) } } @@ -364,7 +362,7 @@ impl RangeBounds for RangeInclusive<&T> { Included(self.start) } fn end_bound(&self) -> Bound<&T> { - Included(self.end) + Included(self.last) } } @@ -372,7 +370,7 @@ impl RangeBounds for RangeInclusive<&T> { #[unstable(feature = "new_range_api", issue = "125687")] impl IntoBounds for RangeInclusive { fn into_bounds(self) -> (Bound, Bound) { - (Included(self.start), Included(self.end)) + (Included(self.start), Included(self.last)) } } @@ -381,7 +379,7 @@ impl IntoBounds for RangeInclusive { impl const From> for legacy::RangeInclusive { #[inline] fn from(value: RangeInclusive) -> Self { - Self::new(value.start, value.end) + Self::new(value.start, value.last) } } #[unstable(feature = "new_range_api", issue = "125687")] @@ -393,8 +391,8 @@ impl From> for RangeInclusive { "attempted to convert from an exhausted `legacy::RangeInclusive` (unspecified behavior)" ); - let (start, end) = value.into_inner(); - RangeInclusive { start, end } + let (start, last) = value.into_inner(); + RangeInclusive { start, last } } } @@ -543,3 +541,107 @@ impl const From> for RangeFrom { Self { start: value.start } } } + +/// A range only bounded inclusively above (`..=last`). +/// +/// The `RangeToInclusive` `..=last` contains all values with `x <= last`. +/// It cannot serve as an [`Iterator`] because it doesn't have a starting point. +/// +/// # Examples +/// +/// The `..=last` syntax is a `RangeToInclusive`: +/// +/// ``` +/// #![feature(new_range_api)] +/// #![feature(new_range)] +/// assert_eq!((..=5), std::range::RangeToInclusive{ last: 5 }); +/// ``` +/// +/// It does not have an [`IntoIterator`] implementation, so you can't use it in a +/// `for` loop directly. This won't compile: +/// +/// ```compile_fail,E0277 +/// // error[E0277]: the trait bound `std::range::RangeToInclusive<{integer}>: +/// // std::iter::Iterator` is not satisfied +/// for i in ..=5 { +/// // ... +/// } +/// ``` +/// +/// When used as a [slicing index], `RangeToInclusive` produces a slice of all +/// array elements up to and including the index indicated by `last`. +/// +/// ``` +/// let arr = [0, 1, 2, 3, 4]; +/// assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]); +/// assert_eq!(arr[ .. 3], [0, 1, 2 ]); +/// assert_eq!(arr[ ..=3], [0, 1, 2, 3 ]); // This is a `RangeToInclusive` +/// assert_eq!(arr[1.. ], [ 1, 2, 3, 4]); +/// assert_eq!(arr[1.. 3], [ 1, 2 ]); +/// assert_eq!(arr[1..=3], [ 1, 2, 3 ]); +/// ``` +/// +/// [slicing index]: crate::slice::SliceIndex +#[lang = "RangeToInclusiveCopy"] +#[doc(alias = "..=")] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[unstable(feature = "new_range_api", issue = "125687")] +pub struct RangeToInclusive { + /// The upper bound of the range (inclusive) + #[unstable(feature = "new_range_api", issue = "125687")] + pub last: Idx, +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl fmt::Debug for RangeToInclusive { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(fmt, "..=")?; + self.last.fmt(fmt)?; + Ok(()) + } +} + +impl> RangeToInclusive { + /// Returns `true` if `item` is contained in the range. + /// + /// # Examples + /// + /// ``` + /// assert!( (..=5).contains(&-1_000_000_000)); + /// assert!( (..=5).contains(&5)); + /// assert!(!(..=5).contains(&6)); + /// + /// assert!( (..=1.0).contains(&1.0)); + /// assert!(!(..=1.0).contains(&f32::NAN)); + /// assert!(!(..=f32::NAN).contains(&0.5)); + /// ``` + #[inline] + #[unstable(feature = "new_range_api", issue = "125687")] + pub fn contains(&self, item: &U) -> bool + where + Idx: PartialOrd, + U: ?Sized + PartialOrd, + { + >::contains(self, item) + } +} + +// RangeToInclusive cannot impl From> +// because underflow would be possible with (..0).into() + +#[unstable(feature = "new_range_api", issue = "125687")] +impl RangeBounds for RangeToInclusive { + fn start_bound(&self) -> Bound<&T> { + Unbounded + } + fn end_bound(&self) -> Bound<&T> { + Included(&self.last) + } +} + +#[unstable(feature = "range_into_bounds", issue = "136903")] +impl IntoBounds for RangeToInclusive { + fn into_bounds(self) -> (Bound, Bound) { + (Unbounded, Included(self.last)) + } +} diff --git a/library/core/src/range/iter.rs b/library/core/src/range/iter.rs index 1e261d8c1d9..24efd4a204a 100644 --- a/library/core/src/range/iter.rs +++ b/library/core/src/range/iter.rs @@ -164,7 +164,7 @@ impl IterRangeInclusive { return None; } - Some(RangeInclusive { start: self.0.start, end: self.0.end }) + Some(RangeInclusive { start: self.0.start, last: self.0.end }) } } diff --git a/library/core/src/range/legacy.rs b/library/core/src/range/legacy.rs index 6723c4903f7..aa11331382d 100644 --- a/library/core/src/range/legacy.rs +++ b/library/core/src/range/legacy.rs @@ -1,10 +1,10 @@ //! # Legacy range types //! //! The types within this module will be replaced by the types -//! [`Range`], [`RangeInclusive`], and [`RangeFrom`] in the parent +//! [`Range`], [`RangeInclusive`], [`RangeToInclusive`], and [`RangeFrom`] in the parent //! module, [`core::range`]. //! //! The types here are equivalent to those in [`core::ops`]. #[doc(inline)] -pub use crate::ops::{Range, RangeFrom, RangeInclusive}; +pub use crate::ops::{Range, RangeFrom, RangeInclusive, RangeToInclusive}; diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 98091e9fe83..82a1c66ffec 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -129,6 +129,8 @@ mod private_slice_index { #[unstable(feature = "new_range_api", issue = "125687")] impl Sealed for range::RangeInclusive {} #[unstable(feature = "new_range_api", issue = "125687")] + impl Sealed for range::RangeToInclusive {} + #[unstable(feature = "new_range_api", issue = "125687")] impl Sealed for range::RangeFrom {} impl Sealed for ops::IndexRange {} @@ -788,6 +790,45 @@ unsafe impl const SliceIndex<[T]> for ops::RangeToInclusive { } } +/// The methods `index` and `index_mut` panic if the end of the range is out of bounds. +#[stable(feature = "inclusive_range", since = "1.26.0")] +#[rustc_const_unstable(feature = "const_index", issue = "143775")] +unsafe impl const SliceIndex<[T]> for range::RangeToInclusive { + type Output = [T]; + + #[inline] + fn get(self, slice: &[T]) -> Option<&[T]> { + (0..=self.last).get(slice) + } + + #[inline] + fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { + (0..=self.last).get_mut(slice) + } + + #[inline] + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. + unsafe { (0..=self.last).get_unchecked(slice) } + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. + unsafe { (0..=self.last).get_unchecked_mut(slice) } + } + + #[inline] + fn index(self, slice: &[T]) -> &[T] { + (0..=self.last).index(slice) + } + + #[inline] + fn index_mut(self, slice: &mut [T]) -> &mut [T] { + (0..=self.last).index_mut(slice) + } +} + /// Performs bounds checking of a range. /// /// This method is similar to [`Index::index`] for slices, but it returns a diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index dc88f35eca7..6a0cdc85dea 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -677,11 +677,11 @@ unsafe impl const SliceIndex for range::RangeInclusive { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { - if self.end == usize::MAX { None } else { self.into_slice_range().get(slice) } + if self.last == usize::MAX { None } else { self.into_slice_range().get(slice) } } #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { - if self.end == usize::MAX { None } else { self.into_slice_range().get_mut(slice) } + if self.last == usize::MAX { None } else { self.into_slice_range().get_mut(slice) } } #[inline] unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { @@ -695,14 +695,14 @@ unsafe impl const SliceIndex for range::RangeInclusive { } #[inline] fn index(self, slice: &str) -> &Self::Output { - if self.end == usize::MAX { + if self.last == usize::MAX { str_index_overflow_fail(); } self.into_slice_range().index(slice) } #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { - if self.end == usize::MAX { + if self.last == usize::MAX { str_index_overflow_fail(); } self.into_slice_range().index_mut(slice) diff --git a/src/tools/clippy/clippy_utils/src/sym.rs b/src/tools/clippy/clippy_utils/src/sym.rs index 278101ac27f..8033b74a8d2 100644 --- a/src/tools/clippy/clippy_utils/src/sym.rs +++ b/src/tools/clippy/clippy_utils/src/sym.rs @@ -194,7 +194,6 @@ generate! { itertools, join, kw, - last, lazy_static, lint_vec, ln, diff --git a/tests/ui/const-generics/std/const-generics-range.full.stderr b/tests/ui/const-generics/std/const-generics-range.full.stderr index 2b5c63e6643..ccede2af9e5 100644 --- a/tests/ui/const-generics/std/const-generics-range.full.stderr +++ b/tests/ui/const-generics/std/const-generics-range.full.stderr @@ -28,7 +28,7 @@ error[E0741]: `RangeTo` must implement `ConstParamTy` to be used as the t LL | struct _RangeTo>; | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0741]: `RangeToInclusive` must implement `ConstParamTy` to be used as the type of a const generic parameter +error[E0741]: `std::ops::RangeToInclusive` must implement `ConstParamTy` to be used as the type of a const generic parameter --> $DIR/const-generics-range.rs:34:35 | LL | struct _RangeToInclusive>; diff --git a/tests/ui/const-generics/std/const-generics-range.min.stderr b/tests/ui/const-generics/std/const-generics-range.min.stderr index 04e3fe74453..43a57c880d5 100644 --- a/tests/ui/const-generics/std/const-generics-range.min.stderr +++ b/tests/ui/const-generics/std/const-generics-range.min.stderr @@ -58,7 +58,7 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more LL + #![feature(adt_const_params)] | -error: `RangeToInclusive` is forbidden as the type of a const generic parameter +error: `std::ops::RangeToInclusive` is forbidden as the type of a const generic parameter --> $DIR/const-generics-range.rs:34:35 | LL | struct _RangeToInclusive>; diff --git a/tests/ui/const-generics/std/const-generics-range.rs b/tests/ui/const-generics/std/const-generics-range.rs index 3a238ed177e..391366dadba 100644 --- a/tests/ui/const-generics/std/const-generics-range.rs +++ b/tests/ui/const-generics/std/const-generics-range.rs @@ -7,32 +7,32 @@ // `Range` should be usable within const generics: struct _Range>; //[min]~^ ERROR `std::ops::Range` is forbidden -const RANGE : _Range<{ 0 .. 1000 }> = _Range; +const RANGE: _Range<{ 0..1000 }> = _Range; // `RangeFrom` should be usable within const generics: struct _RangeFrom>; //[min]~^ ERROR `std::ops::RangeFrom` is forbidden -const RANGE_FROM : _RangeFrom<{ 0 .. }> = _RangeFrom; +const RANGE_FROM: _RangeFrom<{ 0.. }> = _RangeFrom; // `RangeFull` should be usable within const generics: struct _RangeFull; //[min]~^ ERROR `RangeFull` is forbidden -const RANGE_FULL : _RangeFull<{ .. }> = _RangeFull; +const RANGE_FULL: _RangeFull<{ .. }> = _RangeFull; // Regression test for #70155 // `RangeInclusive` should be usable within const generics: struct _RangeInclusive>; //[min]~^ ERROR `std::ops::RangeInclusive` is forbidden -const RANGE_INCLUSIVE : _RangeInclusive<{ 0 ..= 999 }> = _RangeInclusive; +const RANGE_INCLUSIVE: _RangeInclusive<{ 0..=999 }> = _RangeInclusive; // `RangeTo` should be usable within const generics: struct _RangeTo>; //[min]~^ ERROR `RangeTo` is forbidden -const RANGE_TO : _RangeTo<{ .. 1000 }> = _RangeTo; +const RANGE_TO: _RangeTo<{ ..1000 }> = _RangeTo; // `RangeToInclusive` should be usable within const generics: struct _RangeToInclusive>; -//[min]~^ ERROR `RangeToInclusive` is forbidden -const RANGE_TO_INCLUSIVE : _RangeToInclusive<{ ..= 999 }> = _RangeToInclusive; +//[min]~^ ERROR `std::ops::RangeToInclusive` is forbidden +const RANGE_TO_INCLUSIVE: _RangeToInclusive<{ ..=999 }> = _RangeToInclusive; pub fn main() {} diff --git a/tests/ui/iterators/ranges.stderr b/tests/ui/iterators/ranges.stderr index b9fbcd5304b..f85ce644073 100644 --- a/tests/ui/iterators/ranges.stderr +++ b/tests/ui/iterators/ranges.stderr @@ -8,15 +8,15 @@ LL | for _ in ..10 {} = note: `..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a bounded `Range`: `0..end` = note: required for `RangeTo<{integer}>` to implement `IntoIterator` -error[E0277]: `RangeToInclusive<{integer}>` is not an iterator +error[E0277]: `std::ops::RangeToInclusive<{integer}>` is not an iterator --> $DIR/ranges.rs:4:14 | LL | for _ in ..=10 {} | ^^^^^ if you meant to iterate until a value (including it), add a starting value | - = help: the trait `Iterator` is not implemented for `RangeToInclusive<{integer}>` + = help: the trait `Iterator` is not implemented for `std::ops::RangeToInclusive<{integer}>` = note: `..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant to have a bounded `RangeInclusive`: `0..=end` - = note: required for `RangeToInclusive<{integer}>` to implement `IntoIterator` + = note: required for `std::ops::RangeToInclusive<{integer}>` to implement `IntoIterator` error: aborting due to 2 previous errors diff --git a/tests/ui/new-range/disabled.rs b/tests/ui/new-range/disabled.rs index 1a5fe3f9743..6ba29f5ca9a 100644 --- a/tests/ui/new-range/disabled.rs +++ b/tests/ui/new-range/disabled.rs @@ -6,20 +6,20 @@ fn main() { // Unchanged let a: core::range::RangeFull = ..; let b: core::range::RangeTo = ..2; - let c: core::range::RangeToInclusive = ..=3; let _: core::ops::RangeFull = a; let _: core::ops::RangeTo = b; - let _: core::ops::RangeToInclusive = c; // Changed let a: core::range::legacy::RangeFrom = 1..; let b: core::range::legacy::Range = 2..3; let c: core::range::legacy::RangeInclusive = 4..=5; + let d: core::range::legacy::RangeToInclusive = ..=3; let a: core::ops::RangeFrom = a; let b: core::ops::Range = b; let c: core::ops::RangeInclusive = c; + let d: core::ops::RangeToInclusive = d; let _: core::ops::RangeFrom = a.into_iter(); let _: core::ops::Range = b.into_iter(); diff --git a/tests/ui/new-range/enabled.rs b/tests/ui/new-range/enabled.rs index a5fb76ad52b..5ddbba492e7 100644 --- a/tests/ui/new-range/enabled.rs +++ b/tests/ui/new-range/enabled.rs @@ -7,18 +7,18 @@ fn main() { // Unchanged let a: core::range::RangeFull = ..; let b: core::range::RangeTo = ..2; - let c: core::range::RangeToInclusive = ..=3; let _: core::ops::RangeFull = a; let _: core::ops::RangeTo = b; - let _: core::ops::RangeToInclusive = c; // Changed let a: core::range::RangeFrom = 1..; let b: core::range::Range = 2..3; let c: core::range::RangeInclusive = 4..=5; + let d: core::range::RangeToInclusive = ..=3; let _: core::range::IterRangeFrom = a.into_iter(); let _: core::range::IterRange = b.into_iter(); let _: core::range::IterRangeInclusive = c.into_iter(); + // RangeToInclusive has no Iterator implementation } diff --git a/tests/ui/range/issue-54505-no-literals.stderr b/tests/ui/range/issue-54505-no-literals.stderr index c6d4384bcd3..62e2fe4a838 100644 --- a/tests/ui/range/issue-54505-no-literals.stderr +++ b/tests/ui/range/issue-54505-no-literals.stderr @@ -207,7 +207,7 @@ LL | take_range(std::ops::RangeToInclusive { end: 5 }); | arguments to this function are incorrect | = note: expected reference `&_` - found struct `RangeToInclusive<{integer}>` + found struct `std::ops::RangeToInclusive<{integer}>` note: function defined here --> $DIR/issue-54505-no-literals.rs:12:4 | @@ -227,7 +227,7 @@ LL | take_range(::std::ops::RangeToInclusive { end: 5 }); | arguments to this function are incorrect | = note: expected reference `&_` - found struct `RangeToInclusive<{integer}>` + found struct `std::ops::RangeToInclusive<{integer}>` note: function defined here --> $DIR/issue-54505-no-literals.rs:12:4 | diff --git a/tests/ui/range/issue-54505-no-std.stderr b/tests/ui/range/issue-54505-no-std.stderr index 2aa1d584046..866a82afb7e 100644 --- a/tests/ui/range/issue-54505-no-std.stderr +++ b/tests/ui/range/issue-54505-no-std.stderr @@ -112,7 +112,7 @@ LL | take_range(..=42); | arguments to this function are incorrect | = note: expected reference `&_` - found struct `RangeToInclusive<{integer}>` + found struct `core::ops::RangeToInclusive<{integer}>` note: function defined here --> $DIR/issue-54505-no-std.rs:25:4 | diff --git a/tests/ui/range/issue-54505.stderr b/tests/ui/range/issue-54505.stderr index 8b669b2910f..4d94c6c2d09 100644 --- a/tests/ui/range/issue-54505.stderr +++ b/tests/ui/range/issue-54505.stderr @@ -112,7 +112,7 @@ LL | take_range(..=42); | arguments to this function are incorrect | = note: expected reference `&_` - found struct `RangeToInclusive<{integer}>` + found struct `std::ops::RangeToInclusive<{integer}>` note: function defined here --> $DIR/issue-54505.rs:10:4 | -- cgit 1.4.1-3-g733a5 From e3dfcb26cd816046451a4dc85a85c5294245ded7 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Tue, 9 Sep 2025 09:33:49 +0200 Subject: CI: rfl: move job forward to Linux v6.17-rc5 to remove temporary commits v6.17-rc5 contains the equivalent of the two commits we had here, thus move the Rust for Linux job forward to that so that we don't need the temporary commits anymore. Signed-off-by: Miguel Ojeda --- src/ci/docker/scripts/rfl-build.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh index 7e0fb5794f4..b7d7151b171 100755 --- a/src/ci/docker/scripts/rfl-build.sh +++ b/src/ci/docker/scripts/rfl-build.sh @@ -2,9 +2,7 @@ set -euo pipefail -# https://github.com/rust-lang/rust/pull/144443 -# https://github.com/rust-lang/rust/pull/145928 -LINUX_VERSION=8851e27d2cb947ea8bbbe8e812068f7bf5cbd00b +LINUX_VERSION=v6.17-rc5 # Build rustc, rustdoc, cargo, clippy-driver and rustfmt ../x.py build --stage 2 library rustdoc clippy rustfmt -- cgit 1.4.1-3-g733a5 From e379c7758667f900aaf5551c4553c7d4c121e3e1 Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 21 Aug 2025 16:50:54 +0100 Subject: erase_regions to erase_and_anonymize_regions --- compiler/rustc_borrowck/src/region_infer/mod.rs | 2 +- .../src/region_infer/opaque_types/mod.rs | 2 +- compiler/rustc_borrowck/src/type_check/mod.rs | 8 +++-- compiler/rustc_codegen_gcc/src/type_of.rs | 2 +- .../rustc_codegen_llvm/src/debuginfo/metadata.rs | 4 +-- compiler/rustc_codegen_llvm/src/type_of.rs | 2 +- compiler/rustc_const_eval/src/interpret/traits.rs | 7 ++-- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 2 +- .../rustc_hir_analysis/src/coherence/orphan.rs | 2 +- .../src/hir_ty_lowering/errors.rs | 2 +- compiler/rustc_hir_typeck/src/cast.rs | 4 +-- .../rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 2 +- compiler/rustc_hir_typeck/src/inline_asm.rs | 2 +- compiler/rustc_hir_typeck/src/writeback.rs | 4 +-- .../src/infer/outlives/test_type_match.rs | 2 +- compiler/rustc_infer/src/infer/outlives/verify.rs | 4 +-- .../rustc_lint/src/deref_into_dyn_supertrait.rs | 2 +- .../rustc_lint/src/for_loops_over_fallibles.rs | 2 +- compiler/rustc_lint/src/types.rs | 2 +- compiler/rustc_middle/src/mir/interpret/queries.rs | 12 ++++--- compiler/rustc_middle/src/query/mod.rs | 4 +-- compiler/rustc_middle/src/ty/abstract_const.rs | 2 +- compiler/rustc_middle/src/ty/erase_regions.rs | 28 ++++++++-------- compiler/rustc_middle/src/ty/instance.rs | 4 ++- compiler/rustc_middle/src/ty/layout.rs | 5 ++- .../src/ty/normalize_erasing_regions.rs | 4 +-- compiler/rustc_middle/src/ty/print/pretty.rs | 4 +-- compiler/rustc_middle/src/ty/util.rs | 10 +++--- compiler/rustc_middle/src/ty/vtable.rs | 2 +- compiler/rustc_mir_build/src/check_tail_calls.rs | 4 +-- compiler/rustc_mir_build/src/thir/cx/expr.rs | 13 ++++---- .../src/thir/pattern/const_to_pat.rs | 8 +++-- compiler/rustc_mir_dataflow/src/value_analysis.rs | 2 +- .../src/add_subtyping_projections.rs | 4 +-- compiler/rustc_mir_transform/src/promote_consts.rs | 3 +- compiler/rustc_monomorphize/src/collector.rs | 2 +- compiler/rustc_symbol_mangling/src/legacy.rs | 7 ++-- compiler/rustc_symbol_mangling/src/test.rs | 2 +- compiler/rustc_symbol_mangling/src/v0.rs | 5 ++- .../src/error_reporting/infer/mod.rs | 4 +-- .../src/error_reporting/infer/note_and_explain.rs | 6 +++- .../error_reporting/traits/fulfillment_errors.rs | 7 ++-- .../src/error_reporting/traits/suggestions.rs | 6 ++-- .../rustc_trait_selection/src/solve/delegate.rs | 2 +- .../src/traits/dyn_compatibility.rs | 2 +- compiler/rustc_trait_selection/src/traits/mod.rs | 8 ++--- .../src/traits/query/dropck_outlives.rs | 2 +- compiler/rustc_traits/src/codegen.rs | 2 +- .../rustc_traits/src/normalize_erasing_regions.rs | 2 +- compiler/rustc_transmute/src/layout/mod.rs | 2 +- compiler/rustc_transmute/src/layout/tree.rs | 39 +++++++++++----------- compiler/rustc_ty_utils/src/instance.rs | 8 ++--- compiler/rustc_type_ir/src/visit.rs | 2 +- src/tools/clippy/clippy_lints/src/dereference.rs | 2 +- .../clippy_lints/src/loops/explicit_iter_loop.rs | 2 +- .../clippy_lints/src/only_used_in_recursion.rs | 2 +- .../src/transmute/transmute_ref_to_ref.rs | 2 +- .../src/transmute/transmute_undefined_repr.rs | 4 +-- .../clippy/clippy_lints/src/useless_conversion.rs | 2 +- src/tools/clippy/clippy_utils/src/ty/mod.rs | 2 +- 60 files changed, 158 insertions(+), 132 deletions(-) (limited to 'src') diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 9990f4cb3f2..f57456949bb 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -615,7 +615,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } // Type-test failed. Report the error. - let erased_generic_kind = infcx.tcx.erase_regions(type_test.generic_kind); + let erased_generic_kind = infcx.tcx.erase_and_anonymize_regions(type_test.generic_kind); // Skip duplicate-ish errors. if deduplicate_errors.insert(( diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs index 95c5366a6c8..0af636aa734 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs @@ -341,7 +341,7 @@ fn compute_concrete_types_from_defining_uses<'tcx>( // // FIXME(-Znext-solver): This isn't necessary after all. We can remove this check again. if let Some((prev_decl_key, prev_span)) = decls_modulo_regions.insert( - rcx.infcx.tcx.erase_regions(opaque_type_key), + rcx.infcx.tcx.erase_and_anonymize_regions(opaque_type_key), (opaque_type_key, hidden_type.span), ) && let Some((arg1, arg2)) = std::iter::zip( prev_decl_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg), diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 02be78f90b0..8c5447fe1e9 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1892,7 +1892,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if is_diverging { // The signature in this call can reference region variables, // so erase them before calling a query. - let output_ty = self.tcx().erase_regions(sig.output()); + let output_ty = self.tcx().erase_and_anonymize_regions(sig.output()); if !output_ty .is_privately_uninhabited(self.tcx(), self.infcx.typing_env(self.infcx.param_env)) { @@ -1986,7 +1986,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let op_arg_ty = self.normalize(op_arg_ty, term_location); let category = if call_source.from_hir_call() { - ConstraintCategory::CallArgument(Some(self.infcx.tcx.erase_regions(func_ty))) + ConstraintCategory::CallArgument(Some( + self.infcx.tcx.erase_and_anonymize_regions(func_ty), + )) } else { ConstraintCategory::Boring }; @@ -2120,7 +2122,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // Erase the regions from `ty` to get a global type. The // `Sized` bound in no way depends on precise regions, so this // shouldn't affect `is_sized`. - let erased_ty = tcx.erase_regions(ty); + let erased_ty = tcx.erase_and_anonymize_regions(ty); // FIXME(#132279): Using `Ty::is_sized` causes us to incorrectly handle opaques here. if !erased_ty.is_sized(tcx, self.infcx.typing_env(self.infcx.param_env)) { // in current MIR construction, all non-control-flow rvalue diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index 093f902bc3d..93202483eed 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -240,7 +240,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { // Make sure lifetimes are erased, to avoid generating distinct LLVM // types for Rust types that only differ in the choice of lifetimes. - let normal_ty = cx.tcx.erase_regions(self.ty); + let normal_ty = cx.tcx.erase_and_anonymize_regions(self.ty); let mut defer = None; let ty = if self.ty != normal_ty { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index caa3369f413..0d71de21fef 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1435,7 +1435,7 @@ fn build_vtable_type_di_node<'ll, 'tcx>( let vtable_entries = if let Some(poly_trait_ref) = poly_trait_ref { let trait_ref = poly_trait_ref.with_self_ty(tcx, ty); - let trait_ref = tcx.erase_regions(trait_ref); + let trait_ref = tcx.erase_and_anonymize_regions(trait_ref); tcx.vtable_entries(trait_ref) } else { @@ -1562,7 +1562,7 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>( // Unwrap potential addrspacecast let vtable = find_vtable_behind_cast(vtable); let trait_ref_self = trait_ref.with_self_ty(cx.tcx, ty); - let trait_ref_self = cx.tcx.erase_regions(trait_ref_self); + let trait_ref_self = cx.tcx.erase_and_anonymize_regions(trait_ref_self); let trait_def_id = trait_ref_self.def_id; let trait_vis = cx.tcx.visibility(trait_def_id); diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index 4e7096da502..d28ffc4c96e 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -226,7 +226,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { // Make sure lifetimes are erased, to avoid generating distinct LLVM // types for Rust types that only differ in the choice of lifetimes. - let normal_ty = cx.tcx.erase_regions(self.ty); + let normal_ty = cx.tcx.erase_and_anonymize_regions(self.ty); let mut defer = None; let llty = if self.ty != normal_ty { diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs index e4b5c82853a..870f9a396ae 100644 --- a/compiler/rustc_const_eval/src/interpret/traits.rs +++ b/compiler/rustc_const_eval/src/interpret/traits.rs @@ -23,7 +23,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ) -> InterpResult<'tcx, Pointer>> { trace!("get_vtable(ty={ty:?}, dyn_ty={dyn_ty:?})"); - let (ty, dyn_ty) = self.tcx.erase_regions((ty, dyn_ty)); + let (ty, dyn_ty) = self.tcx.erase_and_anonymize_regions((ty, dyn_ty)); // All vtables must be monomorphic, bail out otherwise. ensure_monomorphic_enough(*self.tcx, ty)?; @@ -53,8 +53,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ) -> &'tcx [VtblEntry<'tcx>] { if let Some(trait_) = trait_ { let trait_ref = trait_.with_self_ty(*self.tcx, dyn_ty); - let trait_ref = - self.tcx.erase_regions(self.tcx.instantiate_bound_regions_with_erased(trait_ref)); + let trait_ref = self.tcx.erase_and_anonymize_regions( + self.tcx.instantiate_bound_regions_with_erased(trait_ref), + ); self.tcx.vtable_entries(trait_ref) } else { TyCtxt::COMMON_VTABLE_ENTRIES diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index e6a1f6d8d8b..22a9446fd4c 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1047,7 +1047,7 @@ fn check_type_defn<'tcx>( let needs_drop_copy = || { packed && { let ty = tcx.type_of(variant.tail().did).instantiate_identity(); - let ty = tcx.erase_regions(ty); + let ty = tcx.erase_and_anonymize_regions(ty); assert!(!ty.has_infer()); ty.needs_drop(tcx, wfcx.infcx.typing_env(wfcx.param_env)) } diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index f707196c816..621431ae234 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -404,7 +404,7 @@ fn emit_orphan_check_error<'tcx>( of_trait.trait_ref.path.span }; - ty = tcx.erase_regions(ty); + ty = tcx.erase_and_anonymize_regions(ty); let is_foreign = !trait_ref.def_id.is_local() && matches!(is_target_ty, IsFirstInputType::No); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 93b82acf621..0cf9cb7193f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -482,7 +482,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .map(|header| header.trait_ref.instantiate_identity().self_ty()) // We don't care about blanket impls. .filter(|self_ty| !self_ty.has_non_region_param()) - .map(|self_ty| tcx.erase_regions(self_ty).to_string()) + .map(|self_ty| tcx.erase_and_anonymize_regions(self_ty).to_string()) .collect() }; // FIXME: also look at `tcx.generics_of(self.item_def_id()).params` any that diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 3eeb0eac023..27540fd1a43 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -851,8 +851,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { debug!("check_ptr_ptr_cast m_src={m_src:?} m_dst={m_dst:?}"); // ptr-ptr cast. metadata must match. - let src_kind = fcx.tcx.erase_regions(fcx.pointer_kind(m_src.ty, self.span)?); - let dst_kind = fcx.tcx.erase_regions(fcx.pointer_kind(m_dst.ty, self.span)?); + let src_kind = fcx.tcx.erase_and_anonymize_regions(fcx.pointer_kind(m_src.ty, self.span)?); + let dst_kind = fcx.tcx.erase_and_anonymize_regions(fcx.pointer_kind(m_dst.ty, self.span)?); // We can't cast if target pointer kind is unknown let Some(dst_kind) = dst_kind else { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 84ea2ec0f8a..d7ddbcc8b53 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1358,7 +1358,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .infcx .type_implements_trait( clone_trait_def, - [self.tcx.erase_regions(expected_ty)], + [self.tcx.erase_and_anonymize_regions(expected_ty)], self.param_env, ) .must_apply_modulo_regions() diff --git a/compiler/rustc_hir_typeck/src/inline_asm.rs b/compiler/rustc_hir_typeck/src/inline_asm.rs index b59c1752c25..c0cd23be690 100644 --- a/compiler/rustc_hir_typeck/src/inline_asm.rs +++ b/compiler/rustc_hir_typeck/src/inline_asm.rs @@ -44,7 +44,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if ty.has_non_region_infer() { Ty::new_misc_error(self.tcx()) } else { - self.tcx().erase_regions(ty) + self.tcx().erase_and_anonymize_regions(ty) } } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index d75bc9edab2..8e0180426ef 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -802,7 +802,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { format!("unexpected inference variable after writeback: {predicate:?}"), ); } else { - let predicate = self.tcx().erase_regions(predicate); + let predicate = self.tcx().erase_and_anonymize_regions(predicate); if cause.has_infer() || cause.has_placeholders() { // We can't use the the obligation cause as it references // information local to this query. @@ -984,7 +984,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { // borrowck, and specifically region constraints will be populated during // MIR typeck which is run on the new body. // - // We're not using `tcx.erase_regions` as that also anonymizes bound variables, + // We're not using `tcx.erase_and_anonymize_regions` as that also anonymizes bound variables, // regressing borrowck diagnostics. value = fold_regions(tcx, value, |_, _| tcx.lifetimes.re_erased); diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs index bfdd282d7e1..f06eb58a371 100644 --- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs +++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs @@ -76,7 +76,7 @@ pub(super) fn can_match_erased_ty<'tcx>( erased_ty: Ty<'tcx>, ) -> bool { assert!(!outlives_predicate.has_escaping_bound_vars()); - let erased_outlives_predicate = tcx.erase_regions(outlives_predicate); + let erased_outlives_predicate = tcx.erase_and_anonymize_regions(outlives_predicate); let outlives_ty = erased_outlives_predicate.skip_binder().0; if outlives_ty == erased_ty { // pointless micro-optimization diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index 69feecfe30a..f67b99cb3f8 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -96,7 +96,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { &self, alias_ty: ty::AliasTy<'tcx>, ) -> Vec> { - let erased_alias_ty = self.tcx.erase_regions(alias_ty.to_ty(self.tcx)); + let erased_alias_ty = self.tcx.erase_and_anonymize_regions(alias_ty.to_ty(self.tcx)); self.declared_generic_bounds_from_env_for_erased_ty(erased_alias_ty) } @@ -241,7 +241,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { } let p_ty = p.to_ty(tcx); - let erased_p_ty = self.tcx.erase_regions(p_ty); + let erased_p_ty = self.tcx.erase_and_anonymize_regions(p_ty); (erased_p_ty == erased_ty).then_some(ty::Binder::dummy(ty::OutlivesPredicate(p_ty, r))) })); diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs index 943fcc0801b..e1c51ff8299 100644 --- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs +++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs @@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait { { // erase regions in self type for better diagnostic presentation let (self_ty, target_principal, supertrait_principal) = - tcx.erase_regions((self_ty, target_principal, supertrait_principal)); + tcx.erase_and_anonymize_regions((self_ty, target_principal, supertrait_principal)); let label2 = tcx .associated_items(item.owner_id) .find_by_ident_and_kind( diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs index a56b753bda7..9e1fc598171 100644 --- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs +++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs @@ -176,7 +176,7 @@ fn suggest_question_mark<'tcx>( cause, param_env, // Erase any region vids from the type, which may not be resolved - infcx.tcx.erase_regions(ty), + infcx.tcx.erase_and_anonymize_regions(ty), into_iterator_did, ); diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index a72b802eb5d..88527fa2e6e 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -935,7 +935,7 @@ impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { if let hir::ItemKind::Enum(_, _, ref enum_definition) = it.kind { let t = cx.tcx.type_of(it.owner_id).instantiate_identity(); - let ty = cx.tcx.erase_regions(t); + let ty = cx.tcx.erase_and_anonymize_regions(t); let Ok(layout) = cx.layout_of(ty) else { return }; let Variants::Multiple { tag_encoding: TagEncoding::Direct, tag, variants, .. } = &layout.variants diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index e25f35c59c2..ecf35d9dd6d 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -41,7 +41,7 @@ impl<'tcx> TyCtxt<'tcx> { let instance = ty::Instance::new_raw(def_id, args); let cid = GlobalId { instance, promoted: None }; let typing_env = ty::TypingEnv::post_analysis(self, def_id); - let inputs = self.erase_regions(typing_env.as_query_input(cid)); + let inputs = self.erase_and_anonymize_regions(typing_env.as_query_input(cid)); self.eval_to_allocation_raw(inputs) } @@ -172,8 +172,9 @@ impl<'tcx> TyCtxt<'tcx> { ) -> EvalToConstValueResult<'tcx> { // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. - let inputs = - self.erase_regions(typing_env.with_post_analysis_normalized(self).as_query_input(cid)); + let inputs = self.erase_and_anonymize_regions( + typing_env.with_post_analysis_normalized(self).as_query_input(cid), + ); if !span.is_dummy() { // The query doesn't know where it is being invoked, so we need to fix the span. self.at(span).eval_to_const_value_raw(inputs).map_err(|e| e.with_span(span)) @@ -192,8 +193,9 @@ impl<'tcx> TyCtxt<'tcx> { ) -> ConstToValTreeResult<'tcx> { // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. - let inputs = - self.erase_regions(typing_env.with_post_analysis_normalized(self).as_query_input(cid)); + let inputs = self.erase_and_anonymize_regions( + typing_env.with_post_analysis_normalized(self).as_query_input(cid), + ); debug!(?inputs); let res = if !span.is_dummy() { // The query doesn't know where it is being invoked, so we need to fix the span. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 8fba218cc71..2aa32dfa0d8 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -761,9 +761,9 @@ rustc_queries! { } /// Erases regions from `ty` to yield a new type. - /// Normally you would just use `tcx.erase_regions(value)`, + /// Normally you would just use `tcx.erase_and_anonymize_regions(value)`, /// however, which uses this query as a kind of cache. - query erase_regions_ty(ty: Ty<'tcx>) -> Ty<'tcx> { + query erase_and_anonymize_regions_ty(ty: Ty<'tcx>) -> Ty<'tcx> { // This query is not expected to have input -- as a result, it // is not a good candidates for "replay" because it is essentially a // pure function of its input (and hence the expectation is that diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index c9b9ec771b3..463e4c58805 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -55,7 +55,7 @@ impl<'tcx> TyCtxt<'tcx> { ty::ConstKind::Unevaluated(uv) => match self.tcx.thir_abstract_const(uv.def) { Err(e) => ty::Const::new_error(self.tcx, e), Ok(Some(bac)) => { - let args = self.tcx.erase_regions(uv.args); + let args = self.tcx.erase_and_anonymize_regions(uv.args); let bac = bac.instantiate(self.tcx, args); return bac.fold_with(self); } diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index f4fead7e952..74b4adda7fd 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -6,20 +6,20 @@ use crate::ty::{ }; pub(super) fn provide(providers: &mut Providers) { - *providers = Providers { erase_regions_ty, ..*providers }; + *providers = Providers { erase_and_anonymize_regions_ty, ..*providers }; } -fn erase_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { +fn erase_and_anonymize_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { // N.B., use `super_fold_with` here. If we used `fold_with`, it - // could invoke the `erase_regions_ty` query recursively. - ty.super_fold_with(&mut RegionEraserVisitor { tcx }) + // could invoke the `erase_and_anonymize_regions_ty` query recursively. + ty.super_fold_with(&mut RegionEraserAndAnonymizerVisitor { tcx }) } impl<'tcx> TyCtxt<'tcx> { - /// Returns an equivalent value with all free regions removed (note - /// that late-bound regions remain, because they are important for - /// subtyping, but they are anonymized and normalized as well).. - pub fn erase_regions(self, value: T) -> T + /// Returns an equivalent value with all free regions removed and + /// bound regions anonymized. (note that bound regions are important + /// for subtyping and generally type equality so *cannot* be removed) + pub fn erase_and_anonymize_regions(self, value: T) -> T where T: TypeFoldable>, { @@ -27,18 +27,18 @@ impl<'tcx> TyCtxt<'tcx> { if !value.has_type_flags(TypeFlags::HAS_BINDER_VARS | TypeFlags::HAS_FREE_REGIONS) { return value; } - debug!("erase_regions({:?})", value); - let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self }); - debug!("erase_regions = {:?}", value1); + debug!("erase_and_anonymize_regions({:?})", value); + let value1 = value.fold_with(&mut RegionEraserAndAnonymizerVisitor { tcx: self }); + debug!("erase_and_anonymize_regions = {:?}", value1); value1 } } -struct RegionEraserVisitor<'tcx> { +struct RegionEraserAndAnonymizerVisitor<'tcx> { tcx: TyCtxt<'tcx>, } -impl<'tcx> TypeFolder> for RegionEraserVisitor<'tcx> { +impl<'tcx> TypeFolder> for RegionEraserAndAnonymizerVisitor<'tcx> { fn cx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -49,7 +49,7 @@ impl<'tcx> TypeFolder> for RegionEraserVisitor<'tcx> { } else if ty.has_infer() { ty.super_fold_with(self) } else { - self.tcx.erase_regions_ty(ty) + self.tcx.erase_and_anonymize_regions_ty(ty) } } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 3a51f79f121..e76993e0542 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -544,7 +544,9 @@ impl<'tcx> Instance<'tcx> { // All regions in the result of this query are erased, so it's // fine to erase all of the input regions. - tcx.resolve_instance_raw(tcx.erase_regions(typing_env.as_query_input((def_id, args)))) + tcx.resolve_instance_raw( + tcx.erase_and_anonymize_regions(typing_env.as_query_input((def_id, args))), + ) } pub fn expect_resolve( diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index aed94f9aa04..2114d080dfa 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -401,7 +401,10 @@ impl<'tcx> SizeSkeleton<'tcx> { match tail.kind() { ty::Param(_) | ty::Alias(ty::Projection | ty::Inherent, _) => { debug_assert!(tail.has_non_region_param()); - Ok(SizeSkeleton::Pointer { non_zero, tail: tcx.erase_regions(tail) }) + Ok(SizeSkeleton::Pointer { + non_zero, + tail: tcx.erase_and_anonymize_regions(tail), + }) } ty::Error(guar) => { // Fixes ICE #124031 diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index f2a4a5a4ecf..69c1eb9b345 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -51,7 +51,7 @@ impl<'tcx> TyCtxt<'tcx> { // Erase first before we do the real query -- this keeps the // cache from being too polluted. - let value = self.erase_regions(value); + let value = self.erase_and_anonymize_regions(value); debug!(?value); if !value.has_aliases() { @@ -83,7 +83,7 @@ impl<'tcx> TyCtxt<'tcx> { // Erase first before we do the real query -- this keeps the // cache from being too polluted. - let value = self.erase_regions(value); + let value = self.erase_and_anonymize_regions(value); debug!(?value); if !value.has_aliases() { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 74caee7336a..05c812b6f90 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1436,8 +1436,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { // anonymized regions, but the super projections can still // contain named regions. So we erase and anonymize everything // here to compare the types modulo regions below. - let proj = p.tcx().erase_regions(proj); - let super_proj = p.tcx().erase_regions(super_proj); + let proj = p.tcx().erase_and_anonymize_regions(proj); + let super_proj = p.tcx().erase_and_anonymize_regions(super_proj); proj == super_proj }); diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index a7d07adf78f..5a9e1918e4c 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -132,9 +132,9 @@ impl<'tcx> TyCtxt<'tcx> { /// context it's calculated within. This is used by the `type_id` intrinsic. pub fn type_id_hash(self, ty: Ty<'tcx>) -> Hash128 { // We want the type_id be independent of the types free regions, so we - // erase them. The erase_regions() call will also anonymize bound - // regions, which is desirable too. - let ty = self.erase_regions(ty); + // erase them. We also want type_id to be independnt of the names of bound + // regions so we anonymize them. + let ty = self.erase_and_anonymize_regions(ty); self.with_stable_hashing_context(|mut hcx| { let mut hasher = StableHasher::new(); @@ -1309,7 +1309,7 @@ impl<'tcx> Ty<'tcx> { debug_assert!(!typing_env.param_env.has_infer()); let query_ty = tcx .try_normalize_erasing_regions(typing_env, query_ty) - .unwrap_or_else(|_| tcx.erase_regions(query_ty)); + .unwrap_or_else(|_| tcx.erase_and_anonymize_regions(query_ty)); tcx.needs_drop_raw(typing_env.as_query_input(query_ty)) } @@ -1346,7 +1346,7 @@ impl<'tcx> Ty<'tcx> { debug_assert!(!typing_env.has_infer()); let query_ty = tcx .try_normalize_erasing_regions(typing_env, query_ty) - .unwrap_or_else(|_| tcx.erase_regions(query_ty)); + .unwrap_or_else(|_| tcx.erase_and_anonymize_regions(query_ty)); tcx.needs_async_drop_raw(typing_env.as_query_input(query_ty)) } diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs index 6fc19c82342..e2f09fdcb4b 100644 --- a/compiler/rustc_middle/src/ty/vtable.rs +++ b/compiler/rustc_middle/src/ty/vtable.rs @@ -89,7 +89,7 @@ pub(super) fn vtable_allocation_provider<'tcx>( let vtable_entries = if let Some(poly_trait_ref) = poly_trait_ref { let trait_ref = poly_trait_ref.with_self_ty(tcx, ty); - let trait_ref = tcx.erase_regions(trait_ref); + let trait_ref = tcx.erase_and_anonymize_regions(trait_ref); tcx.vtable_entries(trait_ref) } else { diff --git a/compiler/rustc_mir_build/src/check_tail_calls.rs b/compiler/rustc_mir_build/src/check_tail_calls.rs index e0cbe8519ed..43a4106297a 100644 --- a/compiler/rustc_mir_build/src/check_tail_calls.rs +++ b/compiler/rustc_mir_build/src/check_tail_calls.rs @@ -65,9 +65,9 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { ) }; // While the `caller_sig` does have its regions erased, it does not have its - // binders anonymized. We call `erase_regions` once again to anonymize any binders + // binders anonymized. We call `erase_and_anonymize_regions` once again to anonymize any binders // within the signature, such as in function pointer or `dyn Trait` args. - let caller_sig = self.tcx.erase_regions(caller_sig); + let caller_sig = self.tcx.erase_and_anonymize_regions(caller_sig); let ExprKind::Scope { value, .. } = call.kind else { span_bug!(call.span, "expected scope, found: {call:?}") diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 81b0e21a5f5..0b9bc018a09 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -792,10 +792,9 @@ impl<'tcx> ThirBuildCx<'tcx> { let ty = self.typeck_results.node_type(anon_const.hir_id); let did = anon_const.def_id.to_def_id(); let typeck_root_def_id = tcx.typeck_root_def_id(did); - let parent_args = tcx.erase_regions(GenericArgs::identity_for_item( - tcx, - typeck_root_def_id, - )); + let parent_args = tcx.erase_and_anonymize_regions( + GenericArgs::identity_for_item(tcx, typeck_root_def_id), + ); let args = InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty }) .args; @@ -831,8 +830,10 @@ impl<'tcx> ThirBuildCx<'tcx> { let ty = self.typeck_results.node_type(anon_const.hir_id); let did = anon_const.def_id.to_def_id(); let typeck_root_def_id = tcx.typeck_root_def_id(did); - let parent_args = - tcx.erase_regions(GenericArgs::identity_for_item(tcx, typeck_root_def_id)); + let parent_args = tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item( + tcx, + typeck_root_def_id, + )); let args = InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty }).args; ExprKind::ConstBlock { did, args } diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index d46c4678bcf..6316ccf1b8c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -105,9 +105,11 @@ impl<'tcx> ConstToPat<'tcx> { // // FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself // instead of having this logic here - let typing_env = - self.tcx.erase_regions(self.typing_env).with_post_analysis_normalized(self.tcx); - let uv = self.tcx.erase_regions(uv); + let typing_env = self + .tcx + .erase_and_anonymize_regions(self.typing_env) + .with_post_analysis_normalized(self.tcx); + let uv = self.tcx.erase_and_anonymize_regions(uv); // try to resolve e.g. associated constants to their definition on an impl, and then // evaluate the const. diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 9a00831dc01..bf5ec8f459e 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -891,7 +891,7 @@ pub fn iter_fields<'tcx>( let field_ty = f_def.ty(tcx, args); let field_ty = tcx .try_normalize_erasing_regions(typing_env, field_ty) - .unwrap_or_else(|_| tcx.erase_regions(field_ty)); + .unwrap_or_else(|_| tcx.erase_and_anonymize_regions(field_ty)); f(variant, f_index.into(), field_ty); } } diff --git a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs index 92ee80eaa35..be4f84d64d0 100644 --- a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs +++ b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs @@ -32,8 +32,8 @@ impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> { let mut rval_ty = rvalue.ty(self.local_decls, self.tcx); // Not erasing this causes `Free Regions` errors in validator, // when rval is `ReStatic`. - rval_ty = self.tcx.erase_regions(rval_ty); - place_ty = self.tcx.erase_regions(place_ty); + rval_ty = self.tcx.erase_and_anonymize_regions(rval_ty); + place_ty = self.tcx.erase_and_anonymize_regions(place_ty); if place_ty != rval_ty { let temp = self .patcher diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index 462ddfa3dd3..9ea2eb4f25d 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -875,7 +875,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let mut promoted_operand = |ty, span| { promoted.span = span; promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span); - let args = tcx.erase_regions(GenericArgs::identity_for_item(tcx, def)); + let args = + tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item(tcx, def)); let uneval = mir::UnevaluatedConst { def, args, promoted: Some(next_promoted_index) }; diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index cffeb6f9807..77a3b12d19c 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1558,7 +1558,7 @@ impl<'v> RootCollector<'_, 'v> { ty::Closure(def_id, args) | ty::Coroutine(def_id, args) | ty::CoroutineClosure(def_id, args) => { - Instance::new_raw(def_id, self.tcx.erase_regions(args)) + Instance::new_raw(def_id, self.tcx.erase_and_anonymize_regions(args)) } _ => unreachable!(), }; diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 4d9741f1d11..95a7ec61868 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -54,7 +54,7 @@ pub(super) fn mangle<'tcx>( // Erase regions because they may not be deterministic when hashed // and should not matter anyhow. - let instance_ty = tcx.erase_regions(instance_ty); + let instance_ty = tcx.erase_and_anonymize_regions(instance_ty); let hash = get_symbol_hash(tcx, instance, instance_ty, instantiating_crate); @@ -422,7 +422,10 @@ impl<'tcx> Printer<'tcx> for LegacySymbolMangler<'tcx> { || &args[..generics.count()] == self .tcx - .erase_regions(ty::GenericArgs::identity_for_item(self.tcx, impl_def_id)) + .erase_and_anonymize_regions(ty::GenericArgs::identity_for_item( + self.tcx, + impl_def_id, + )) .as_slice() { ( diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs index 0c6d1495e39..50935e7caf3 100644 --- a/compiler/rustc_symbol_mangling/src/test.rs +++ b/compiler/rustc_symbol_mangling/src/test.rs @@ -58,7 +58,7 @@ impl SymbolNamesTest<'_> { let def_id = def_id.to_def_id(); let instance = Instance::new_raw( def_id, - tcx.erase_regions(GenericArgs::identity_for_item(tcx, def_id)), + tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item(tcx, def_id)), ); let mangled = tcx.symbol_name(instance); tcx.dcx().emit_err(TestOutput { diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 0655c2d5e81..121d3b6b105 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -329,7 +329,10 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> { || &args[..generics.count()] == self .tcx - .erase_regions(ty::GenericArgs::identity_for_item(self.tcx, impl_def_id)) + .erase_and_anonymize_regions(ty::GenericArgs::identity_for_item( + self.tcx, + impl_def_id, + )) .as_slice() { ( diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index d3a17232a40..d71110521ff 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -1616,8 +1616,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && let Some((e, f)) = values.ty() && let TypeError::ArgumentSorts(..) | TypeError::Sorts(_) = terr { - let e = self.tcx.erase_regions(e); - let f = self.tcx.erase_regions(f); + let e = self.tcx.erase_and_anonymize_regions(e); + let f = self.tcx.erase_and_anonymize_regions(f); let mut expected = with_forced_trimmed_paths!(e.sort_string(self.tcx)); let mut found = with_forced_trimmed_paths!(f.sort_string(self.tcx)); if let ObligationCauseCode::Pattern { span, .. } = cause.code() diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index 40285e5d0e9..e042ce84955 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -629,7 +629,11 @@ impl Trait for X { let tcx = self.tcx; // Don't suggest constraining a projection to something containing itself - if self.tcx.erase_regions(values.found).contains(self.tcx.erase_regions(values.expected)) { + if self + .tcx + .erase_and_anonymize_regions(values.found) + .contains(self.tcx.erase_and_anonymize_regions(values.expected)) + { return; } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index bc984f30472..c82043f0222 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -75,7 +75,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { { if let Some(cause) = self .tcx - .diagnostic_hir_wf_check((tcx.erase_regions(obligation.predicate), *wf_loc)) + .diagnostic_hir_wf_check((tcx.erase_and_anonymize_regions(obligation.predicate), *wf_loc)) { obligation.cause = cause.clone(); span = obligation.cause.span; @@ -2612,8 +2612,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } // Erase regions because layout code doesn't particularly care about regions. - let trait_pred = - self.tcx.erase_regions(self.tcx.instantiate_bound_regions_with_erased(trait_pred)); + let trait_pred = self.tcx.erase_and_anonymize_regions( + self.tcx.instantiate_bound_regions_with_erased(trait_pred), + ); let src_and_dst = rustc_transmute::Types { dst: trait_pred.trait_ref.args.type_at(0), diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index f6dbbeb51ca..cb84d583e6e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -2442,7 +2442,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Look for a type inside the coroutine interior that matches the target type to get // a span. - let target_ty_erased = self.tcx.erase_regions(target_ty); + let target_ty_erased = self.tcx.erase_and_anonymize_regions(target_ty); let ty_matches = |ty| -> bool { // Careful: the regions for types that appear in the // coroutine interior are not generally known, so we @@ -2454,10 +2454,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // interior generally contain "bound regions" to // represent regions that are part of the suspended // coroutine frame. Bound regions are preserved by - // `erase_regions` and so we must also call + // `erase_and_anonymize_regions` and so we must also call // `instantiate_bound_regions_with_erased`. let ty_erased = self.tcx.instantiate_bound_regions_with_erased(ty); - let ty_erased = self.tcx.erase_regions(ty_erased); + let ty_erased = self.tcx.erase_and_anonymize_regions(ty_erased); let eq = ty_erased == target_ty_erased; debug!(?ty_erased, ?target_ty_erased, ?eq); eq diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index 16f444486a6..b6bdf1067a3 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -300,7 +300,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< ) -> Result { // Erase regions because we compute layouts in `rustc_transmute`, // which will ICE for region vars. - let (dst, src) = self.tcx.erase_regions((dst, src)); + let (dst, src) = self.tcx.erase_and_anonymize_regions((dst, src)); let Some(assume) = rustc_transmute::Assume::from_const(self.tcx, assume) else { return Err(NoSolution); diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 4b493c95d59..bcd11d6918d 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -759,7 +759,7 @@ impl<'tcx> TypeVisitor> for IllegalSelfTypeVisitor<'tcx> { )), ) .map(|trait_ref| { - self.tcx.erase_regions( + self.tcx.erase_and_anonymize_regions( self.tcx.instantiate_bound_regions_with_erased(trait_ref), ) }) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index a9fb16b8000..6fefac43699 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -576,7 +576,7 @@ pub fn try_evaluate_const<'tcx>( let args = replace_param_and_infer_args_with_placeholder(tcx, uv.args); let typing_env = infcx - .typing_env(tcx.erase_regions(param_env)) + .typing_env(tcx.erase_and_anonymize_regions(param_env)) .with_post_analysis_normalized(tcx); (args, typing_env) } @@ -589,7 +589,7 @@ pub fn try_evaluate_const<'tcx>( } } else { let typing_env = infcx - .typing_env(tcx.erase_regions(param_env)) + .typing_env(tcx.erase_and_anonymize_regions(param_env)) .with_post_analysis_normalized(tcx); (uv.args, typing_env) } @@ -634,14 +634,14 @@ pub fn try_evaluate_const<'tcx>( } let typing_env = infcx - .typing_env(tcx.erase_regions(param_env)) + .typing_env(tcx.erase_and_anonymize_regions(param_env)) .with_post_analysis_normalized(tcx); (uv.args, typing_env) } }; let uv = ty::UnevaluatedConst::new(uv.def, args); - let erased_uv = tcx.erase_regions(uv); + let erased_uv = tcx.erase_and_anonymize_regions(uv); use rustc_middle::mir::interpret::ErrorHandled; // FIXME: `def_span` will point at the definition of this const; ideally, we'd point at diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index de404532899..f917b62e461 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -350,7 +350,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( // Note that we don't care about whether the resume type has any drops since this is // redundant; there is no storage for the resume type, so if it is actually stored // in the interior, we'll already detect the need for a drop by checking the interior. - let typing_env = tcx.erase_regions(typing_env); + let typing_env = tcx.erase_and_anonymize_regions(typing_env); let needs_drop = tcx.mir_coroutine_witnesses(def_id).is_some_and(|witness| { witness.field_tys.iter().any(|field| field.ty.needs_drop(tcx, typing_env)) }); diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index 7dd3c59edd0..4b05e2cc381 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -73,7 +73,7 @@ pub(crate) fn codegen_select_candidate<'tcx>( } let impl_source = infcx.resolve_vars_if_possible(impl_source); - let impl_source = tcx.erase_regions(impl_source); + let impl_source = tcx.erase_and_anonymize_regions(impl_source); if impl_source.has_non_region_infer() { // Unused generic types or consts on an impl get replaced with inference vars, // but never resolved, causing the return value of a query to contain inference diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index c1b848a2e79..c98b56abe9c 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -41,7 +41,7 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable> + Par // fresh `InferCtxt`. If this assert does trigger, it will give // us a test case. debug_assert_eq!(normalized_value, resolved_value); - let erased = infcx.tcx.erase_regions(resolved_value); + let erased = infcx.tcx.erase_and_anonymize_regions(resolved_value); debug_assert!(!erased.has_infer(), "{erased:?}"); Ok(erased) } diff --git a/compiler/rustc_transmute/src/layout/mod.rs b/compiler/rustc_transmute/src/layout/mod.rs index acbce258f39..4e548ff8fe2 100644 --- a/compiler/rustc_transmute/src/layout/mod.rs +++ b/compiler/rustc_transmute/src/layout/mod.rs @@ -163,7 +163,7 @@ pub mod rustc { ty: Ty<'tcx>, ) -> Result, &'tcx LayoutError<'tcx>> { use rustc_middle::ty::layout::LayoutOf; - let ty = cx.tcx().erase_regions(ty); + let ty = cx.tcx().erase_and_anonymize_regions(ty); cx.layout_of(ty).map(|tl| tl.layout) } } diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index 3f83b4d50aa..406a1b5746f 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -426,24 +426,25 @@ pub(crate) mod rustc { assert!(def.is_enum()); // Computes the layout of a variant. - let layout_of_variant = - |index, encoding: Option>| -> Result { - let variant_layout = ty_variant(cx, (ty, layout), index); - if variant_layout.is_uninhabited() { - return Ok(Self::uninhabited()); - } - let tag = cx.tcx().tag_for_variant( - cx.typing_env.as_query_input((cx.tcx().erase_regions(ty), index)), - ); - let variant_def = Def::Variant(def.variant(index)); - Self::from_variant( - variant_def, - tag.map(|tag| (tag, index, encoding.unwrap())), - (ty, variant_layout), - layout.size, - cx, - ) - }; + let layout_of_variant = |index, + encoding: Option>| + -> Result { + let variant_layout = ty_variant(cx, (ty, layout), index); + if variant_layout.is_uninhabited() { + return Ok(Self::uninhabited()); + } + let tag = cx.tcx().tag_for_variant( + cx.typing_env.as_query_input((cx.tcx().erase_and_anonymize_regions(ty), index)), + ); + let variant_def = Def::Variant(def.variant(index)); + Self::from_variant( + variant_def, + tag.map(|tag| (tag, index, encoding.unwrap())), + (ty, variant_layout), + layout.size, + cx, + ) + }; match layout.variants() { Variants::Empty => Ok(Self::uninhabited()), @@ -634,7 +635,7 @@ pub(crate) mod rustc { (ty, layout): (Ty<'tcx>, Layout<'tcx>), i: VariantIdx, ) -> Layout<'tcx> { - let ty = cx.tcx().erase_regions(ty); + let ty = cx.tcx().erase_and_anonymize_regions(ty); TyAndLayout { ty, layout }.for_variant(&cx, i).layout } } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 5c3f7d491a5..e28ebaabc0a 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -176,7 +176,7 @@ fn resolve_associated_item<'tcx>( args, leaf_def.defining_node, ); - let args = infcx.tcx.erase_regions(args); + let args = infcx.tcx.erase_and_anonymize_regions(args); // HACK: We may have overlapping `dyn Trait` built-in impls and // user-provided blanket impls. Detect that case here, and return @@ -222,7 +222,7 @@ fn resolve_associated_item<'tcx>( return Err(guar); } - let args = tcx.erase_regions(args); + let args = tcx.erase_and_anonymize_regions(args); // We check that the impl item is compatible with the trait item // because otherwise we may ICE in const eval due to type mismatches, @@ -279,7 +279,7 @@ fn resolve_associated_item<'tcx>( assert_eq!(name, sym::clone_from); // Use the default `fn clone_from` from `trait Clone`. - let args = tcx.erase_regions(rcvr_args); + let args = tcx.erase_and_anonymize_regions(rcvr_args); Some(ty::Instance::new_raw(trait_item_id, args)) } } else if tcx.is_lang_item(trait_ref.def_id, LangItem::FnPtrTrait) { @@ -380,7 +380,7 @@ fn resolve_associated_item<'tcx>( } else if tcx.is_lang_item(trait_ref.def_id, LangItem::TransmuteTrait) { let name = tcx.item_name(trait_item_id); assert_eq!(name, sym::transmute); - let args = tcx.erase_regions(rcvr_args); + let args = tcx.erase_and_anonymize_regions(rcvr_args); Some(ty::Instance::new_raw(trait_item_id, args)) } else { Instance::try_resolve_item_for_coroutine(tcx, trait_item_id, trait_id, rcvr_args) diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 5104484e9c4..a30aa42a0a4 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -400,7 +400,7 @@ impl std::fmt::Debug for HasTypeFlagsVisitor { // N.B. The only case where this isn't totally true is binders, which also // add `HAS_{RE,TY,CT}_LATE_BOUND` flag depending on the *bound variables* that // are present, regardless of whether those bound variables are used. This -// is important for anonymization of binders in `TyCtxt::erase_regions`. We +// is important for anonymization of binders in `TyCtxt::erase_and_anonymize_regions`. We // specifically detect this case in `visit_binder`. impl TypeVisitor for HasTypeFlagsVisitor { type Result = ControlFlow; diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 9aa2f3cf0a5..9645a26a68a 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -364,7 +364,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { // priority. if let Some(fn_id) = typeck.type_dependent_def_id(hir_id) && let Some(trait_id) = cx.tcx.trait_of_assoc(fn_id) - && let arg_ty = cx.tcx.erase_regions(adjusted_ty) + && let arg_ty = cx.tcx.erase_and_anonymize_regions(adjusted_ty) && let ty::Ref(_, sub_ty, _) = *arg_ty.kind() && let args = typeck.node_args_opt(hir_id).map(|args| &args[1..]).unwrap_or_default() diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs index 010652e1cb9..6ce7f0b1f0b 100644 --- a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs @@ -140,7 +140,7 @@ fn is_ref_iterable<'tcx>( let res_ty = cx .tcx - .erase_regions(EarlyBinder::bind(req_res_ty).instantiate(cx.tcx, typeck.node_args(call_expr.hir_id))); + .erase_and_anonymize_regions(EarlyBinder::bind(req_res_ty).instantiate(cx.tcx, typeck.node_args(call_expr.hir_id))); let mutbl = if let ty::Ref(_, _, mutbl) = *req_self_ty.kind() { Some(mutbl) } else { diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs index a42763172f5..809a6728e12 100644 --- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs @@ -252,7 +252,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { { ( trait_item_id, - FnKind::ImplTraitFn(std::ptr::from_ref(cx.tcx.erase_regions(trait_ref.args)) as usize), + FnKind::ImplTraitFn(std::ptr::from_ref(cx.tcx.erase_and_anonymize_regions(trait_ref.args)) as usize), usize::from(sig.decl.implicit_self.has_implicit_self()), ) } else { diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs index 3842c4eb60e..6aeb22d41a7 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs @@ -45,7 +45,7 @@ pub(super) fn check<'tcx>( Applicability::MaybeIncorrect, ); triggered = true; - } else if (cx.tcx.erase_regions(from_ty) != cx.tcx.erase_regions(to_ty)) && !const_context { + } else if (cx.tcx.erase_and_anonymize_regions(from_ty) != cx.tcx.erase_and_anonymize_regions(to_ty)) && !const_context { span_lint_and_then( cx, TRANSMUTE_PTR_TO_PTR, diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs index 26323af3122..3e6aae475ec 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs @@ -12,8 +12,8 @@ pub(super) fn check<'tcx>( from_ty_orig: Ty<'tcx>, to_ty_orig: Ty<'tcx>, ) -> bool { - let mut from_ty = cx.tcx.erase_regions(from_ty_orig); - let mut to_ty = cx.tcx.erase_regions(to_ty_orig); + let mut from_ty = cx.tcx.erase_and_anonymize_regions(from_ty_orig); + let mut to_ty = cx.tcx.erase_and_anonymize_regions(to_ty_orig); while from_ty != to_ty { let reduced_tys = reduce_refs(cx, from_ty, to_ty); diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs index 70ae982a445..e45f884cfcb 100644 --- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs +++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs @@ -98,7 +98,7 @@ fn into_iter_bound<'tcx>( if tr.def_id() == into_iter_did { into_iter_span = Some(*span); } else { - let tr = cx.tcx.erase_regions(tr); + let tr = cx.tcx.erase_and_anonymize_regions(tr); if tr.has_escaping_bound_vars() { return None; } diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs index 8e302f9d2ad..9f77a1c4d9b 100644 --- a/src/tools/clippy/clippy_utils/src/ty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs @@ -285,7 +285,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>( let _ = tcx.hir_body_owner_kind(callee_id); } - let ty = tcx.erase_regions(ty); + let ty = tcx.erase_and_anonymize_regions(ty); if ty.has_escaping_bound_vars() { return false; } -- cgit 1.4.1-3-g733a5 From 6e36750c617c656432aafaffe170691b91ecc985 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 9 Sep 2025 10:30:03 -0700 Subject: Update wasm-component-ld to 0.5.17 Keeping this up-to-date as the project itself, and its dependencies, are updated. --- Cargo.lock | 50 +++++++++++++++++----------------- src/tools/wasm-component-ld/Cargo.toml | 2 +- 2 files changed, 26 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index c29c3158d4a..cff5864dbbe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5984,9 +5984,9 @@ dependencies = [ [[package]] name = "wasm-component-ld" -version = "0.5.16" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cd35d6cae91109a0ffd207b573cf3c741cab7e921dd376ea7aaf2c52a3408c" +checksum = "1c9208f87cac2332fd80dcf36d54e9163d3446e28301e0c6e424984425738984" dependencies = [ "anyhow", "clap", @@ -5994,9 +5994,9 @@ dependencies = [ "libc", "tempfile", "wasi-preview1-component-adapter-provider", - "wasmparser 0.237.0", + "wasmparser 0.239.0", "wat", - "windows-sys 0.59.0", + "windows-sys 0.60.2", "winsplit", "wit-component", "wit-parser", @@ -6021,24 +6021,24 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.237.0" +version = "0.239.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efe92d1321afa53ffc88a57c497bb7330c3cf84c98ffdba4a4caf6a0684fad3c" +checksum = "5be00faa2b4950c76fe618c409d2c3ea5a3c9422013e079482d78544bb2d184c" dependencies = [ "leb128fmt", - "wasmparser 0.237.0", + "wasmparser 0.239.0", ] [[package]] name = "wasm-metadata" -version = "0.237.0" +version = "0.239.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cc0b0a0c4f35ca6efa7a797671372915d4e9659dba2d59edc6fafc931d19997" +checksum = "20b3ec880a9ac69ccd92fbdbcf46ee833071cf09f82bb005b2327c7ae6025ae2" dependencies = [ "anyhow", "indexmap", - "wasm-encoder 0.237.0", - "wasmparser 0.237.0", + "wasm-encoder 0.239.0", + "wasmparser 0.239.0", ] [[package]] @@ -6063,9 +6063,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.237.0" +version = "0.239.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d2a40ca0d2bdf4b0bf36c13a737d0b2c58e4c8aaefe1c57f336dd75369ca250" +checksum = "8c9d90bb93e764f6beabf1d02028c70a2156a6583e63ac4218dd07ef733368b0" dependencies = [ "bitflags", "hashbrown", @@ -6076,22 +6076,22 @@ dependencies = [ [[package]] name = "wast" -version = "237.0.0" +version = "239.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf66f545acbd55082485cb9a6daab54579cb8628a027162253e8e9f5963c767" +checksum = "9139176fe8a2590e0fb174cdcaf373b224cb93c3dde08e4297c1361d2ba1ea5d" dependencies = [ "bumpalo", "leb128fmt", "memchr", "unicode-width 0.2.1", - "wasm-encoder 0.237.0", + "wasm-encoder 0.239.0", ] [[package]] name = "wat" -version = "1.237.0" +version = "1.239.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27975186f549e4b8d6878b627be732863883c72f7bf4dcf8f96e5f8242f73da9" +checksum = "3e1c941927d34709f255558166f8901a2005f8ab4a9650432e9281b7cc6f3b75" dependencies = [ "wast", ] @@ -6580,9 +6580,9 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.237.0" +version = "0.239.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb7674f76c10e82fe00b256a9d4ffb2b8d037d42ab8e9a83ebb3be35c9d0bf6" +checksum = "88a866b19dba2c94d706ec58c92a4c62ab63e482b4c935d2a085ac94caecb136" dependencies = [ "anyhow", "bitflags", @@ -6591,17 +6591,17 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "wasm-encoder 0.237.0", + "wasm-encoder 0.239.0", "wasm-metadata", - "wasmparser 0.237.0", + "wasmparser 0.239.0", "wit-parser", ] [[package]] name = "wit-parser" -version = "0.237.0" +version = "0.239.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce2596a5bc7c24cc965b56ad6ff9e32394c4e401764f89620a888519c6e849ab" +checksum = "55c92c939d667b7bf0c6bf2d1f67196529758f99a2a45a3355cc56964fd5315d" dependencies = [ "anyhow", "id-arena", @@ -6612,7 +6612,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-xid", - "wasmparser 0.237.0", + "wasmparser 0.239.0", ] [[package]] diff --git a/src/tools/wasm-component-ld/Cargo.toml b/src/tools/wasm-component-ld/Cargo.toml index 23dc86998e8..3def2391a13 100644 --- a/src/tools/wasm-component-ld/Cargo.toml +++ b/src/tools/wasm-component-ld/Cargo.toml @@ -10,4 +10,4 @@ name = "wasm-component-ld" path = "src/main.rs" [dependencies] -wasm-component-ld = "0.5.16" +wasm-component-ld = "0.5.17" -- cgit 1.4.1-3-g733a5 From 7a66925a8138df105f77d646f9206024baf7ea4b Mon Sep 17 00:00:00 2001 From: León Orell Valerian Liehr Date: Mon, 8 Sep 2025 19:25:22 +0200 Subject: Strip frontmatter in fewer places --- compiler/rustc_builtin_macros/src/source_util.rs | 69 ++++++++++++++-------- compiler/rustc_driver_impl/src/lib.rs | 12 +++- compiler/rustc_expand/src/module.rs | 9 ++- compiler/rustc_expand/src/proc_macro_server.rs | 11 +++- compiler/rustc_interface/src/interface.rs | 22 ++++--- compiler/rustc_interface/src/passes.rs | 17 ++++-- compiler/rustc_parse/src/lexer/mod.rs | 2 +- compiler/rustc_parse/src/lib.rs | 36 +++++------ compiler/rustc_parse/src/parser/tests.rs | 7 ++- src/librustdoc/clean/render_macro_matchers.rs | 21 ++++--- src/librustdoc/doctest/make.rs | 19 +++--- .../clippy_lints/src/doc/needless_doctest_main.rs | 16 ++--- src/tools/rustfmt/src/parse/parser.rs | 14 ++++- tests/ui-fulldeps/auxiliary/parser.rs | 3 +- tests/ui-fulldeps/mod_dir_path_canonicalized.rs | 9 ++- tests/ui/frontmatter/auxiliary/expr.rs | 4 ++ tests/ui/frontmatter/auxiliary/makro.rs | 14 ++++- tests/ui/frontmatter/include-in-expr-ctxt.rs | 9 +++ tests/ui/frontmatter/include-in-item-ctxt.rs | 10 ++++ tests/ui/frontmatter/included-frontmatter.rs | 12 ---- tests/ui/frontmatter/proc-macro-observer.rs | 7 +-- 21 files changed, 208 insertions(+), 115 deletions(-) create mode 100644 tests/ui/frontmatter/auxiliary/expr.rs create mode 100644 tests/ui/frontmatter/include-in-expr-ctxt.rs create mode 100644 tests/ui/frontmatter/include-in-item-ctxt.rs delete mode 100644 tests/ui/frontmatter/included-frontmatter.rs (limited to 'src') diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index f95c8f38229..11b868f81a9 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -13,9 +13,11 @@ use rustc_expand::base::{ }; use rustc_expand::module::DirOwnership; use rustc_lint_defs::BuiltinLintDiag; -use rustc_parse::parser::{ForceCollect, Parser}; +use rustc_parse::lexer::StripTokens; +use rustc_parse::parser::ForceCollect; use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal, utf8_error}; use rustc_session::lint::builtin::INCOMPLETE_INCLUDE; +use rustc_session::parse::ParseSess; use rustc_span::source_map::SourceMap; use rustc_span::{ByteSymbol, Pos, Span, Symbol}; use smallvec::SmallVec; @@ -114,39 +116,48 @@ pub(crate) fn expand_include<'cx>( let ExpandResult::Ready(mac) = get_single_str_from_tts(cx, sp, tts, "include!") else { return ExpandResult::Retry(()); }; - let file = match mac { - Ok(file) => file, + let path = match mac { + Ok(path) => path, Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)), }; // The file will be added to the code map by the parser - let file = match resolve_path(&cx.sess, file.as_str(), sp) { - Ok(f) => f, + let path = match resolve_path(&cx.sess, path.as_str(), sp) { + Ok(path) => path, Err(err) => { let guar = err.emit(); return ExpandResult::Ready(DummyResult::any(sp, guar)); } }; - let p = unwrap_or_emit_fatal(new_parser_from_file(cx.psess(), &file, Some(sp))); // If in the included file we have e.g., `mod bar;`, - // then the path of `bar.rs` should be relative to the directory of `file`. + // then the path of `bar.rs` should be relative to the directory of `path`. // See https://github.com/rust-lang/rust/pull/69838/files#r395217057 for a discussion. // `MacroExpander::fully_expand_fragment` later restores, so "stack discipline" is maintained. - let dir_path = file.parent().unwrap_or(&file).to_owned(); + let dir_path = path.parent().unwrap_or(&path).to_owned(); cx.current_expansion.module = Rc::new(cx.current_expansion.module.with_dir_path(dir_path)); cx.current_expansion.dir_ownership = DirOwnership::Owned { relative: None }; struct ExpandInclude<'a> { - p: Parser<'a>, + psess: &'a ParseSess, + path: PathBuf, node_id: ast::NodeId, + span: Span, } impl<'a> MacResult for ExpandInclude<'a> { - fn make_expr(mut self: Box>) -> Option> { - let expr = parse_expr(&mut self.p).ok()?; - if self.p.token != token::Eof { - self.p.psess.buffer_lint( + fn make_expr(self: Box>) -> Option> { + let mut p = unwrap_or_emit_fatal(new_parser_from_file( + self.psess, + &self.path, + // Don't strip frontmatter for backward compatibility, `---` may be the start of a + // manifold negation. FIXME: Ideally, we wouldn't strip shebangs here either. + StripTokens::Shebang, + Some(self.span), + )); + let expr = parse_expr(&mut p).ok()?; + if p.token != token::Eof { + p.psess.buffer_lint( INCOMPLETE_INCLUDE, - self.p.token.span, + p.token.span, self.node_id, BuiltinLintDiag::IncompleteInclude, ); @@ -154,24 +165,27 @@ pub(crate) fn expand_include<'cx>( Some(expr) } - fn make_items(mut self: Box>) -> Option; 1]>> { + fn make_items(self: Box>) -> Option; 1]>> { + let mut p = unwrap_or_emit_fatal(new_parser_from_file( + self.psess, + &self.path, + StripTokens::ShebangAndFrontmatter, + Some(self.span), + )); let mut ret = SmallVec::new(); loop { - match self.p.parse_item(ForceCollect::No) { + match p.parse_item(ForceCollect::No) { Err(err) => { err.emit(); break; } Ok(Some(item)) => ret.push(item), Ok(None) => { - if self.p.token != token::Eof { - self.p - .dcx() - .create_err(errors::ExpectedItem { - span: self.p.token.span, - token: &pprust::token_to_string(&self.p.token), - }) - .emit(); + if p.token != token::Eof { + p.dcx().emit_err(errors::ExpectedItem { + span: p.token.span, + token: &pprust::token_to_string(&p.token), + }); } break; @@ -182,7 +196,12 @@ pub(crate) fn expand_include<'cx>( } } - ExpandResult::Ready(Box::new(ExpandInclude { p, node_id: cx.current_expansion.lint_node_id })) + ExpandResult::Ready(Box::new(ExpandInclude { + psess: cx.psess(), + path, + node_id: cx.current_expansion.lint_node_id, + span: sp, + })) } /// Expand `include_str!($input)` to the content of the UTF-8-encoded file given by path `$input` as a string literal. diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index f3ed6042105..d00a4c35834 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -51,6 +51,7 @@ use rustc_lint::unerased_lint_store; use rustc_metadata::creader::MetadataLoader; use rustc_metadata::locator; use rustc_middle::ty::TyCtxt; +use rustc_parse::lexer::StripTokens; use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal}; use rustc_session::config::{ CG_OPTIONS, CrateType, ErrorOutputType, Input, OptionDesc, OutFileName, OutputType, Sysroot, @@ -1288,10 +1289,15 @@ fn warn_on_confusing_output_filename_flag( fn parse_crate_attrs<'a>(sess: &'a Session) -> PResult<'a, ast::AttrVec> { let mut parser = unwrap_or_emit_fatal(match &sess.io.input { - Input::File(file) => new_parser_from_file(&sess.psess, file, None), - Input::Str { name, input } => { - new_parser_from_source_str(&sess.psess, name.clone(), input.clone()) + Input::File(file) => { + new_parser_from_file(&sess.psess, file, StripTokens::ShebangAndFrontmatter, None) } + Input::Str { name, input } => new_parser_from_source_str( + &sess.psess, + name.clone(), + input.clone(), + StripTokens::ShebangAndFrontmatter, + ), }); parser.parse_inner_attributes() } diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs index 19f3cdbc549..79ab3cab22c 100644 --- a/compiler/rustc_expand/src/module.rs +++ b/compiler/rustc_expand/src/module.rs @@ -4,6 +4,7 @@ use std::path::{self, Path, PathBuf}; use rustc_ast::{AttrVec, Attribute, Inline, Item, ModSpans}; use rustc_attr_parsing::validate_attr; use rustc_errors::{Diag, ErrorGuaranteed}; +use rustc_parse::lexer::StripTokens; use rustc_parse::{exp, new_parser_from_file, unwrap_or_emit_fatal}; use rustc_session::Session; use rustc_session::parse::ParseSess; @@ -67,8 +68,12 @@ pub(crate) fn parse_external_mod( } // Actually parse the external file as a module. - let mut parser = - unwrap_or_emit_fatal(new_parser_from_file(&sess.psess, &mp.file_path, Some(span))); + let mut parser = unwrap_or_emit_fatal(new_parser_from_file( + &sess.psess, + &mp.file_path, + StripTokens::ShebangAndFrontmatter, + Some(span), + )); let (inner_attrs, items, inner_span) = parser.parse_mod(exp!(Eof)).map_err(|err| ModError::ParserError(err))?; attrs.extend(inner_attrs); diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 5b1d3d6d35b..295573f4492 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -8,7 +8,7 @@ use rustc_ast::util::literal::escape_byte_str_symbol; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Diag, ErrorGuaranteed, MultiSpan, PResult}; -use rustc_parse::lexer::nfc_normalize; +use rustc_parse::lexer::{StripTokens, nfc_normalize}; use rustc_parse::parser::Parser; use rustc_parse::{exp, new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal}; use rustc_proc_macro::bridge::{ @@ -485,8 +485,13 @@ impl server::FreeFunctions for Rustc<'_, '_> { fn literal_from_str(&mut self, s: &str) -> Result, ()> { let name = FileName::proc_macro_source_code(s); - let mut parser = - unwrap_or_emit_fatal(new_parser_from_source_str(self.psess(), name, s.to_owned())); + + let mut parser = unwrap_or_emit_fatal(new_parser_from_source_str( + self.psess(), + name, + s.to_owned(), + StripTokens::Nothing, + )); let first_span = parser.token.span.data(); let minus_present = parser.eat(exp!(Minus)); diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 4c820b8877b..b52c5b4cd66 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -13,7 +13,8 @@ use rustc_lint::LintStore; use rustc_middle::ty; use rustc_middle::ty::CurrentGcx; use rustc_middle::util::Providers; -use rustc_parse::new_parser_from_simple_source_str; +use rustc_parse::lexer::StripTokens; +use rustc_parse::new_parser_from_source_str; use rustc_parse::parser::attr::AllowLeadingUnsafe; use rustc_query_impl::QueryCtxt; use rustc_query_system::query::print_query_stack; @@ -68,7 +69,8 @@ pub(crate) fn parse_cfg(dcx: DiagCtxtHandle<'_>, cfgs: Vec) -> Cfg { }; } - match new_parser_from_simple_source_str(&psess, filename, s.to_string()) { + match new_parser_from_source_str(&psess, filename, s.to_string(), StripTokens::Nothing) + { Ok(mut parser) => match parser.parse_meta_item(AllowLeadingUnsafe::No) { Ok(meta_item) if parser.token == token::Eof => { if meta_item.path.segments.len() != 1 { @@ -166,13 +168,15 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec) -> Ch error!("expected `cfg(name, values(\"value1\", \"value2\", ... \"valueN\"))`") }; - let mut parser = match new_parser_from_simple_source_str(&psess, filename, s.to_string()) { - Ok(parser) => parser, - Err(errs) => { - errs.into_iter().for_each(|err| err.cancel()); - expected_error(); - } - }; + let mut parser = + match new_parser_from_source_str(&psess, filename, s.to_string(), StripTokens::Nothing) + { + Ok(parser) => parser, + Err(errs) => { + errs.into_iter().for_each(|err| err.cancel()); + expected_error(); + } + }; let meta_item = match parser.parse_meta_item(AllowLeadingUnsafe::No) { Ok(meta_item) if parser.token == token::Eof => meta_item, diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index ca8c10311fb..cf81a125707 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -27,6 +27,7 @@ use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepsType; use rustc_middle::ty::{self, CurrentGcx, GlobalCtxt, RegisteredTools, TyCtxt}; use rustc_middle::util::Providers; +use rustc_parse::lexer::StripTokens; use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal}; use rustc_passes::{abi_test, input_stats, layout_test}; use rustc_resolve::{Resolver, ResolverOutputs}; @@ -51,10 +52,18 @@ pub fn parse<'a>(sess: &'a Session) -> ast::Crate { let mut krate = sess .time("parse_crate", || { let mut parser = unwrap_or_emit_fatal(match &sess.io.input { - Input::File(file) => new_parser_from_file(&sess.psess, file, None), - Input::Str { input, name } => { - new_parser_from_source_str(&sess.psess, name.clone(), input.clone()) - } + Input::File(file) => new_parser_from_file( + &sess.psess, + file, + StripTokens::ShebangAndFrontmatter, + None, + ), + Input::Str { input, name } => new_parser_from_source_str( + &sess.psess, + name.clone(), + input.clone(), + StripTokens::ShebangAndFrontmatter, + ), }); parser.parse_crate_mod() }) diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index f5f081efc49..51019db7c00 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -45,7 +45,7 @@ pub(crate) struct UnmatchedDelim { } /// Which tokens should be stripped before lexing the tokens. -pub(crate) enum StripTokens { +pub enum StripTokens { /// Strip both shebang and frontmatter. ShebangAndFrontmatter, /// Strip the shebang but not frontmatter. diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index d8792d7af4c..88b67d792de 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -54,29 +54,18 @@ pub fn unwrap_or_emit_fatal(expr: Result>>) -> T { } } -/// Creates a new parser from a source string. On failure, the errors must be consumed via -/// `unwrap_or_emit_fatal`, `emit`, `cancel`, etc., otherwise a panic will occur when they are -/// dropped. -pub fn new_parser_from_source_str( - psess: &ParseSess, - name: FileName, - source: String, -) -> Result, Vec>> { - let source_file = psess.source_map().new_source_file(name, source); - new_parser_from_source_file(psess, source_file, StripTokens::ShebangAndFrontmatter) -} - -/// Creates a new parser from a simple (no shebang, no frontmatter) source string. +/// Creates a new parser from a source string. /// /// On failure, the errors must be consumed via `unwrap_or_emit_fatal`, `emit`, `cancel`, /// etc., otherwise a panic will occur when they are dropped. -pub fn new_parser_from_simple_source_str( +pub fn new_parser_from_source_str( psess: &ParseSess, name: FileName, source: String, + strip_tokens: StripTokens, ) -> Result, Vec>> { let source_file = psess.source_map().new_source_file(name, source); - new_parser_from_source_file(psess, source_file, StripTokens::Nothing) + new_parser_from_source_file(psess, source_file, strip_tokens) } /// Creates a new parser from a filename. On failure, the errors must be consumed via @@ -87,6 +76,7 @@ pub fn new_parser_from_simple_source_str( pub fn new_parser_from_file<'a>( psess: &'a ParseSess, path: &Path, + strip_tokens: StripTokens, sp: Option, ) -> Result, Vec>> { let sm = psess.source_map(); @@ -110,7 +100,7 @@ pub fn new_parser_from_file<'a>( } err.emit(); }); - new_parser_from_source_file(psess, source_file, StripTokens::ShebangAndFrontmatter) + new_parser_from_source_file(psess, source_file, strip_tokens) } pub fn utf8_error( @@ -172,6 +162,9 @@ fn new_parser_from_source_file( Ok(parser) } +/// Given a source string, produces a sequence of token trees. +/// +/// NOTE: This only strips shebangs, not frontmatter! pub fn source_str_to_stream( psess: &ParseSess, name: FileName, @@ -179,13 +172,16 @@ pub fn source_str_to_stream( override_span: Option, ) -> Result>> { let source_file = psess.source_map().new_source_file(name, source); - // used mainly for `proc_macro` and the likes, not for our parsing purposes, so don't parse - // frontmatters as frontmatters, but for compatibility reason still strip the shebang + // FIXME(frontmatter): Consider stripping frontmatter in a future edition. We can't strip them + // in the current edition since that would be breaking. + // See also . + // Alternatively, stop stripping shebangs here, too, if T-lang and crater approve. source_file_to_stream(psess, source_file, override_span, StripTokens::Shebang) } -/// Given a source file, produces a sequence of token trees. Returns any buffered errors from -/// parsing the token stream. +/// Given a source file, produces a sequence of token trees. +/// +/// Returns any buffered errors from parsing the token stream. fn source_file_to_stream<'psess>( psess: &'psess ParseSess, source_file: Arc, diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs index a6e7266e71b..e645fb47b9e 100644 --- a/compiler/rustc_parse/src/parser/tests.rs +++ b/compiler/rustc_parse/src/parser/tests.rs @@ -22,6 +22,7 @@ use rustc_span::{ }; use termcolor::WriteColor; +use crate::lexer::StripTokens; use crate::parser::{ForceCollect, Parser}; use crate::{new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal}; @@ -35,6 +36,7 @@ fn string_to_parser(psess: &ParseSess, source_str: String) -> Parser<'_> { psess, PathBuf::from("bogofile").into(), source_str, + StripTokens::Nothing, )) } @@ -2240,7 +2242,7 @@ fn parse_item_from_source_str( source: String, psess: &ParseSess, ) -> PResult<'_, Option>> { - unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source)) + unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source, StripTokens::Nothing)) .parse_item(ForceCollect::No) } @@ -2520,7 +2522,8 @@ fn ttdelim_span() { source: String, psess: &ParseSess, ) -> PResult<'_, Box> { - unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source)).parse_expr() + unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source, StripTokens::Nothing)) + .parse_expr() } create_default_session_globals_then(|| { diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs index d684e6f8650..b5a8d64ff4f 100644 --- a/src/librustdoc/clean/render_macro_matchers.rs +++ b/src/librustdoc/clean/render_macro_matchers.rs @@ -3,6 +3,7 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast_pretty::pprust::PrintState; use rustc_ast_pretty::pprust::state::State as Printer; use rustc_middle::ty::TyCtxt; +use rustc_parse::lexer::StripTokens; use rustc_session::parse::ParseSess; use rustc_span::symbol::{Ident, Symbol, kw}; use rustc_span::{FileName, Span}; @@ -64,14 +65,18 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option parser, - Err(errs) => { - errs.into_iter().for_each(|err| err.cancel()); - return None; - } - }; + let mut parser = match rustc_parse::new_parser_from_source_str( + &psess, + file_name, + snippet.clone(), + StripTokens::Nothing, + ) { + Ok(parser) => parser, + Err(errs) => { + errs.into_iter().for_each(|err| err.cancel()); + return None; + } + }; // Reparse a single token tree. if parser.token == token::Eof { diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index f229f77c978..5eaadc9eb45 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -10,6 +10,7 @@ use rustc_ast::tokenstream::TokenTree; use rustc_ast::{self as ast, AttrStyle, HasAttrs, StmtKind}; use rustc_errors::emitter::stderr_destination; use rustc_errors::{ColorConfig, DiagCtxtHandle}; +use rustc_parse::lexer::StripTokens; use rustc_parse::new_parser_from_source_str; use rustc_session::parse::ParseSess; use rustc_span::edition::{DEFAULT_EDITION, Edition}; @@ -468,14 +469,16 @@ fn parse_source( let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings(); let psess = ParseSess::with_dcx(dcx, sm); - let mut parser = match new_parser_from_source_str(&psess, filename, wrapped_source) { - Ok(p) => p, - Err(errs) => { - errs.into_iter().for_each(|err| err.cancel()); - reset_error_count(&psess); - return Err(()); - } - }; + // Don't strip any tokens; it wouldn't matter anyway because the source is wrapped in a function. + let mut parser = + match new_parser_from_source_str(&psess, filename, wrapped_source, StripTokens::Nothing) { + Ok(p) => p, + Err(errs) => { + errs.into_iter().for_each(|err| err.cancel()); + reset_error_count(&psess); + return Err(()); + } + }; fn push_to_s(s: &mut String, source: &str, span: rustc_span::Span, prev_span_hi: &mut usize) { let extra_len = DOCTEST_CODE_WRAPPER.len(); diff --git a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs index 74283d7ba86..43bb9723555 100644 --- a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs +++ b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs @@ -8,6 +8,7 @@ use rustc_ast::{CoroutineKind, Fn, FnRetTy, Item, ItemKind}; use rustc_errors::emitter::HumanEmitter; use rustc_errors::{Diag, DiagCtxt}; use rustc_lint::LateContext; +use rustc_parse::lexer::StripTokens; use rustc_parse::new_parser_from_source_str; use rustc_parse::parser::ForceCollect; use rustc_session::parse::ParseSess; @@ -49,13 +50,14 @@ pub fn check( let sm = Arc::new(SourceMap::new(FilePathMapping::empty())); let psess = ParseSess::with_dcx(dcx, sm); - let mut parser = match new_parser_from_source_str(&psess, filename, code) { - Ok(p) => p, - Err(errs) => { - errs.into_iter().for_each(Diag::cancel); - return (false, test_attr_spans); - }, - }; + let mut parser = + match new_parser_from_source_str(&psess, filename, code, StripTokens::ShebangAndFrontmatter) { + Ok(p) => p, + Err(errs) => { + errs.into_iter().for_each(Diag::cancel); + return (false, test_attr_spans); + }, + }; let mut relevant_main_found = false; let mut eligible = true; diff --git a/src/tools/rustfmt/src/parse/parser.rs b/src/tools/rustfmt/src/parse/parser.rs index 2ec8769c45f..63c6c8c99d0 100644 --- a/src/tools/rustfmt/src/parse/parser.rs +++ b/src/tools/rustfmt/src/parse/parser.rs @@ -3,6 +3,7 @@ use std::path::{Path, PathBuf}; use rustc_ast::{ast, attr}; use rustc_errors::Diag; +use rustc_parse::lexer::StripTokens; use rustc_parse::parser::Parser as RawParser; use rustc_parse::{exp, new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal}; use rustc_span::{Span, sym}; @@ -64,11 +65,14 @@ impl<'a> ParserBuilder<'a> { input: Input, ) -> Result, Vec>> { match input { - Input::File(ref file) => new_parser_from_file(psess, file, None), + Input::File(ref file) => { + new_parser_from_file(psess, file, StripTokens::ShebangAndFrontmatter, None) + } Input::Text(text) => new_parser_from_source_str( psess, rustc_span::FileName::Custom("stdin".to_owned()), text, + StripTokens::ShebangAndFrontmatter, ), } } @@ -104,8 +108,12 @@ impl<'a> Parser<'a> { span: Span, ) -> Result<(ast::AttrVec, ThinVec>, Span), ParserError> { let result = catch_unwind(AssertUnwindSafe(|| { - let mut parser = - unwrap_or_emit_fatal(new_parser_from_file(psess.inner(), path, Some(span))); + let mut parser = unwrap_or_emit_fatal(new_parser_from_file( + psess.inner(), + path, + StripTokens::ShebangAndFrontmatter, + Some(span), + )); match parser.parse_mod(exp!(Eof)) { Ok((a, i, spans)) => Some((a, i, spans.inner_span)), Err(e) => { diff --git a/tests/ui-fulldeps/auxiliary/parser.rs b/tests/ui-fulldeps/auxiliary/parser.rs index 6726969350d..6ee39e5130f 100644 --- a/tests/ui-fulldeps/auxiliary/parser.rs +++ b/tests/ui-fulldeps/auxiliary/parser.rs @@ -10,7 +10,7 @@ extern crate rustc_span; use rustc_ast::ast::{AttrKind, Attribute, DUMMY_NODE_ID, Expr}; use rustc_ast::mut_visit::{self, MutVisitor}; use rustc_ast::node_id::NodeId; -use rustc_ast::token::{self, Token}; +use rustc_ast::token; use rustc_ast::tokenstream::{AttrTokenStream, AttrTokenTree, LazyAttrTokenStream}; use rustc_errors::Diag; use rustc_parse::parser::Recovery; @@ -23,6 +23,7 @@ pub fn parse_expr(psess: &ParseSess, source_code: &str) -> Option> { psess, FileName::anon_source_code(source_code), source_code.to_owned(), + rustc_parse::lexer::StripTokens::Nothing, )); let mut parser = parser.recovery(Recovery::Forbidden); diff --git a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs index 99cb5fc5aa1..df5f29e35fe 100644 --- a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs +++ b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs @@ -16,7 +16,7 @@ extern crate rustc_span; #[allow(unused_extern_crates)] extern crate rustc_driver; -use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal}; +use rustc_parse::{lexer::StripTokens, new_parser_from_file, unwrap_or_emit_fatal}; use rustc_session::parse::ParseSess; use std::path::Path; @@ -34,6 +34,11 @@ fn parse() { let path = Path::new(file!()); let path = path.canonicalize().unwrap(); - let mut parser = unwrap_or_emit_fatal(new_parser_from_file(&psess, &path, None)); + let mut parser = unwrap_or_emit_fatal(new_parser_from_file( + &psess, + &path, + StripTokens::ShebangAndFrontmatter, + None, + )); let _ = parser.parse_crate_mod(); } diff --git a/tests/ui/frontmatter/auxiliary/expr.rs b/tests/ui/frontmatter/auxiliary/expr.rs new file mode 100644 index 00000000000..5f694110666 --- /dev/null +++ b/tests/ui/frontmatter/auxiliary/expr.rs @@ -0,0 +1,4 @@ +--- +- +--- +1 diff --git a/tests/ui/frontmatter/auxiliary/makro.rs b/tests/ui/frontmatter/auxiliary/makro.rs index 70707b27bff..1d64fa44bd3 100644 --- a/tests/ui/frontmatter/auxiliary/makro.rs +++ b/tests/ui/frontmatter/auxiliary/makro.rs @@ -1,8 +1,20 @@ extern crate proc_macro; -use proc_macro::TokenStream; +use proc_macro::{Literal, TokenStream}; #[proc_macro] pub fn check(_: TokenStream) -> TokenStream { + // In the following test cases, the `---` may look like the start of frontmatter but it is not! + // That's because it would be backward incompatible to interpret them as such in the latest + // stable edition. That's not only the case due to the feature gate error but also due to the + // fact that we "eagerly" emit errors on malformed frontmatter. + + // issue: + _ = "---".parse::(); + // Just a sequence of regular Rust punctuation tokens. assert_eq!(6, "---\n---".parse::().unwrap().into_iter().count()); + + // issue: + assert!("---".parse::().is_err()); + Default::default() } diff --git a/tests/ui/frontmatter/include-in-expr-ctxt.rs b/tests/ui/frontmatter/include-in-expr-ctxt.rs new file mode 100644 index 00000000000..7b02c9cb8a5 --- /dev/null +++ b/tests/ui/frontmatter/include-in-expr-ctxt.rs @@ -0,0 +1,9 @@ +// Check that an expr-ctxt `include` doesn't try to parse frontmatter and instead +// treats it as a regular Rust token sequence. +//@ check-pass +#![expect(double_negations)] + +fn main() { + // issue: + const _: () = assert!(-1 == include!("auxiliary/expr.rs")); +} diff --git a/tests/ui/frontmatter/include-in-item-ctxt.rs b/tests/ui/frontmatter/include-in-item-ctxt.rs new file mode 100644 index 00000000000..c8455bc49ab --- /dev/null +++ b/tests/ui/frontmatter/include-in-item-ctxt.rs @@ -0,0 +1,10 @@ +// Ensure that in item ctxts we can `include` files that contain frontmatter. +//@ check-pass + +#![feature(frontmatter)] + +include!("auxiliary/lib.rs"); + +fn main() { + foo(1); +} diff --git a/tests/ui/frontmatter/included-frontmatter.rs b/tests/ui/frontmatter/included-frontmatter.rs deleted file mode 100644 index 57616cd1228..00000000000 --- a/tests/ui/frontmatter/included-frontmatter.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![feature(frontmatter)] - -//@ check-pass - -include!("auxiliary/lib.rs"); - -// auxiliary/lib.rs contains a frontmatter. Ensure that we can use them in an -// `include!` macro. - -fn main() { - foo(1); -} diff --git a/tests/ui/frontmatter/proc-macro-observer.rs b/tests/ui/frontmatter/proc-macro-observer.rs index b1cc1460933..6c4c8c57289 100644 --- a/tests/ui/frontmatter/proc-macro-observer.rs +++ b/tests/ui/frontmatter/proc-macro-observer.rs @@ -2,10 +2,9 @@ //@ proc-macro: makro.rs //@ edition: 2021 -makro::check!(); +// Check that a proc-macro doesn't try to parse frontmatter and instead treats +// it as a regular Rust token sequence. See `auxiliary/makro.rs` for details. -// checks that a proc-macro doesn't know or parse frontmatters at all and instead treats -// it as normal Rust code. -// see auxiliary/makro.rs for how it is tested. +makro::check!(); fn main() {} -- cgit 1.4.1-3-g733a5 From cbacd00f106778830803ad2e2364518f06ff9078 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 7 Jun 2025 22:56:22 +0200 Subject: allow `#[rustc_align_static(N)]` on `static`s We need a different attribute than `rustc_align` because unstable attributes are tied to their feature (we can't have two unstable features use the same unstable attribute). Otherwise this uses all of the same infrastructure as `#[rustc_align]`. --- .../src/attributes/codegen_attrs.rs | 1 + compiler/rustc_attr_parsing/src/attributes/repr.rs | 27 +++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 3 +- compiler/rustc_codegen_gcc/src/consts.rs | 2 + compiler/rustc_codegen_llvm/src/consts.rs | 2 + compiler/rustc_const_eval/src/interpret/memory.rs | 1 + compiler/rustc_const_eval/src/interpret/util.rs | 11 +++++- compiler/rustc_feature/src/builtin_attrs.rs | 1 + compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_middle/src/mir/interpret/mod.rs | 11 +++++- compiler/rustc_passes/messages.ftl | 4 ++ compiler/rustc_passes/src/check_attr.rs | 8 +++- compiler/rustc_passes/src/errors.rs | 9 +++++ compiler/rustc_span/src/symbol.rs | 2 + src/tools/miri/tests/pass/static_align.rs | 14 +++++++ tests/codegen-llvm/align-static.rs | 31 +++++++++++++++ tests/ui/attributes/malformed-static-align.rs | 17 ++++++++ tests/ui/attributes/malformed-static-align.stderr | 45 ++++++++++++++++++++++ .../ui/feature-gates/feature-gate-static_align.rs | 11 ++++++ .../feature-gates/feature-gate-static_align.stderr | 23 +++++++++++ tests/ui/static/static-align.rs | 26 +++++++++++++ 21 files changed, 246 insertions(+), 5 deletions(-) create mode 100644 src/tools/miri/tests/pass/static_align.rs create mode 100644 tests/codegen-llvm/align-static.rs create mode 100644 tests/ui/attributes/malformed-static-align.rs create mode 100644 tests/ui/attributes/malformed-static-align.stderr create mode 100644 tests/ui/feature-gates/feature-gate-static_align.rs create mode 100644 tests/ui/feature-gates/feature-gate-static_align.stderr create mode 100644 tests/ui/static/static-align.rs (limited to 'src') diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index ffdacff7152..d5d51f2e79a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -218,6 +218,7 @@ impl AttributeParser for NakedParser { sym::rustc_std_internal_symbol, // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity sym::rustc_align, + sym::rustc_align_static, // obviously compatible with self sym::naked, // documentation diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index 23aabd15597..0330e2515c7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -331,3 +331,30 @@ impl AttributeParser for AlignParser { Some(AttributeKind::Align { align, span }) } } + +#[derive(Default)] +pub(crate) struct AlignStaticParser(AlignParser); + +impl AlignStaticParser { + const PATH: &'static [Symbol] = &[sym::rustc_align_static]; + const TEMPLATE: AttributeTemplate = AlignParser::TEMPLATE; + + fn parse<'c, S: Stage>( + &mut self, + cx: &'c mut AcceptContext<'_, '_, S>, + args: &'c ArgParser<'_>, + ) { + self.0.parse(cx, args) + } +} + +impl AttributeParser for AlignStaticParser { + const ATTRIBUTES: AcceptMapping = &[(Self::PATH, Self::TEMPLATE, Self::parse)]; + const ALLOWED_TARGETS: AllowedTargets = + AllowedTargets::AllowList(&[Allow(Target::Static), Allow(Target::ForeignStatic)]); + + fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option { + let (align, span) = self.0.0?; + Some(AttributeKind::Align { align, span }) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 7f5b810f244..1fb0660f534 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -47,7 +47,7 @@ use crate::attributes::proc_macro_attrs::{ ProcMacroAttributeParser, ProcMacroDeriveParser, ProcMacroParser, RustcBuiltinMacroParser, }; use crate::attributes::prototype::CustomMirParser; -use crate::attributes::repr::{AlignParser, ReprParser}; +use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart, RustcObjectLifetimeDefaultParser, @@ -149,6 +149,7 @@ attribute_parsers!( pub(crate) static ATTRIBUTE_PARSERS = [ // tidy-alphabetical-start AlignParser, + AlignStaticParser, BodyStabilityParser, ConfusablesParser, ConstStabilityParser, diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index 619277eba8b..7fe8fc122b3 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -81,6 +81,8 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> { if global.to_rvalue().get_type() != val_llty { global.to_rvalue().set_type(val_llty); } + + // NOTE: Alignment from attributes has already been applied to the allocation. set_global_alignment(self, global, alloc.align); global.global_set_initializer_rvalue(value); diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 9ec7b0f80ae..dc9bb743560 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -452,6 +452,8 @@ impl<'ll> CodegenCx<'ll, '_> { self.statics_to_rauw.borrow_mut().push((g, new_g)); new_g }; + + // NOTE: Alignment from attributes has already been applied to the allocation. set_global_alignment(self, g, alloc.align); llvm::set_initializer(g, v); diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 2c1e5087e1c..67e1f6b2fbd 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -953,6 +953,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // # Global allocations if let Some(global_alloc) = self.tcx.try_get_global_alloc(id) { + // NOTE: `static` alignment from attributes has already been applied to the allocation. let (size, align) = global_alloc.size_and_align(*self.tcx, self.typing_env); let mutbl = global_alloc.mutability(*self.tcx, self.typing_env); let kind = match global_alloc { diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index 72bee345406..f667823723c 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -1,6 +1,6 @@ use rustc_hir::def_id::LocalDefId; use rustc_middle::mir; -use rustc_middle::mir::interpret::{AllocInit, Allocation, InterpResult, Pointer}; +use rustc_middle::mir::interpret::{AllocInit, Allocation, GlobalAlloc, InterpResult, Pointer}; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::{TyCtxt, TypeVisitable, TypeVisitableExt}; use tracing::debug; @@ -38,7 +38,14 @@ pub(crate) fn create_static_alloc<'tcx>( static_def_id: LocalDefId, layout: TyAndLayout<'tcx>, ) -> InterpResult<'tcx, MPlaceTy<'tcx>> { - let alloc = Allocation::try_new(layout.size, layout.align.abi, AllocInit::Uninit, ())?; + // Inherit size and align from the `GlobalAlloc::Static` so we can avoid duplicating + // the alignment attribute logic. + let (size, align) = + GlobalAlloc::Static(static_def_id.into()).size_and_align(*ecx.tcx, ecx.typing_env); + assert_eq!(size, layout.size); + assert!(align >= layout.align.abi); + + let alloc = Allocation::try_new(size, align, AllocInit::Uninit, ())?; let alloc_id = ecx.tcx.reserve_and_set_static_alloc(static_def_id.into()); assert_eq!(ecx.machine.static_root_ids, None); ecx.machine.static_root_ids = Some((alloc_id, static_def_id)); diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index e81003b1897..129ab7eccb5 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -621,6 +621,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity gated!(rustc_align, Normal, template!(List: &["alignment"]), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(rustc_align)), + gated!(rustc_align_static, Normal, template!(List: &["alignment"]), DuplicatesOk, EncodeCrossCrate::No, static_align, experimental!(rustc_align_static)), ungated!( unsafe(Edition2024) export_name, Normal, template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute"), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 4f35bf63a1a..93e5588146e 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -632,6 +632,8 @@ declare_features! ( (unstable, simd_ffi, "1.0.0", Some(27731)), /// Allows specialization of implementations (RFC 1210). (incomplete, specialization, "1.7.0", Some(31844)), + /// Allows using `#[rustc_align_static(...)]` on static items. + (unstable, static_align, "CURRENT_RUSTC_VERSION", Some(146177)), /// Allows attributes on expressions and non-item statements. (unstable, stmt_expr_attributes, "1.6.0", Some(15701)), /// Allows lints part of the strict provenance effort. diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index bed99a4ff2a..9762e0f21da 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -386,7 +386,16 @@ impl<'tcx> GlobalAlloc<'tcx> { .expect("statics should not have generic parameters"); let layout = tcx.layout_of(typing_env.as_query_input(ty)).unwrap(); assert!(layout.is_sized()); - (layout.size, layout.align.abi) + + // Take over-alignment from attributes into account. + let align = match tcx.codegen_fn_attrs(def_id).alignment { + Some(align_from_attribute) => { + Ord::max(align_from_attribute, layout.align.abi) + } + None => layout.align.abi, + }; + + (layout.size, align) } } GlobalAlloc::Memory(alloc) => { diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index afd08319738..ab7885905a6 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -501,6 +501,10 @@ passes_repr_align_should_be_align = `#[repr(align(...))]` is not supported on {$item} .help = use `#[rustc_align(...)]` instead +passes_repr_align_should_be_align_static = + `#[repr(align(...))]` is not supported on {$item} + .help = use `#[rustc_align_static(...)]` instead + passes_repr_conflicting = conflicting representation hints diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2cd4830b5d9..10585e7b920 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1602,12 +1602,18 @@ impl<'tcx> CheckAttrVisitor<'tcx> { ReprAttr::ReprAlign(align) => { match target { Target::Struct | Target::Union | Target::Enum => {} - Target::Fn | Target::Method(_) => { + Target::Fn | Target::Method(_) if self.tcx.features().fn_align() => { self.dcx().emit_err(errors::ReprAlignShouldBeAlign { span: *repr_span, item: target.plural_name(), }); } + Target::Static if self.tcx.features().static_align() => { + self.dcx().emit_err(errors::ReprAlignShouldBeAlignStatic { + span: *repr_span, + item: target.plural_name(), + }); + } _ => { self.dcx().emit_err(errors::AttrApplication::StructEnumUnion { hint_span: *repr_span, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 23dcabef1a1..2da4b6f52cf 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1609,6 +1609,15 @@ pub(crate) struct ReprAlignShouldBeAlign { pub item: &'static str, } +#[derive(Diagnostic)] +#[diag(passes_repr_align_should_be_align_static)] +pub(crate) struct ReprAlignShouldBeAlignStatic { + #[primary_span] + #[help] + pub span: Span, + pub item: &'static str, +} + #[derive(Diagnostic)] #[diag(passes_custom_mir_phase_requires_dialect)] pub(crate) struct CustomMirPhaseRequiresDialect { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index e5108d8b7e9..ac933b20608 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1846,6 +1846,7 @@ symbols! { rustc_abi, // FIXME(#82232, #143834): temporary name to mitigate `#[align]` nameres ambiguity rustc_align, + rustc_align_static, rustc_allocator, rustc_allocator_zeroed, rustc_allocator_zeroed_variant, @@ -2097,6 +2098,7 @@ symbols! { staged_api, start, state, + static_align, static_in_const, static_nobundle, static_recursion, diff --git a/src/tools/miri/tests/pass/static_align.rs b/src/tools/miri/tests/pass/static_align.rs new file mode 100644 index 00000000000..f292f028568 --- /dev/null +++ b/src/tools/miri/tests/pass/static_align.rs @@ -0,0 +1,14 @@ +#![feature(static_align)] + +// When a static uses `align(N)`, its address should be a multiple of `N`. + +#[rustc_align_static(256)] +static FOO: u64 = 0; + +#[rustc_align_static(512)] +static BAR: u64 = 0; + +fn main() { + assert!(core::ptr::from_ref(&FOO).addr().is_multiple_of(256)); + assert!(core::ptr::from_ref(&BAR).addr().is_multiple_of(512)); +} diff --git a/tests/codegen-llvm/align-static.rs b/tests/codegen-llvm/align-static.rs new file mode 100644 index 00000000000..53db998919a --- /dev/null +++ b/tests/codegen-llvm/align-static.rs @@ -0,0 +1,31 @@ +//@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 + +#![crate_type = "lib"] +#![feature(static_align)] + +// CHECK: @STATIC_ALIGN = +// CHECK-SAME: align 16 +#[no_mangle] +#[rustc_align_static(16)] +pub static STATIC_ALIGN: u64 = 0; + +// CHECK: @ALIGN_SPECIFIED_TWICE_1 = +// CHECK-SAME: align 64 +#[no_mangle] +#[rustc_align_static(32)] +#[rustc_align_static(64)] +pub static ALIGN_SPECIFIED_TWICE_1: u64 = 0; + +// CHECK: @ALIGN_SPECIFIED_TWICE_2 = +// CHECK-SAME: align 128 +#[no_mangle] +#[rustc_align_static(128)] +#[rustc_align_static(32)] +pub static ALIGN_SPECIFIED_TWICE_2: u64 = 0; + +// CHECK: @ALIGN_SPECIFIED_TWICE_3 = +// CHECK-SAME: align 256 +#[no_mangle] +#[rustc_align_static(32)] +#[rustc_align_static(256)] +pub static ALIGN_SPECIFIED_TWICE_3: u64 = 0; diff --git a/tests/ui/attributes/malformed-static-align.rs b/tests/ui/attributes/malformed-static-align.rs new file mode 100644 index 00000000000..305d8acf8af --- /dev/null +++ b/tests/ui/attributes/malformed-static-align.rs @@ -0,0 +1,17 @@ +#![feature(static_align)] +#![crate_type = "lib"] + +#[rustc_align_static = 16] //~ ERROR malformed `rustc_align_static` attribute input +static S1: () = (); + +#[rustc_align_static("hello")] //~ ERROR invalid alignment value: not an unsuffixed integer +static S2: () = (); + +#[rustc_align_static(0)] //~ ERROR invalid alignment value: not a power of two +static S3: () = (); + +#[repr(align(16))] //~ ERROR `#[repr(align(...))]` is not supported on static +static S4: () = (); + +#[rustc_align_static(16)] //~ ERROR `#[rustc_align_static]` attribute cannot be used on structs +struct Struct1; diff --git a/tests/ui/attributes/malformed-static-align.stderr b/tests/ui/attributes/malformed-static-align.stderr new file mode 100644 index 00000000000..35f654d3990 --- /dev/null +++ b/tests/ui/attributes/malformed-static-align.stderr @@ -0,0 +1,45 @@ +error[E0539]: malformed `rustc_align_static` attribute input + --> $DIR/malformed-static-align.rs:4:1 + | +LL | #[rustc_align_static = 16] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[rustc_align_static()]` + +error[E0589]: invalid alignment value: not an unsuffixed integer + --> $DIR/malformed-static-align.rs:7:22 + | +LL | #[rustc_align_static("hello")] + | ^^^^^^^ + +error[E0589]: invalid alignment value: not a power of two + --> $DIR/malformed-static-align.rs:10:22 + | +LL | #[rustc_align_static(0)] + | ^ + +error: `#[rustc_align_static]` attribute cannot be used on structs + --> $DIR/malformed-static-align.rs:16:1 + | +LL | #[rustc_align_static(16)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_align_static]` can be applied to statics and foreign statics + +error: `#[repr(align(...))]` is not supported on statics + --> $DIR/malformed-static-align.rs:13:8 + | +LL | #[repr(align(16))] + | ^^^^^^^^^ + | +help: use `#[rustc_align_static(...)]` instead + --> $DIR/malformed-static-align.rs:13:8 + | +LL | #[repr(align(16))] + | ^^^^^^^^^ + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0539, E0589. +For more information about an error, try `rustc --explain E0539`. diff --git a/tests/ui/feature-gates/feature-gate-static_align.rs b/tests/ui/feature-gates/feature-gate-static_align.rs new file mode 100644 index 00000000000..4d8f0e18d94 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-static_align.rs @@ -0,0 +1,11 @@ +#![crate_type = "lib"] + +#[rustc_align_static(16)] +//~^ ERROR the `#[rustc_align_static]` attribute is an experimental feature +static REQUIRES_ALIGNMENT: u64 = 0; + +extern "C" { + #[rustc_align_static(16)] + //~^ ERROR the `#[rustc_align_static]` attribute is an experimental feature + static FOREIGN_STATIC: u32; +} diff --git a/tests/ui/feature-gates/feature-gate-static_align.stderr b/tests/ui/feature-gates/feature-gate-static_align.stderr new file mode 100644 index 00000000000..b45fcdefc9c --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-static_align.stderr @@ -0,0 +1,23 @@ +error[E0658]: the `#[rustc_align_static]` attribute is an experimental feature + --> $DIR/feature-gate-static_align.rs:3:1 + | +LL | #[rustc_align_static(16)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #146177 for more information + = help: add `#![feature(static_align)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the `#[rustc_align_static]` attribute is an experimental feature + --> $DIR/feature-gate-static_align.rs:8:5 + | +LL | #[rustc_align_static(16)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #146177 for more information + = help: add `#![feature(static_align)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/static/static-align.rs b/tests/ui/static/static-align.rs new file mode 100644 index 00000000000..93241db09f9 --- /dev/null +++ b/tests/ui/static/static-align.rs @@ -0,0 +1,26 @@ +//@ run-pass +#![feature(static_align)] + +#[rustc_align_static(64)] +static A: u8 = 0; + +#[rustc_align_static(64)] +static B: u8 = 0; + +#[rustc_align_static(128)] +#[no_mangle] +static EXPORTED: u64 = 0; + +unsafe extern "C" { + #[rustc_align_static(128)] + #[link_name = "EXPORTED"] + static C: u64; +} + +fn main() { + assert!(core::ptr::from_ref(&A).addr().is_multiple_of(64)); + assert!(core::ptr::from_ref(&B).addr().is_multiple_of(64)); + + assert!(core::ptr::from_ref(&EXPORTED).addr().is_multiple_of(128)); + unsafe { assert!(core::ptr::from_ref(&C).addr().is_multiple_of(128)) }; +} -- cgit 1.4.1-3-g733a5