diff options
616 files changed, 6898 insertions, 4264 deletions
diff --git a/.github/ISSUE_TEMPLATE/bootstrap.md b/.github/ISSUE_TEMPLATE/bootstrap.md index 8d72eae8593..344ea30e1fc 100644 --- a/.github/ISSUE_TEMPLATE/bootstrap.md +++ b/.github/ISSUE_TEMPLATE/bootstrap.md @@ -32,7 +32,7 @@ Describe what you expected to happen. Describe what actually happened. --> -### Bootstrap configuration (config.toml) +### Bootstrap configuration (bootstrap.toml) ```toml <config> ``` diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96c0955e871..25397006ee2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -239,16 +239,31 @@ jobs: if: github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1' - name: postprocess metrics into the summary + # This step is not critical, and if some I/O problem happens, we don't want + # to cancel the build. + continue-on-error: true run: | if [ -f build/metrics.json ]; then - ./build/citool/debug/citool postprocess-metrics build/metrics.json ${GITHUB_STEP_SUMMARY} + METRICS=build/metrics.json elif [ -f obj/build/metrics.json ]; then - ./build/citool/debug/citool postprocess-metrics obj/build/metrics.json ${GITHUB_STEP_SUMMARY} + METRICS=obj/build/metrics.json else echo "No metrics.json found" + exit 0 fi + # Get closest bors merge commit + PARENT_COMMIT=`git rev-list --author='bors <bors@rust-lang.org>' -n1 --first-parent HEAD^1` + + ./build/citool/debug/citool postprocess-metrics \ + --job-name ${CI_JOB_NAME} \ + --parent ${PARENT_COMMIT} \ + ${METRICS} >> ${GITHUB_STEP_SUMMARY} + - name: upload job metrics to DataDog + # This step is not critical, and if some I/O problem happens, we don't want + # to cancel the build. + continue-on-error: true if: needs.calculate_matrix.outputs.run_type != 'pr' env: DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }} diff --git a/.github/workflows/ghcr.yml b/.github/workflows/ghcr.yml index 052c9ae72b8..c2c0c11f008 100644 --- a/.github/workflows/ghcr.yml +++ b/.github/workflows/ghcr.yml @@ -5,6 +5,9 @@ # Docker Hub has a rate limit, while ghcr.io doesn't. # Those images are pushed to ghcr.io by this job. # +# While Docker Hub rate limit *shouldn't* be an issue on GitHub Actions, +# it certainly is for AWS codebuild. +# # Note that authenticating to DockerHub or other registries isn't possible # for PR jobs, because forks can't access secrets. # That's why we use ghcr.io: it has no rate limit and it doesn't require authentication. @@ -54,6 +57,10 @@ jobs: "ubuntu:22.04" # Mirrored because used by all linux CI jobs, including mingw-check-tidy "moby/buildkit:buildx-stable-1" + # Mirrored because used when CI is running inside a Docker container + "alpine:3.4" + # Mirrored because used by dist-x86_64-linux + "centos:7" ) # Mirror each image from DockerHub to ghcr.io diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index de31c28cc90..94553608a2f 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -35,13 +35,12 @@ jobs: cd src/ci/citool - printf "*This is an experimental post-merge analysis report. You can ignore it.*\n\n" > output.log - printf "<details>\n<summary>Post-merge report</summary>\n\n" >> output.log + printf "<details>\n<summary>What is this?</summary>\n" >> output.log + printf "This is an experimental post-merge analysis report that shows differences in test outcomes between the merged PR and its parent PR.\n" >> output.log + printf "</details>\n\n" >> output.log cargo run --release post-merge-report ${PARENT_COMMIT} ${{ github.sha }} >> output.log - printf "</details>\n" >> output.log - cat output.log gh pr comment ${HEAD_PR} -F output.log diff --git a/.gitignore b/.gitignore index b8cb31e8190..a549b6e6e56 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # This file should only ignore things that are generated during a `x.py` build, # generated by common IDEs, and optional files controlled by the user that -# affect the build (such as config.toml). +# affect the build (such as bootstrap.toml). # In particular, things like `mir_dump` should not be listed here; they are only # created during manual debugging and many people like to clean up instead of # having git ignore such leftovers. You can use `.git/info/exclude` to @@ -34,6 +34,7 @@ Session.vim !/tests/run-make/thumb-none-qemu/example/.cargo ## Configuration +/bootstrap.toml /config.toml /Makefile config.mk diff --git a/.ignore b/.ignore index 40d1513978f..b0c640fee3d 100644 --- a/.ignore +++ b/.ignore @@ -1,2 +1,3 @@ -# Make vscode *not* count `config.toml` as ignored, so it is included in search +# Make vscode *not* count `bootstrap.toml` and `config.toml` as ignored, so it is included in search +!/bootstrap.toml !/config.toml diff --git a/Cargo.lock b/Cargo.lock index b7ad2ca5ba0..1a8dea0b105 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1548,16 +1548,14 @@ dependencies = [ [[package]] name = "html5ever" -version = "0.27.0" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4" +checksum = "9b958f80f0fde8601dc6c08685adc743eecaa046181cebd5a57551468dfc2ddc" dependencies = [ "log", "mac", "markup5ever", - "proc-macro2", - "quote", - "syn 2.0.96", + "match_token", ] [[package]] @@ -2023,7 +2021,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -2134,9 +2132,9 @@ checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" [[package]] name = "markup5ever" -version = "0.12.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45" +checksum = "03a7b81dfb91586d0677086d40a6d755070e0799b71bb897485bac408dfd5c69" dependencies = [ "log", "phf", @@ -2147,6 +2145,17 @@ dependencies = [ ] [[package]] +name = "match_token" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] name = "matchers" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2180,6 +2189,20 @@ dependencies = [ ] [[package]] +name = "measureme" +version = "12.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "570a507d8948a66a97f42cbbaf8a6bb9516a51017d4ee949502ad7a10a864395" +dependencies = [ + "log", + "memmap2", + "parking_lot", + "perf-event-open-sys", + "rustc-hash 1.1.0", + "smallvec", +] + +[[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2262,7 +2285,7 @@ dependencies = [ "libc", "libffi", "libloading", - "measureme", + "measureme 11.0.1", "rand 0.9.0", "regex", "rustc_version", @@ -2628,7 +2651,7 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ - "phf_shared 0.11.3", + "phf_shared", ] [[package]] @@ -2637,18 +2660,8 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", -] - -[[package]] -name = "phf_generator" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" -dependencies = [ - "phf_shared 0.10.0", - "rand 0.8.5", + "phf_generator", + "phf_shared", ] [[package]] @@ -2657,26 +2670,17 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ - "phf_shared 0.11.3", + "phf_shared", "rand 0.8.5", ] [[package]] name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher 0.3.11", -] - -[[package]] -name = "phf_shared" version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ - "siphasher 1.0.1", + "siphasher", ] [[package]] @@ -3202,7 +3206,6 @@ dependencies = [ "rustc_data_structures", "rustc_macros", "rustc_serialize", - "rustc_span", ] [[package]] @@ -3221,7 +3224,6 @@ dependencies = [ "rustc_index", "rustc_macros", "rustc_middle", - "rustc_parse", "rustc_session", "rustc_span", "rustc_target", @@ -3256,7 +3258,6 @@ version = "0.0.0" dependencies = [ "itertools", "rustc_ast", - "rustc_data_structures", "rustc_lexer", "rustc_span", "thin-vec", @@ -3284,15 +3285,12 @@ dependencies = [ "rustc_ast", "rustc_ast_pretty", "rustc_attr_data_structures", - "rustc_data_structures", "rustc_errors", "rustc_feature", "rustc_fluent_macro", "rustc_hir", "rustc_lexer", "rustc_macros", - "rustc_middle", - "rustc_serialize", "rustc_session", "rustc_span", "thin-vec", @@ -3371,7 +3369,7 @@ dependencies = [ "gimli 0.30.0", "itertools", "libc", - "measureme", + "measureme 12.0.1", "object 0.36.7", "rustc-demangle", "rustc_abi", @@ -3419,7 +3417,6 @@ dependencies = [ "rustc_abi", "rustc_arena", "rustc_ast", - "rustc_ast_pretty", "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", @@ -3427,7 +3424,6 @@ dependencies = [ "rustc_fs_util", "rustc_hashes", "rustc_hir", - "rustc_hir_pretty", "rustc_incremental", "rustc_index", "rustc_macros", @@ -3488,7 +3484,7 @@ dependencies = [ "indexmap", "jobserver", "libc", - "measureme", + "measureme 12.0.1", "memmap2", "parking_lot", "portable-atomic", @@ -3875,7 +3871,6 @@ dependencies = [ "rustc_query_impl", "rustc_query_system", "rustc_resolve", - "rustc_serialize", "rustc_session", "rustc_span", "rustc_symbol_mangling", @@ -3950,7 +3945,6 @@ dependencies = [ name = "rustc_log" version = "0.0.0" dependencies = [ - "rustc_span", "tracing", "tracing-core", "tracing-subscriber", @@ -4039,13 +4033,11 @@ dependencies = [ name = "rustc_mir_build" version = "0.0.0" dependencies = [ - "either", "itertools", "rustc_abi", "rustc_apfloat", "rustc_arena", "rustc_ast", - "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", @@ -4250,10 +4242,8 @@ dependencies = [ name = "rustc_query_impl" version = "0.0.0" dependencies = [ - "measureme", - "rustc_attr_data_structures", + "measureme 12.0.1", "rustc_data_structures", - "rustc_errors", "rustc_hashes", "rustc_hir", "rustc_index", @@ -4262,7 +4252,6 @@ dependencies = [ "rustc_serialize", "rustc_session", "rustc_span", - "thin-vec", "tracing", ] @@ -4287,7 +4276,6 @@ dependencies = [ "rustc_session", "rustc_span", "smallvec", - "thin-vec", "tracing", ] @@ -4325,7 +4313,6 @@ version = "0.0.0" dependencies = [ "bitflags", "rustc_abi", - "rustc_ast", "rustc_data_structures", "rustc_hir", "rustc_middle", @@ -4380,7 +4367,6 @@ name = "rustc_smir" version = "0.0.0" dependencies = [ "rustc_abi", - "rustc_ast", "rustc_data_structures", "rustc_hir", "rustc_hir_pretty", @@ -4422,7 +4408,6 @@ dependencies = [ "punycode", "rustc-demangle", "rustc_abi", - "rustc_ast", "rustc_data_structures", "rustc_errors", "rustc_hashes", @@ -4517,7 +4502,6 @@ version = "0.0.0" dependencies = [ "itertools", "rustc_abi", - "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", @@ -4863,12 +4847,6 @@ checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" [[package]] name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - -[[package]] -name = "siphasher" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" @@ -4981,26 +4959,25 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "string_cache" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +checksum = "938d512196766101d333398efde81bc1f37b00cb42c2f8350e5df639f040bbbe" dependencies = [ "new_debug_unreachable", - "once_cell", "parking_lot", - "phf_shared 0.10.0", + "phf_shared", "precomputed-hash", "serde", ] [[package]] name = "string_cache_codegen" -version = "0.5.2" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" +checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", + "phf_generator", + "phf_shared", "proc-macro2", "quote", ] diff --git a/INSTALL.md b/INSTALL.md index a46d3d70093..30e08201d6d 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -6,9 +6,9 @@ If you just want to install Rust, check out the [README.md](README.md) instead.* The Rust build system uses a Python script called `x.py` to build the compiler, which manages the bootstrapping process. It lives at the root of the project. -It also uses a file named `config.toml` to determine various configuration +It also uses a file named `bootstrap.toml` to determine various configuration settings for the build. You can see a full list of options in -`config.example.toml`. +`bootstrap.example.toml`. The `x.py` command can be run directly on most Unix systems in the following format: @@ -115,7 +115,7 @@ See [the rustc-dev-guide for more info][sysllvm]. This project provides a configure script and makefile (the latter of which just invokes `x.py`). `./configure` is the recommended way to programmatically -generate a `config.toml`. `make` is not recommended (we suggest using `x.py` +generate a `bootstrap.toml`. `make` is not recommended (we suggest using `x.py` directly), but it is supported and we try not to break it unnecessarily. ```sh @@ -123,7 +123,7 @@ directly), but it is supported and we try not to break it unnecessarily. make && sudo make install ``` -`configure` generates a `config.toml` which can also be used with normal `x.py` +`configure` generates a `bootstrap.toml` which can also be used with normal `x.py` invocations. ## Building on Windows @@ -255,7 +255,7 @@ Windows build triples are: - `x86_64-pc-windows-msvc` The build triple can be specified by either specifying `--build=<triple>` when -invoking `x.py` commands, or by creating a `config.toml` file (as described in +invoking `x.py` commands, or by creating a `bootstrap.toml` file (as described in [Building on a Unix-like system](#building-on-a-unix-like-system)), and passing `--set build.build=<triple>` to `./configure`. diff --git a/README.md b/README.md index d84d96a0e91..611260470f1 100644 --- a/README.md +++ b/README.md @@ -67,11 +67,11 @@ See [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT), and trademarks and logos (the "Rust Trademarks"). If you want to use these names or brands, please read the -[media guide][media-guide]. +[Rust language trademark policy][trademark-policy]. Third-party logos may be subject to third-party copyrights and trademarks. See [Licenses][policies-licenses] for details. -[rust-foundation]: https://foundation.rust-lang.org/ -[media-guide]: https://foundation.rust-lang.org/policies/logo-policy-and-media-guide/ +[rust-foundation]: https://rustfoundation.org/ +[trademark-policy]: https://rustfoundation.org/policy/rust-trademark-policy/ [policies-licenses]: https://www.rust-lang.org/policies/licenses diff --git a/RELEASES.md b/RELEASES.md index 038d7ca639f..381b9ebc952 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -2282,7 +2282,7 @@ Compatibility Notes - [Cargo denies `CARGO_HOME` in the `[env]` configuration table. Cargo itself doesn't pick up this value, but recursive calls to cargo would, which was not intended.](https://github.com/rust-lang/cargo/pull/11644/) - [Debuginfo for build dependencies is now off if not explicitly set. This is expected to improve the overall build time.](https://github.com/rust-lang/cargo/pull/11252/) - [The Rust distribution no longer always includes rustdoc](https://github.com/rust-lang/rust/pull/106886) - If `tools = [...]` is set in config.toml, we will respect a missing rustdoc in that list. By + If `tools = [...]` is set in bootstrap.toml, we will respect a missing rustdoc in that list. By default rustdoc remains included. To retain the prior behavior explicitly add `"rustdoc"` to the list. @@ -5268,7 +5268,7 @@ related tools. - [Building `rustc` from source now uses `ninja` by default over `make`.][74922] You can continue building with `make` by setting `ninja=false` in - your `config.toml`. + your `bootstrap.toml`. - [cg_llvm: `fewer_names` in `uncached_llvm_type`][76030] - [Made `ensure_sufficient_stack()` non-generic][76680] diff --git a/REUSE.toml b/REUSE.toml index 9e873e94eff..816c6d730c8 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -22,7 +22,7 @@ path = [ "Cargo.lock", "Cargo.toml", "CODE_OF_CONDUCT.md", - "config.example.toml", + "bootstrap.example.toml", "configure", "CONTRIBUTING.md", "COPYRIGHT", diff --git a/config.example.toml b/bootstrap.example.toml index c3d2ad094ce..294d9780716 100644 --- a/config.example.toml +++ b/bootstrap.example.toml @@ -5,7 +5,7 @@ # # All options are commented out by default in this file, and they're commented # out with their default values. The build system by default looks for -# `config.toml` in the current directory of a build for build configuration, but +# `bootstrap.toml` in the current directory of a build for build configuration, but # a custom configuration file can also be specified with `--config` to the build # system. @@ -16,7 +16,7 @@ # Use different pre-set defaults than the global defaults. # # See `src/bootstrap/defaults` for more information. -# Note that this has no default value (x.py uses the defaults in `config.example.toml`). +# Note that this has no default value (x.py uses the defaults in `bootstrap.example.toml`). #profile = <none> # Keeps track of major changes made to this configuration. @@ -346,7 +346,7 @@ # Enable a build of the extended Rust tool set which is not only the compiler # but also tools such as Cargo. This will also produce "combined installers" # which are used to install Rust and Cargo together. -# The `tools` (check `config.example.toml` to see its default value) option specifies +# The `tools` (check `bootstrap.example.toml` to see its default value) option specifies # which tools should be built if `extended = true`. # # This is disabled by default. @@ -446,6 +446,10 @@ # a specific version. #ccache = false +# List of paths to exclude from the build and test processes. +# For example, exclude = ["tests/ui", "src/tools/tidy"]. +#exclude = [] + # ============================================================================= # General install configuration options # ============================================================================= diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index b159e136245..4edd0864300 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -238,6 +238,10 @@ pub trait MutVisitor: Sized { walk_ident(self, i); } + fn visit_modifiers(&mut self, m: &mut TraitBoundModifiers) { + walk_modifiers(self, m); + } + fn visit_path(&mut self, p: &mut Path) { walk_path(self, p); } @@ -1156,12 +1160,29 @@ fn walk_trait_ref<T: MutVisitor>(vis: &mut T, TraitRef { path, ref_id }: &mut Tr } fn walk_poly_trait_ref<T: MutVisitor>(vis: &mut T, p: &mut PolyTraitRef) { - let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span } = p; + let PolyTraitRef { bound_generic_params, modifiers, trait_ref, span } = p; + vis.visit_modifiers(modifiers); bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); vis.visit_trait_ref(trait_ref); vis.visit_span(span); } +fn walk_modifiers<V: MutVisitor>(vis: &mut V, m: &mut TraitBoundModifiers) { + let TraitBoundModifiers { constness, asyncness, polarity } = m; + match constness { + BoundConstness::Never => {} + BoundConstness::Always(span) | BoundConstness::Maybe(span) => vis.visit_span(span), + } + match asyncness { + BoundAsyncness::Normal => {} + BoundAsyncness::Async(span) => vis.visit_span(span), + } + match polarity { + BoundPolarity::Positive => {} + BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => vis.visit_span(span), + } +} + pub fn walk_field_def<T: MutVisitor>(visitor: &mut T, fd: &mut FieldDef) { let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _, safety, default } = fd; visitor.visit_id(id); diff --git a/compiler/rustc_ast_ir/Cargo.toml b/compiler/rustc_ast_ir/Cargo.toml index f54e9687d8c..76bdd9f7eb6 100644 --- a/compiler/rustc_ast_ir/Cargo.toml +++ b/compiler/rustc_ast_ir/Cargo.toml @@ -8,7 +8,6 @@ edition = "2024" rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_macros = { path = "../rustc_macros", optional = true } rustc_serialize = { path = "../rustc_serialize", optional = true } -rustc_span = { path = "../rustc_span", optional = true } # tidy-alphabetical-end [features] @@ -17,5 +16,4 @@ nightly = [ "dep:rustc_serialize", "dep:rustc_data_structures", "dep:rustc_macros", - "dep:rustc_span", ] diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index 2ec4f4b0555..6ac258155fe 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -20,7 +20,6 @@ rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } -rustc_parse = { path = "../rustc_parse" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index 906fb213ee7..65e5b530bbe 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -185,8 +185,6 @@ ast_lowering_underscore_expr_lhs_assign = ast_lowering_unstable_inline_assembly = inline assembly is not stable yet on this architecture ast_lowering_unstable_inline_assembly_label_operand_with_outputs = using both label and output operands for inline assembly is unstable -ast_lowering_unstable_inline_assembly_label_operands = - label operands for inline assembly are unstable ast_lowering_unstable_may_unwind = the `may_unwind` option is unstable ast_lowering_use_angle_brackets = use angle brackets instead diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 65784af92c7..af279e07acc 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -470,22 +470,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - // Feature gate checking for asm goto. + // Feature gate checking for `asm_goto_with_outputs`. if let Some((_, op_sp)) = operands.iter().find(|(op, _)| matches!(op, hir::InlineAsmOperand::Label { .. })) { - if !self.tcx.features().asm_goto() { - feature_err( - sess, - sym::asm_goto, - *op_sp, - fluent::ast_lowering_unstable_inline_assembly_label_operands, - ) - .emit(); - } - - // In addition, check if an output operand is used. - // This is gated behind an additional feature. + // Check if an output operand is used. let output_operand_used = operands.iter().any(|(op, _)| { matches!( op, diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index d1e23bf2522..26c0e7e5f82 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -164,7 +164,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { fn visit_item(&mut self, i: &'hir Item<'hir>) { debug_assert_eq!(i.owner_id, self.owner); self.with_parent(i.hir_id(), |this| { - if let ItemKind::Struct(struct_def, _) = &i.kind { + if let ItemKind::Struct(_, struct_def, _) = &i.kind { // If this is a tuple or unit-like struct, register the constructor. if let Some(ctor_hir_id) = struct_def.ctor_hir_id() { this.insert(i.span, ctor_hir_id, Node::Ctor(struct_def)); diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 9adc8bdd361..bd011d59aaa 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -111,6 +111,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { } fn lower_foreign_item(&mut self, item: &ForeignItem) { + debug_assert_ne!(item.ident.name, kw::Empty); self.with_lctx(item.id, |lctx| hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item))) } } @@ -154,14 +155,12 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> { - let mut ident = i.ident; let vis_span = self.lower_span(i.vis.span); let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); let attrs = self.lower_attrs(hir_id, &i.attrs, i.span); - let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, vis_span, &i.kind); + let kind = self.lower_item_kind(i.span, i.id, hir_id, i.ident, attrs, vis_span, &i.kind); let item = hir::Item { owner_id: hir_id.expect_owner(), - ident: self.lower_ident(ident), kind, vis_span, span: self.lower_span(i.span), @@ -174,25 +173,34 @@ impl<'hir> LoweringContext<'_, 'hir> { span: Span, id: NodeId, hir_id: hir::HirId, - ident: &mut Ident, + ident: Ident, attrs: &'hir [hir::Attribute], vis_span: Span, i: &ItemKind, ) -> hir::ItemKind<'hir> { match i { - ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(*orig_name), + ItemKind::ExternCrate(orig_name) => { + debug_assert_ne!(ident.name, kw::Empty); + let ident = self.lower_ident(ident); + hir::ItemKind::ExternCrate(*orig_name, ident) + } ItemKind::Use(use_tree) => { + debug_assert_eq!(ident.name, kw::Empty); // Start with an empty prefix. let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None }; - self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs) + self.lower_use_tree(use_tree, &prefix, id, vis_span, attrs) } ItemKind::Static(box ast::StaticItem { ty: t, safety: _, mutability: m, expr: e }) => { + debug_assert_ne!(ident.name, kw::Empty); + let ident = self.lower_ident(ident); let (ty, body_id) = self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy); - hir::ItemKind::Static(ty, *m, body_id) + hir::ItemKind::Static(ident, ty, *m, body_id) } ItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => { + debug_assert_ne!(ident.name, kw::Empty); + let ident = self.lower_ident(ident); let (generics, (ty, body_id)) = self.lower_generics( generics, id, @@ -201,7 +209,7 @@ impl<'hir> LoweringContext<'_, 'hir> { this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy) }, ); - hir::ItemKind::Const(ty, generics, body_id) + hir::ItemKind::Const(ident, ty, generics, body_id) } ItemKind::Fn(box Fn { sig: FnSig { decl, header, span: fn_sig_span }, @@ -211,6 +219,7 @@ impl<'hir> LoweringContext<'_, 'hir> { define_opaque, .. }) => { + debug_assert_ne!(ident.name, kw::Empty); self.with_new_scopes(*fn_sig_span, |this| { // Note: we don't need to change the return type from `T` to // `impl Future<Output = T>` here because lower_body @@ -238,28 +247,44 @@ impl<'hir> LoweringContext<'_, 'hir> { span: this.lower_span(*fn_sig_span), }; this.lower_define_opaque(hir_id, &define_opaque); - hir::ItemKind::Fn { sig, generics, body: body_id, has_body: body.is_some() } + let ident = this.lower_ident(ident); + hir::ItemKind::Fn { + ident, + sig, + generics, + body: body_id, + has_body: body.is_some(), + } }) } - ItemKind::Mod(_, mod_kind) => match mod_kind { - ModKind::Loaded(items, _, spans, _) => { - hir::ItemKind::Mod(self.lower_mod(items, spans)) + ItemKind::Mod(_, mod_kind) => { + debug_assert_ne!(ident.name, kw::Empty); + let ident = self.lower_ident(ident); + match mod_kind { + ModKind::Loaded(items, _, spans, _) => { + hir::ItemKind::Mod(ident, self.lower_mod(items, spans)) + } + ModKind::Unloaded => panic!("`mod` items should have been loaded by now"), } - ModKind::Unloaded => panic!("`mod` items should have been loaded by now"), - }, - ItemKind::ForeignMod(fm) => hir::ItemKind::ForeignMod { - abi: fm.abi.map_or(ExternAbi::FALLBACK, |abi| self.lower_abi(abi)), - items: self - .arena - .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))), - }, + } + ItemKind::ForeignMod(fm) => { + debug_assert_eq!(ident.name, kw::Empty); + hir::ItemKind::ForeignMod { + abi: fm.abi.map_or(ExternAbi::FALLBACK, |abi| self.lower_abi(abi)), + items: self + .arena + .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))), + } + } ItemKind::GlobalAsm(asm) => { + debug_assert_eq!(ident.name, kw::Empty); let asm = self.lower_inline_asm(span, asm); let fake_body = self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm)))); hir::ItemKind::GlobalAsm { asm, fake_body } } ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => { + debug_assert_ne!(ident.name, kw::Empty); // We lower // // type Foo = impl Trait @@ -268,6 +293,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // // type Foo = Foo1 // opaque type Foo1: Trait + let ident = self.lower_ident(ident); let mut generics = generics.clone(); add_ty_alias_where_clause(&mut generics, *where_clauses, true); let (generics, ty) = self.lower_generics( @@ -293,9 +319,11 @@ impl<'hir> LoweringContext<'_, 'hir> { ), }, ); - hir::ItemKind::TyAlias(ty, generics) + hir::ItemKind::TyAlias(ident, ty, generics) } ItemKind::Enum(enum_definition, generics) => { + debug_assert_ne!(ident.name, kw::Empty); + let ident = self.lower_ident(ident); let (generics, variants) = self.lower_generics( generics, id, @@ -306,25 +334,29 @@ impl<'hir> LoweringContext<'_, 'hir> { ) }, ); - hir::ItemKind::Enum(hir::EnumDef { variants }, generics) + hir::ItemKind::Enum(ident, hir::EnumDef { variants }, generics) } ItemKind::Struct(struct_def, generics) => { + debug_assert_ne!(ident.name, kw::Empty); + let ident = self.lower_ident(ident); let (generics, struct_def) = self.lower_generics( generics, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| this.lower_variant_data(hir_id, struct_def), ); - hir::ItemKind::Struct(struct_def, generics) + hir::ItemKind::Struct(ident, struct_def, generics) } ItemKind::Union(vdata, generics) => { + debug_assert_ne!(ident.name, kw::Empty); + let ident = self.lower_ident(ident); let (generics, vdata) = self.lower_generics( generics, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| this.lower_variant_data(hir_id, vdata), ); - hir::ItemKind::Union(vdata, generics) + hir::ItemKind::Union(ident, vdata, generics) } ItemKind::Impl(box Impl { safety, @@ -336,6 +368,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self_ty: ty, items: impl_items, }) => { + debug_assert_eq!(ident.name, kw::Empty); // Lower the "impl header" first. This ordering is important // for in-band lifetimes! Consider `'a` here: // @@ -401,6 +434,8 @@ impl<'hir> LoweringContext<'_, 'hir> { })) } ItemKind::Trait(box Trait { is_auto, safety, generics, bounds, items }) => { + debug_assert_ne!(ident.name, kw::Empty); + let ident = self.lower_ident(ident); let (generics, (safety, items, bounds)) = self.lower_generics( generics, id, @@ -417,9 +452,11 @@ impl<'hir> LoweringContext<'_, 'hir> { (safety, items, bounds) }, ); - hir::ItemKind::Trait(*is_auto, safety, generics, bounds, items) + hir::ItemKind::Trait(*is_auto, safety, ident, generics, bounds, items) } ItemKind::TraitAlias(generics, bounds) => { + debug_assert_ne!(ident.name, kw::Empty); + let ident = self.lower_ident(ident); let (generics, bounds) = self.lower_generics( generics, id, @@ -431,9 +468,11 @@ impl<'hir> LoweringContext<'_, 'hir> { ) }, ); - hir::ItemKind::TraitAlias(generics, bounds) + hir::ItemKind::TraitAlias(ident, generics, bounds) } ItemKind::MacroDef(MacroDef { body, macro_rules }) => { + debug_assert_ne!(ident.name, kw::Empty); + let ident = self.lower_ident(ident); let body = P(self.lower_delim_args(body)); let def_id = self.local_def_id(id); let def_kind = self.tcx.def_kind(def_id); @@ -444,11 +483,14 @@ impl<'hir> LoweringContext<'_, 'hir> { ); }; let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules }); - hir::ItemKind::Macro(macro_def, macro_kind) + hir::ItemKind::Macro(ident, macro_def, macro_kind) } ItemKind::Delegation(box delegation) => { + debug_assert_ne!(ident.name, kw::Empty); + let ident = self.lower_ident(ident); let delegation_results = self.lower_delegation(delegation, id); hir::ItemKind::Fn { + ident, sig: delegation_results.sig, generics: delegation_results.generics, body: delegation_results.body_id, @@ -479,7 +521,6 @@ impl<'hir> LoweringContext<'_, 'hir> { prefix: &Path, id: NodeId, vis_span: Span, - ident: &mut Ident, attrs: &'hir [hir::Attribute], ) -> hir::ItemKind<'hir> { let path = &tree.prefix; @@ -487,7 +528,7 @@ impl<'hir> LoweringContext<'_, 'hir> { match tree.kind { UseTreeKind::Simple(rename) => { - *ident = tree.ident(); + let mut ident = tree.ident(); // First, apply the prefix to the path. let mut path = Path { segments, span: path.span, tokens: None }; @@ -498,13 +539,14 @@ impl<'hir> LoweringContext<'_, 'hir> { { let _ = path.segments.pop(); if rename.is_none() { - *ident = path.segments.last().unwrap().ident; + ident = path.segments.last().unwrap().ident; } } let res = self.lower_import_res(id, path.span); let path = self.lower_use_path(res, &path, ParamMode::Explicit); - hir::ItemKind::Use(path, hir::UseKind::Single) + let ident = self.lower_ident(ident); + hir::ItemKind::Use(path, hir::UseKind::Single(ident)) } UseTreeKind::Glob => { let res = self.expect_full_res(id); @@ -551,20 +593,16 @@ impl<'hir> LoweringContext<'_, 'hir> { // own its own names, we have to adjust the owner before // lowering the rest of the import. self.with_hir_id_owner(id, |this| { - let mut ident = *ident; - // `prefix` is lowered multiple times, but in different HIR owners. // So each segment gets renewed `HirId` with the same // `ItemLocalId` and the new owner. (See `lower_node_id`) - let kind = - this.lower_use_tree(use_tree, &prefix, id, vis_span, &mut ident, attrs); + let kind = this.lower_use_tree(use_tree, &prefix, id, vis_span, attrs); if !attrs.is_empty() { this.attrs.insert(hir::ItemLocalId::ZERO, attrs); } let item = hir::Item { owner_id: hir::OwnerId { def_id: new_hir_id }, - ident: this.lower_ident(ident), kind, vis_span, span: this.lower_span(use_tree.span), @@ -604,7 +642,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ItemKind::Impl(impl_) => { self.is_in_trait_impl = impl_.of_trait.is_some(); } - hir::ItemKind::Trait(_, _, _, _, _) => {} + hir::ItemKind::Trait(..) => {} kind => { span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr()) } @@ -760,6 +798,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> { + debug_assert_ne!(i.ident.name, kw::Empty); let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id); let attrs = self.lower_attrs(hir_id, &i.attrs, i.span); let trait_item_def_id = hir_id.expect_owner(); @@ -907,6 +946,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> { + debug_assert_ne!(i.ident.name, kw::Empty); // Since `default impl` is not yet implemented, this is always true in impls. let has_value = true; let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value); @@ -1720,7 +1760,6 @@ impl<'hir> LoweringContext<'_, 'hir> { let bounds = self.lower_param_bounds(bounds, itctx); - let ident = self.lower_ident(ident); let param_span = ident.span; // Reconstruct the span of the entire predicate from the individual generic bounds. @@ -1739,6 +1778,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let def_id = self.local_def_id(id).to_def_id(); let hir_id = self.next_id(); let res = Res::Def(DefKind::TyParam, def_id); + let ident = self.lower_ident(ident); let ty_path = self.arena.alloc(hir::Path { span: param_span, res, @@ -1757,7 +1797,6 @@ impl<'hir> LoweringContext<'_, 'hir> { }) } GenericParamKind::Lifetime => { - let ident = self.lower_ident(ident); let lt_id = self.next_node_id(); let lifetime = self.new_named_lifetime(id, lt_id, ident); hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index df671cf4b86..e24b45c5b19 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1769,17 +1769,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } fn lower_lifetime(&mut self, l: &Lifetime) -> &'hir hir::Lifetime { - let ident = self.lower_ident(l.ident); - self.new_named_lifetime(l.id, l.id, ident) + self.new_named_lifetime(l.id, l.id, l.ident) } #[instrument(level = "debug", skip(self))] - fn new_named_lifetime_with_res( + fn new_named_lifetime( &mut self, id: NodeId, + new_id: NodeId, ident: Ident, - res: LifetimeRes, ) -> &'hir hir::Lifetime { + let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error); let res = match res { LifetimeRes::Param { param, .. } => hir::LifetimeName::Param(param), LifetimeRes::Fresh { param, .. } => { @@ -1789,31 +1789,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { LifetimeRes::Infer => hir::LifetimeName::Infer, LifetimeRes::Static { .. } => hir::LifetimeName::Static, LifetimeRes::Error => hir::LifetimeName::Error, - res => panic!( - "Unexpected lifetime resolution {:?} for {:?} at {:?}", - res, ident, ident.span - ), + LifetimeRes::ElidedAnchor { .. } => { + panic!("Unexpected `ElidedAnchar` {:?} at {:?}", ident, ident.span); + } }; debug!(?res); self.arena.alloc(hir::Lifetime { - hir_id: self.lower_node_id(id), + hir_id: self.lower_node_id(new_id), ident: self.lower_ident(ident), res, }) } - #[instrument(level = "debug", skip(self))] - fn new_named_lifetime( - &mut self, - id: NodeId, - new_id: NodeId, - ident: Ident, - ) -> &'hir hir::Lifetime { - let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error); - self.new_named_lifetime_with_res(new_id, ident, res) - } - fn lower_generic_params_mut( &mut self, params: &[GenericParam], diff --git a/compiler/rustc_ast_pretty/Cargo.toml b/compiler/rustc_ast_pretty/Cargo.toml index 2634dd1fdf9..b704040be96 100644 --- a/compiler/rustc_ast_pretty/Cargo.toml +++ b/compiler/rustc_ast_pretty/Cargo.toml @@ -7,8 +7,11 @@ edition = "2024" # tidy-alphabetical-start itertools = "0.12" rustc_ast = { path = "../rustc_ast" } -rustc_data_structures = { path = "../rustc_data_structures" } rustc_lexer = { path = "../rustc_lexer" } rustc_span = { path = "../rustc_span" } +# tidy-alphabetical-end + +[dev-dependencies] +# tidy-alphabetical-start thin-vec = "0.2.12" # tidy-alphabetical-end diff --git a/compiler/rustc_attr_parsing/Cargo.toml b/compiler/rustc_attr_parsing/Cargo.toml index 6b4ce957630..32029137268 100644 --- a/compiler/rustc_attr_parsing/Cargo.toml +++ b/compiler/rustc_attr_parsing/Cargo.toml @@ -9,15 +9,12 @@ rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_attr_data_structures = { path = "../rustc_attr_data_structures" } -rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } -rustc_middle = { path = "../rustc_middle" } -rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } thin-vec = "0.2.12" diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 3951b467961..fddddf404db 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -691,7 +691,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { true, td.is_local(), td.as_local().and_then(|tld| match self.infcx.tcx.hir_node_by_def_id(tld) { - Node::Item(hir::Item { kind: hir::ItemKind::Trait(_, _, _, _, items), .. }) => { + Node::Item(hir::Item { + kind: hir::ItemKind::Trait(_, _, _, _, _, items), .. + }) => { let mut f_in_trait_opt = None; for hir::TraitItemRef { id: fi, kind: k, .. } in *items { let hi = fi.hir_id(); @@ -980,7 +982,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let arg = match tcx.hir_get_if_local(callee_def_id) { Some( hir::Node::Item(hir::Item { - ident, kind: hir::ItemKind::Fn { sig, .. }, .. + kind: hir::ItemKind::Fn { ident, sig, .. }, .. }) | hir::Node::TraitItem(hir::TraitItem { ident, @@ -1021,7 +1023,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // return type. match tcx.hir_node_by_def_id(tcx.hir_get_parent_item(fn_call_id).def_id) { hir::Node::Item(hir::Item { - ident, kind: hir::ItemKind::Fn { sig, .. }, .. + kind: hir::ItemKind::Fn { ident, sig, .. }, .. }) | hir::Node::TraitItem(hir::TraitItem { ident, @@ -1632,8 +1634,8 @@ fn get_mut_span_in_struct_field<'tcx>( /// If possible, suggest replacing `ref` with `ref mut`. fn suggest_ref_mut(tcx: TyCtxt<'_>, span: Span) -> Option<Span> { let pattern_str = tcx.sess.source_map().span_to_snippet(span).ok()?; - if pattern_str.starts_with("ref") - && pattern_str["ref".len()..].starts_with(rustc_lexer::is_whitespace) + if let Some(rest) = pattern_str.strip_prefix("ref") + && rest.starts_with(rustc_lexer::is_whitespace) { let span = span.with_lo(span.lo() + BytePos(4)).shrink_to_lo(); Some(span) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 07b3f3477a8..ed95545dea4 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2479,19 +2479,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { let body = self.body; for local in body.mut_vars_and_args_iter().filter(|local| !self.used_mut.contains(local)) { let local_decl = &body.local_decls[local]; - let lint_root = match &body.source_scopes[local_decl.source_info.scope].local_data { - ClearCrossCrate::Set(data) => data.lint_root, - _ => continue, + let ClearCrossCrate::Set(SourceScopeLocalData { lint_root, .. }) = + body.source_scopes[local_decl.source_info.scope].local_data + else { + continue; }; // Skip over locals that begin with an underscore or have no name - match self.local_names[local] { - Some(name) => { - if name.as_str().starts_with('_') { - continue; - } - } - None => continue, + if self.local_names[local].is_none_or(|name| name.as_str().starts_with('_')) { + continue; } let span = local_decl.source_info.span; diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index dab3053d8b0..606e85577f7 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -23,6 +23,8 @@ extern crate proc_macro; +use std::sync::Arc; + use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind}; use rustc_expand::proc_macro::BangProcMacro; use rustc_span::sym; @@ -67,13 +69,13 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" } pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { let mut register = |name, kind| resolver.register_builtin_macro(name, kind); macro register_bang($($name:ident: $f:expr,)*) { - $(register(sym::$name, SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)));)* + $(register(sym::$name, SyntaxExtensionKind::LegacyBang(Arc::new($f as MacroExpanderFn)));)* } macro register_attr($($name:ident: $f:expr,)*) { - $(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Box::new($f)));)* + $(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Arc::new($f)));)* } macro register_derive($($name:ident: $f:expr,)*) { - $(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f))));)* + $(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Arc::new(BuiltinDerive($f))));)* } register_bang! { @@ -139,9 +141,9 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { } let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote); - register(sym::quote, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client }))); - let requires = SyntaxExtensionKind::Attr(Box::new(contracts::ExpandRequires)); + register(sym::quote, SyntaxExtensionKind::Bang(Arc::new(BangProcMacro { client }))); + let requires = SyntaxExtensionKind::Attr(Arc::new(contracts::ExpandRequires)); register(sym::contracts_requires, requires); - let ensures = SyntaxExtensionKind::Attr(Box::new(contracts::ExpandEnsures)); + let ensures = SyntaxExtensionKind::Attr(Arc::new(contracts::ExpandEnsures)); register(sym::contracts_ensures, ensures); } diff --git a/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch b/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch index 3c81b04c0ea..d7e3b11127c 100644 --- a/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch +++ b/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch @@ -1,4 +1,4 @@ -From ad7ffe71baba46865f2e65266ab025920dfdc20b Mon Sep 17 00:00:00 2001 +From 5d7c709608b01301d4628d2159265936d4440b67 Mon Sep 17 00:00:00 2001 From: bjorn3 <bjorn3@users.noreply.github.com> Date: Thu, 18 Feb 2021 18:45:28 +0100 Subject: [PATCH] Disable 128bit atomic operations @@ -7,11 +7,10 @@ Cranelift doesn't support them yet --- library/core/src/panic/unwind_safe.rs | 6 ----- library/core/src/sync/atomic.rs | 38 --------------------------- - library/core/tests/atomic.rs | 4 --- - 4 files changed, 4 insertions(+), 50 deletions(-) + 2 files changed, 44 deletions(-) diff --git a/library/core/src/panic/unwind_safe.rs b/library/core/src/panic/unwind_safe.rs -index 092b7cf..158cf71 100644 +index a60f0799c0e..af056fbf41f 100644 --- a/library/core/src/panic/unwind_safe.rs +++ b/library/core/src/panic/unwind_safe.rs @@ -216,9 +216,6 @@ impl RefUnwindSafe for crate::sync::atomic::AtomicI32 {} @@ -21,7 +20,7 @@ index 092b7cf..158cf71 100644 -#[cfg(target_has_atomic_load_store = "128")] -#[unstable(feature = "integer_atomics", issue = "99069")] -impl RefUnwindSafe for crate::sync::atomic::AtomicI128 {} - + #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")] @@ -235,9 +232,6 @@ impl RefUnwindSafe for crate::sync::atomic::AtomicU32 {} @@ -31,14 +30,14 @@ index 092b7cf..158cf71 100644 -#[cfg(target_has_atomic_load_store = "128")] -#[unstable(feature = "integer_atomics", issue = "99069")] -impl RefUnwindSafe for crate::sync::atomic::AtomicU128 {} - + #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")] diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs -index d9de37e..8293fce 100644 +index bf2b6d59f88..d5ccce03bbf 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs -@@ -2996,44 +2996,6 @@ atomic_int! { +@@ -3585,44 +3585,6 @@ pub const fn as_ptr(&self) -> *mut $int_type { 8, u64 AtomicU64 } @@ -54,7 +53,7 @@ index d9de37e..8293fce 100644 - unstable(feature = "integer_atomics", issue = "99069"), - rustc_const_unstable(feature = "integer_atomics", issue = "99069"), - rustc_const_unstable(feature = "integer_atomics", issue = "99069"), -- cfg_attr(not(test), rustc_diagnostic_item = "AtomicI128"), +- rustc_diagnostic_item = "AtomicI128", - "i128", - "#![feature(integer_atomics)]\n\n", - atomic_min, atomic_max, @@ -73,7 +72,7 @@ index d9de37e..8293fce 100644 - unstable(feature = "integer_atomics", issue = "99069"), - rustc_const_unstable(feature = "integer_atomics", issue = "99069"), - rustc_const_unstable(feature = "integer_atomics", issue = "99069"), -- cfg_attr(not(test), rustc_diagnostic_item = "AtomicU128"), +- rustc_diagnostic_item = "AtomicU128", - "u128", - "#![feature(integer_atomics)]\n\n", - atomic_umin, atomic_umax, @@ -83,7 +82,6 @@ index d9de37e..8293fce 100644 #[cfg(target_has_atomic_load_store = "ptr")] macro_rules! atomic_int_ptr_sized { - ( $($target_pointer_width:literal $align:literal)* ) => { $( --- -2.26.2.7.g19db9cfb68 +-- +2.48.1 diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs index 5e33b9d606f..9cff8a84db3 100644 --- a/compiler/rustc_codegen_cranelift/src/allocator.rs +++ b/compiler/rustc_codegen_cranelift/src/allocator.rs @@ -7,6 +7,7 @@ use rustc_ast::expand::allocator::{ }; use rustc_codegen_ssa::base::allocator_kind_for_codegen; use rustc_session::config::OomStrategy; +use rustc_symbol_mangling::mangle_internal_symbol; use crate::prelude::*; @@ -14,6 +15,7 @@ use crate::prelude::*; pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool { let Some(kind) = allocator_kind_for_codegen(tcx) else { return false }; codegen_inner( + tcx, module, kind, tcx.alloc_error_handler_kind(()).unwrap(), @@ -23,6 +25,7 @@ pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool { } fn codegen_inner( + tcx: TyCtxt<'_>, module: &mut dyn Module, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, @@ -62,8 +65,8 @@ fn codegen_inner( crate::common::create_wrapper_function( module, sig, - &global_fn_name(method.name), - &default_fn_name(method.name), + &mangle_internal_symbol(tcx, &global_fn_name(method.name)), + &mangle_internal_symbol(tcx, &default_fn_name(method.name)), ); } } @@ -76,19 +79,32 @@ fn codegen_inner( crate::common::create_wrapper_function( module, sig, - "__rust_alloc_error_handler", - &alloc_error_handler_name(alloc_error_handler_kind), + &mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), + &mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)), ); - let data_id = module.declare_data(OomStrategy::SYMBOL, Linkage::Export, false, false).unwrap(); + let data_id = module + .declare_data( + &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), + Linkage::Export, + false, + false, + ) + .unwrap(); let mut data = DataDescription::new(); data.set_align(1); let val = oom_strategy.should_panic(); data.define(Box::new([val])); module.define_data(data_id, &data).unwrap(); - let data_id = - module.declare_data(NO_ALLOC_SHIM_IS_UNSTABLE, Linkage::Export, false, false).unwrap(); + let data_id = module + .declare_data( + &mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), + Linkage::Export, + false, + false, + ) + .unwrap(); let mut data = DataDescription::new(); data.set_align(1); data.define(Box::new([0])); diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 06939beb374..ab3386a9b4c 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -26,6 +26,7 @@ extern crate rustc_index; extern crate rustc_metadata; extern crate rustc_session; extern crate rustc_span; +extern crate rustc_symbol_mangling; extern crate rustc_target; #[macro_use] extern crate tracing; diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index 416f3231a13..f4ebd42ee2d 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -8,6 +8,7 @@ use rustc_ast::expand::allocator::{ use rustc_middle::bug; use rustc_middle::ty::TyCtxt; use rustc_session::config::OomStrategy; +use rustc_symbol_mangling::mangle_internal_symbol; use crate::GccContext; #[cfg(feature = "master")] @@ -53,8 +54,8 @@ pub(crate) unsafe fn codegen( panic!("invalid allocator output") } }; - let from_name = global_fn_name(method.name); - let to_name = default_fn_name(method.name); + let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name)); + let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name)); create_wrapper_function(tcx, context, &from_name, &to_name, &types, output); } @@ -64,13 +65,13 @@ pub(crate) unsafe fn codegen( create_wrapper_function( tcx, context, - "__rust_alloc_error_handler", - alloc_error_handler_name(alloc_error_handler_kind), + &mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), + &mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)), &[usize, usize], None, ); - let name = OomStrategy::SYMBOL.to_string(); + let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL); let global = context.new_global(None, GlobalKind::Exported, i8, name); #[cfg(feature = "master")] global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc( @@ -80,7 +81,7 @@ pub(crate) unsafe fn codegen( let value = context.new_rvalue_from_int(i8, value as i32); global.global_set_initializer_rvalue(value); - let name = NO_ALLOC_SHIM_IS_UNSTABLE.to_string(); + let name = mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE); let global = context.new_global(None, GlobalKind::Exported, i8, name); #[cfg(feature = "master")] global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc( diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index d478b2af46c..bfa23174a19 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -52,6 +52,7 @@ extern crate rustc_metadata; extern crate rustc_middle; extern crate rustc_session; extern crate rustc_span; +extern crate rustc_symbol_mangling; extern crate rustc_target; // This prevents duplicating functions and statics that are already part of the host rustc process. diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index d3ce7c5a113..ec1fd4b641a 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -14,7 +14,7 @@ bitflags = "2.4.1" gimli = "0.30" itertools = "0.12" libc = "0.2" -measureme = "11" +measureme = "12.0.1" object = { version = "0.36.3", default-features = false, features = ["std", "read"] } rustc-demangle = "0.1.21" rustc_abi = { path = "../rustc_abi" } diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index e614115f64b..4a78e694979 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -7,6 +7,7 @@ use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _; use rustc_middle::bug; use rustc_middle::ty::TyCtxt; use rustc_session::config::{DebugInfo, OomStrategy}; +use rustc_symbol_mangling::mangle_internal_symbol; use crate::builder::SBuilder; use crate::declare::declare_simple_fn; @@ -53,8 +54,8 @@ pub(crate) unsafe fn codegen( } }; - let from_name = global_fn_name(method.name); - let to_name = default_fn_name(method.name); + let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name)); + let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name)); create_wrapper_function(tcx, &cx, &from_name, &to_name, &args, output, false); } @@ -64,8 +65,8 @@ pub(crate) unsafe fn codegen( create_wrapper_function( tcx, &cx, - "__rust_alloc_error_handler", - alloc_error_handler_name(alloc_error_handler_kind), + &mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), + &mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)), &[usize, usize], // size, align None, true, @@ -73,15 +74,15 @@ pub(crate) unsafe fn codegen( unsafe { // __rust_alloc_error_handler_should_panic - let name = OomStrategy::SYMBOL; - let ll_g = cx.declare_global(name, i8); + let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL); + let ll_g = cx.declare_global(&name, i8); llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility())); let val = tcx.sess.opts.unstable_opts.oom.should_panic(); let llval = llvm::LLVMConstInt(i8, val as u64, False); llvm::set_initializer(ll_g, llval); - let name = NO_ALLOC_SHIM_IS_UNSTABLE; - let ll_g = cx.declare_global(name, i8); + let name = mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE); + let ll_g = cx.declare_global(&name, i8); llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility())); let llval = llvm::LLVMConstInt(i8, 0, False); llvm::set_initializer(ll_g, llval); diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index a4e5749b3ac..62fa2884e0f 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -5,6 +5,7 @@ use rustc_abi::{ }; use rustc_codegen_ssa::common; use rustc_codegen_ssa::traits::*; +use rustc_hir::LangItem; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; @@ -12,9 +13,9 @@ use rustc_middle::mir::interpret::{ Allocation, ConstAllocation, ErrorHandled, InitChunk, Pointer, Scalar as InterpScalar, read_target_uint, }; -use rustc_middle::mir::mono::MonoItem; -use rustc_middle::ty::Instance; +use rustc_middle::mir::mono::{Linkage, MonoItem}; use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; +use rustc_middle::ty::{self, Instance}; use rustc_middle::{bug, span_bug}; use tracing::{debug, instrument, trace}; @@ -171,8 +172,27 @@ fn check_and_apply_linkage<'ll, 'tcx>( if let Some(linkage) = attrs.import_linkage { debug!("get_static: sym={} linkage={:?}", sym, linkage); - // Declare a symbol `foo` with the desired linkage. - let g1 = cx.declare_global(sym, cx.type_i8()); + // Declare a symbol `foo`. If `foo` is an extern_weak symbol, we declare + // an extern_weak function, otherwise a global with the desired linkage. + let g1 = if matches!(attrs.import_linkage, Some(Linkage::ExternalWeak)) { + // An `extern_weak` function is represented as an `Option<unsafe extern ...>`, + // we extract the function signature and declare it as an extern_weak function + // instead of an extern_weak i8. + let instance = Instance::mono(cx.tcx, def_id); + if let ty::Adt(struct_def, args) = instance.ty(cx.tcx, cx.typing_env()).kind() + && cx.tcx.is_lang_item(struct_def.did(), LangItem::Option) + && let ty::FnPtr(sig, header) = args.type_at(0).kind() + { + let fn_sig = sig.with(*header); + + let fn_abi = cx.fn_abi_of_fn_ptr(fn_sig, ty::List::empty()); + cx.declare_fn(sym, &fn_abi, None) + } else { + cx.declare_global(sym, cx.type_i8()) + } + } else { + cx.declare_global(sym, cx.type_i8()) + }; llvm::set_linkage(g1, base::linkage_to_llvm(linkage)); // Declare an internal global `extern_with_linkage_foo` which diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 9f8ec0ea526..926445c780b 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -27,6 +27,7 @@ use rustc_session::config::{ }; use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, Span}; +use rustc_symbol_mangling::mangle_internal_symbol; use rustc_target::spec::{HasTargetSpec, RelocModel, SmallDataThresholdSupport, Target, TlsModel}; use smallvec::SmallVec; @@ -1199,7 +1200,7 @@ impl<'ll> CodegenCx<'ll, '_> { Some(def_id) => self.get_static(def_id), _ => { let ty = self.type_struct(&[self.type_ptr(), self.type_ptr()], false); - self.declare_global("rust_eh_catch_typeinfo", ty) + self.declare_global(&mangle_internal_symbol(self.tcx, "rust_eh_catch_typeinfo"), ty) } }; self.eh_catch_typeinfo.set(Some(eh_catch_typeinfo)); diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs index 80e54bf045e..5b487bc1a8b 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs @@ -105,9 +105,14 @@ fn fill_region_tables<'tcx>( ids_info: &'tcx CoverageIdsInfo, covfun: &mut CovfunRecord<'tcx>, ) { - // Currently a function's mappings must all be in the same file as its body span. + // Currently a function's mappings must all be in the same file, so use the + // first mapping's span to determine the file. let source_map = tcx.sess.source_map(); - let source_file = source_map.lookup_source_file(fn_cov_info.body_span.lo()); + let Some(first_span) = (try { fn_cov_info.mappings.first()?.span }) else { + debug_assert!(false, "function has no mappings: {:?}", covfun.mangled_function_name); + return; + }; + let source_file = source_map.lookup_source_file(first_span.lo()); // Look up the global file ID for that file. let global_file_id = global_file_table.global_file_id_for_file(&source_file); @@ -118,9 +123,8 @@ fn fill_region_tables<'tcx>( let ffi::Regions { code_regions, branch_regions, mcdc_branch_regions, mcdc_decision_regions } = &mut covfun.regions; - let make_cov_span = |span: Span| { - spans::make_coverage_span(local_file_id, source_map, fn_cov_info, &source_file, span) - }; + let make_cov_span = + |span: Span| spans::make_coverage_span(local_file_id, source_map, &source_file, span); let discard_all = tcx.sess.coverage_discard_all_spans_in_codegen(); // For each counter/region pair in this function+file, convert it to a diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs index 6d1d91340c2..3193be31ada 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs @@ -1,4 +1,3 @@ -use rustc_middle::mir::coverage::FunctionCoverageInfo; use rustc_span::source_map::SourceMap; use rustc_span::{BytePos, Pos, SourceFile, Span}; use tracing::debug; @@ -19,11 +18,10 @@ use crate::coverageinfo::mapgen::LocalFileId; pub(crate) fn make_coverage_span( file_id: LocalFileId, source_map: &SourceMap, - fn_cov_info: &FunctionCoverageInfo, file: &SourceFile, span: Span, ) -> Option<ffi::CoverageSpan> { - let span = ensure_non_empty_span(source_map, fn_cov_info, span)?; + let span = ensure_non_empty_span(source_map, span)?; let lo = span.lo(); let hi = span.hi(); @@ -55,36 +53,22 @@ pub(crate) fn make_coverage_span( }) } -fn ensure_non_empty_span( - source_map: &SourceMap, - fn_cov_info: &FunctionCoverageInfo, - span: Span, -) -> Option<Span> { +fn ensure_non_empty_span(source_map: &SourceMap, span: Span) -> Option<Span> { if !span.is_empty() { return Some(span); } - let lo = span.lo(); - let hi = span.hi(); - - // The span is empty, so try to expand it to cover an adjacent '{' or '}', - // but only within the bounds of the body span. - let try_next = hi < fn_cov_info.body_span.hi(); - let try_prev = fn_cov_info.body_span.lo() < lo; - if !(try_next || try_prev) { - return None; - } - + // The span is empty, so try to enlarge it to cover an adjacent '{' or '}'. source_map .span_to_source(span, |src, start, end| try { // Adjusting span endpoints by `BytePos(1)` is normally a bug, // but in this case we have specifically checked that the character // we're skipping over is one of two specific ASCII characters, so // adjusting by exactly 1 byte is correct. - if try_next && src.as_bytes()[end] == b'{' { - Some(span.with_hi(hi + BytePos(1))) - } else if try_prev && src.as_bytes()[start - 1] == b'}' { - Some(span.with_lo(lo - BytePos(1))) + if src.as_bytes().get(end).copied() == Some(b'{') { + Some(span.with_hi(span.hi() + BytePos(1))) + } else if start > 0 && src.as_bytes()[start - 1] == b'}' { + Some(span.with_lo(span.lo() - BytePos(1))) } else { None } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 98d59f5a8ae..2eaaf127e41 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use std::fmt::{self, Write}; use std::hash::{Hash, Hasher}; use std::path::{Path, PathBuf}; +use std::sync::Arc; use std::{iter, ptr}; use libc::{c_char, c_longlong, c_uint}; @@ -38,8 +39,8 @@ use crate::debuginfo::metadata::type_map::build_type_with_children; use crate::debuginfo::utils::{WidePtrKind, wide_pointer_kind}; use crate::llvm; use crate::llvm::debuginfo::{ - DIDescriptor, DIFile, DIFlags, DILexicalBlock, DIScope, DIType, DebugEmissionKind, - DebugNameTableKind, + DIBasicType, DIBuilder, DICompositeType, DIDescriptor, DIFile, DIFlags, DILexicalBlock, + DIScope, DIType, DebugEmissionKind, DebugNameTableKind, }; use crate::value::Value; @@ -68,7 +69,8 @@ pub(super) const UNKNOWN_COLUMN_NUMBER: c_uint = 0; const NO_SCOPE_METADATA: Option<&DIScope> = None; /// A function that returns an empty list of generic parameter debuginfo nodes. -const NO_GENERICS: for<'ll> fn(&CodegenCx<'ll, '_>) -> SmallVec<&'ll DIType> = |_| SmallVec::new(); +const NO_GENERICS: for<'ll> fn(&CodegenCx<'ll, '_>) -> SmallVec<Option<&'ll DIType>> = + |_| SmallVec::new(); // SmallVec is used quite a bit in this module, so create a shorthand. // The actual number of elements is not so important. @@ -243,7 +245,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( cx, owner, addr_field_name, - (addr_field.size, addr_field.align.abi), + addr_field, layout.fields.offset(WIDE_PTR_ADDR), DIFlags::FlagZero, data_ptr_type_di_node, @@ -253,7 +255,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( cx, owner, extra_field_name, - (extra_field.size, extra_field.align.abi), + extra_field, layout.fields.offset(WIDE_PTR_EXTRA), DIFlags::FlagZero, type_di_node(cx, extra_field.ty), @@ -311,12 +313,7 @@ fn build_subroutine_type_di_node<'ll, 'tcx>( debug_context(cx).type_map.unique_id_to_di_node.borrow_mut().remove(&unique_type_id); - let fn_di_node = unsafe { - llvm::LLVMRustDIBuilderCreateSubroutineType( - DIB(cx), - create_DIArray(DIB(cx), &signature_di_nodes[..]), - ) - }; + let fn_di_node = create_subroutine_type(cx, create_DIArray(DIB(cx), &signature_di_nodes[..])); // This is actually a function pointer, so wrap it in pointer DI. let name = compute_debuginfo_type_name(cx.tcx, fn_ty, false); @@ -340,6 +337,13 @@ fn build_subroutine_type_di_node<'ll, 'tcx>( DINodeCreationResult::new(di_node, false) } +pub(super) fn create_subroutine_type<'ll>( + cx: &CodegenCx<'ll, '_>, + signature: &'ll DICompositeType, +) -> &'ll DICompositeType { + unsafe { llvm::LLVMRustDIBuilderCreateSubroutineType(DIB(cx), signature) } +} + /// Create debuginfo for `dyn SomeTrait` types. Currently these are empty structs /// we with the correct type name (e.g. "dyn SomeTrait<Foo, Item=u32> + Sync"). fn build_dyn_type_di_node<'ll, 'tcx>( @@ -487,26 +491,22 @@ pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> // FIXME(mw): Cache this via a regular UniqueTypeId instead of an extra field in the debug context. fn recursion_marker_type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> &'ll DIType { *debug_context(cx).recursion_marker_type.get_or_init(move || { - unsafe { - // The choice of type here is pretty arbitrary - - // anything reading the debuginfo for a recursive - // type is going to see *something* weird - the only - // question is what exactly it will see. - // - // FIXME: the name `<recur_type>` does not fit the naming scheme - // of other types. - // - // FIXME: it might make sense to use an actual pointer type here - // so that debuggers can show the address. - let name = "<recur_type>"; - llvm::LLVMRustDIBuilderCreateBasicType( - DIB(cx), - name.as_c_char_ptr(), - name.len(), - cx.tcx.data_layout.pointer_size.bits(), - dwarf_const::DW_ATE_unsigned, - ) - } + // The choice of type here is pretty arbitrary - + // anything reading the debuginfo for a recursive + // type is going to see *something* weird - the only + // question is what exactly it will see. + // + // FIXME: the name `<recur_type>` does not fit the naming scheme + // of other types. + // + // FIXME: it might make sense to use an actual pointer type here + // so that debuggers can show the address. + create_basic_type( + cx, + "<recur_type>", + cx.tcx.data_layout.pointer_size, + dwarf_const::DW_ATE_unsigned, + ) }) } @@ -620,42 +620,38 @@ pub(crate) fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFi let source = cx.sess().opts.unstable_opts.embed_source.then_some(()).and(source_file.src.as_ref()); - unsafe { - llvm::LLVMRustDIBuilderCreateFile( - DIB(cx), - file_name.as_c_char_ptr(), - file_name.len(), - directory.as_c_char_ptr(), - directory.len(), - hash_kind, - hash_value.as_c_char_ptr(), - hash_value.len(), - source.map_or(ptr::null(), |x| x.as_c_char_ptr()), - source.map_or(0, |x| x.len()), - ) - } + create_file(DIB(cx), &file_name, &directory, &hash_value, hash_kind, source) } } fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile { - debug_context(cx).created_files.borrow_mut().entry(None).or_insert_with(|| unsafe { - let file_name = "<unknown>"; - let directory = ""; - let hash_value = ""; + debug_context(cx).created_files.borrow_mut().entry(None).or_insert_with(|| { + create_file(DIB(cx), "<unknown>", "", "", llvm::ChecksumKind::None, None) + }) +} +fn create_file<'ll>( + builder: &DIBuilder<'ll>, + file_name: &str, + directory: &str, + hash_value: &str, + hash_kind: llvm::ChecksumKind, + source: Option<&Arc<String>>, +) -> &'ll DIFile { + unsafe { llvm::LLVMRustDIBuilderCreateFile( - DIB(cx), + builder, file_name.as_c_char_ptr(), file_name.len(), directory.as_c_char_ptr(), directory.len(), - llvm::ChecksumKind::None, + hash_kind, hash_value.as_c_char_ptr(), hash_value.len(), - ptr::null(), - 0, + source.map_or(ptr::null(), |x| x.as_c_char_ptr()), + source.map_or(0, |x| x.len()), ) - }) + } } trait MsvcBasicName { @@ -742,7 +738,7 @@ fn build_cpp_f16_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> DINodeCreation cx, float_di_node, "bits", - cx.size_and_align_of(bits_ty), + cx.layout_of(bits_ty), Size::ZERO, DIFlags::FlagZero, type_di_node(cx, bits_ty), @@ -788,15 +784,7 @@ fn build_basic_type_di_node<'ll, 'tcx>( _ => bug!("debuginfo::build_basic_type_di_node - `t` is invalid type"), }; - let ty_di_node = unsafe { - llvm::LLVMRustDIBuilderCreateBasicType( - DIB(cx), - name.as_c_char_ptr(), - name.len(), - cx.size_of(t).bits(), - encoding, - ) - }; + let ty_di_node = create_basic_type(cx, name, cx.size_of(t), encoding); if !cpp_like_debuginfo { return DINodeCreationResult::new(ty_di_node, false); @@ -824,6 +812,23 @@ fn build_basic_type_di_node<'ll, 'tcx>( DINodeCreationResult::new(typedef_di_node, false) } +fn create_basic_type<'ll, 'tcx>( + cx: &CodegenCx<'ll, 'tcx>, + name: &str, + size: Size, + encoding: u32, +) -> &'ll DIBasicType { + unsafe { + llvm::LLVMRustDIBuilderCreateBasicType( + DIB(cx), + name.as_c_char_ptr(), + name.len(), + size.bits(), + encoding, + ) + } +} + fn build_foreign_type_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>, @@ -929,17 +934,13 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>( }; unsafe { - let compile_unit_file = llvm::LLVMRustDIBuilderCreateFile( + let compile_unit_file = create_file( debug_context.builder.as_ref(), - name_in_debuginfo.as_c_char_ptr(), - name_in_debuginfo.len(), - work_dir.as_c_char_ptr(), - work_dir.len(), + &name_in_debuginfo, + &work_dir, + "", llvm::ChecksumKind::None, - ptr::null(), - 0, - ptr::null(), - 0, + None, ); let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit( @@ -971,7 +972,7 @@ fn build_field_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, owner: &'ll DIScope, name: &str, - size_and_align: (Size, Align), + layout: TyAndLayout<'tcx>, offset: Size, flags: DIFlags, type_di_node: &'ll DIType, @@ -983,6 +984,30 @@ fn build_field_di_node<'ll, 'tcx>( } else { (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER) }; + create_member_type( + cx, + owner, + name, + file_metadata, + line_number, + layout, + offset, + flags, + type_di_node, + ) +} + +fn create_member_type<'ll, 'tcx>( + cx: &CodegenCx<'ll, 'tcx>, + owner: &'ll DIScope, + name: &str, + file_metadata: &'ll DIType, + line_number: u32, + layout: TyAndLayout<'tcx>, + offset: Size, + flags: DIFlags, + type_di_node: &'ll DIType, +) -> &'ll DIType { unsafe { llvm::LLVMRustDIBuilderCreateMemberType( DIB(cx), @@ -991,8 +1016,8 @@ fn build_field_di_node<'ll, 'tcx>( name.len(), file_metadata, line_number, - size_and_align.0.bits(), - size_and_align.1.bits() as u32, + layout.size.bits(), + layout.align.abi.bits() as u32, offset.bits(), flags, type_di_node, @@ -1076,7 +1101,7 @@ fn build_struct_type_di_node<'ll, 'tcx>( cx, owner, &field_name[..], - (field_layout.size, field_layout.align.abi), + field_layout, struct_type_and_layout.fields.offset(i), visibility_di_flags(cx, f.did, adt_def.did()), type_di_node(cx, field_layout.ty), @@ -1126,7 +1151,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>( cx, closure_or_coroutine_di_node, capture_name.as_str(), - cx.size_and_align_of(up_var_ty), + cx.layout_of(up_var_ty), layout.fields.offset(index), DIFlags::FlagZero, type_di_node(cx, up_var_ty), @@ -1171,7 +1196,7 @@ fn build_tuple_type_di_node<'ll, 'tcx>( cx, tuple_di_node, &tuple_field_name(index), - cx.size_and_align_of(component_type), + cx.layout_of(component_type), tuple_type_and_layout.fields.offset(index), DIFlags::FlagZero, type_di_node(cx, component_type), @@ -1269,7 +1294,7 @@ fn build_union_type_di_node<'ll, 'tcx>( cx, owner, f.name.as_str(), - size_and_align_of(field_layout), + field_layout, Size::ZERO, DIFlags::FlagZero, type_di_node(cx, field_layout.ty), @@ -1287,32 +1312,33 @@ fn build_union_type_di_node<'ll, 'tcx>( fn build_generic_type_param_di_nodes<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, -) -> SmallVec<&'ll DIType> { +) -> SmallVec<Option<&'ll DIType>> { if let ty::Adt(def, args) = *ty.kind() { - if args.types().next().is_some() { - let generics = cx.tcx.generics_of(def.did()); - let names = get_parameter_names(cx, generics); - let template_params: SmallVec<_> = iter::zip(args, names) - .filter_map(|(kind, name)| { - kind.as_type().map(|ty| { - let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty); - let actual_type_di_node = type_di_node(cx, actual_type); - let name = name.as_str(); - unsafe { - llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( - DIB(cx), - None, - name.as_c_char_ptr(), - name.len(), - actual_type_di_node, - ) - } - }) + let generics = cx.tcx.generics_of(def.did()); + return get_template_parameters(cx, generics, args); + } + + return smallvec![]; +} + +pub(super) fn get_template_parameters<'ll, 'tcx>( + cx: &CodegenCx<'ll, 'tcx>, + generics: &ty::Generics, + args: ty::GenericArgsRef<'tcx>, +) -> SmallVec<Option<&'ll DIType>> { + if args.types().next().is_some() { + let names = get_parameter_names(cx, generics); + let template_params: SmallVec<_> = iter::zip(args, names) + .filter_map(|(kind, name)| { + kind.as_type().map(|ty| { + let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty); + let actual_type_di_node = type_di_node(cx, actual_type); + Some(cx.create_template_type_parameter(name.as_str(), actual_type_di_node)) }) - .collect(); + }) + .collect(); - return template_params; - } + return template_params; } return smallvec![]; @@ -1416,7 +1442,9 @@ fn build_vtable_type_di_node<'ll, 'tcx>( let void_pointer_ty = Ty::new_imm_ptr(tcx, tcx.types.unit); let void_pointer_type_di_node = type_di_node(cx, void_pointer_ty); let usize_di_node = type_di_node(cx, tcx.types.usize); - let (pointer_size, pointer_align) = cx.size_and_align_of(void_pointer_ty); + let pointer_layout = cx.layout_of(void_pointer_ty); + let pointer_size = pointer_layout.size; + let pointer_align = pointer_layout.align.abi; // If `usize` is not pointer-sized and -aligned then the size and alignment computations // for the vtable as a whole would be wrong. Let's make sure this holds even on weird // platforms. @@ -1472,7 +1500,7 @@ fn build_vtable_type_di_node<'ll, 'tcx>( cx, vtable_type_di_node, &field_name, - (pointer_size, pointer_align), + pointer_layout, field_offset, DIFlags::FlagZero, field_type_di_node, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs index a72e205c9b2..07075be55fa 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs @@ -17,8 +17,8 @@ use crate::debuginfo::metadata::enums::DiscrResult; use crate::debuginfo::metadata::type_map::{self, Stub, UniqueTypeId}; use crate::debuginfo::metadata::{ DINodeCreationResult, NO_GENERICS, NO_SCOPE_METADATA, SmallVec, UNKNOWN_LINE_NUMBER, - build_field_di_node, file_metadata, file_metadata_from_def_id, size_and_align_of, type_di_node, - unknown_file_metadata, visibility_di_flags, + build_field_di_node, create_member_type, file_metadata, file_metadata_from_def_id, + size_and_align_of, type_di_node, unknown_file_metadata, visibility_di_flags, }; use crate::debuginfo::utils::DIB; use crate::llvm::debuginfo::{DIFile, DIFlags, DIType}; @@ -370,9 +370,9 @@ fn build_single_variant_union_fields<'ll, 'tcx>( cx, enum_type_di_node, &variant_union_field_name(variant_index), - // NOTE: We use the size and align of the entire type, not from variant_layout + // NOTE: We use the layout of the entire type, not from variant_layout // since the later is sometimes smaller (if it has fewer fields). - size_and_align_of(enum_type_and_layout), + enum_type_and_layout, Size::ZERO, visibility_flags, variant_struct_type_wrapper_di_node, @@ -560,7 +560,7 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>( cx, wrapper_struct_type_di_node, "value", - size_and_align_of(enum_or_coroutine_type_and_layout), + enum_or_coroutine_type_and_layout, Size::ZERO, DIFlags::FlagZero, variant_struct_type_di_node, @@ -820,7 +820,6 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( .unwrap_or_else(|| (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)); let field_name = variant_union_field_name(variant_member_info.variant_index); - let (size, align) = size_and_align_of(enum_type_and_layout); let variant_struct_type_wrapper = build_variant_struct_wrapper_type_di_node( cx, @@ -840,27 +839,23 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( }, ); - // We use LLVMRustDIBuilderCreateMemberType() member type directly because + // We use create_member_type() member type directly because // the build_field_di_node() function does not support specifying a source location, // which is something that we don't do anywhere else. - unsafe { - llvm::LLVMRustDIBuilderCreateMemberType( - DIB(cx), - enum_type_di_node, - field_name.as_c_char_ptr(), - field_name.len(), - file_di_node, - line_number, - // NOTE: We use the size and align of the entire type, not from variant_layout - // since the later is sometimes smaller (if it has fewer fields). - size.bits(), - align.bits() as u32, - // Union fields are always at offset zero - Size::ZERO.bits(), - di_flags, - variant_struct_type_wrapper, - ) - } + create_member_type( + cx, + enum_type_di_node, + &field_name, + file_di_node, + line_number, + // NOTE: We use the layout of the entire type, not from variant_layout + // since the later is sometimes smaller (if it has fewer fields). + enum_type_and_layout, + // Union fields are always at offset zero + Size::ZERO, + di_flags, + variant_struct_type_wrapper, + ) })); assert_eq!( @@ -874,7 +869,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( if is_128_bits { let type_di_node = type_di_node(cx, cx.tcx.types.u64); - let size_and_align = cx.size_and_align_of(cx.tcx.types.u64); + let u64_layout = cx.layout_of(cx.tcx.types.u64); let (lo_offset, hi_offset) = match cx.tcx.data_layout.endian { Endian::Little => (0, 8), @@ -889,7 +884,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( cx, enum_type_di_node, TAG_FIELD_NAME_128_LO, - size_and_align, + u64_layout, lo_offset, di_flags, type_di_node, @@ -900,7 +895,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( cx, enum_type_di_node, TAG_FIELD_NAME_128_HI, - size_and_align, + u64_layout, hi_offset, DIFlags::FlagZero, type_di_node, @@ -911,7 +906,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( cx, enum_type_di_node, TAG_FIELD_NAME, - cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty), + enum_type_and_layout.field(cx, tag_field), enum_type_and_layout.fields.offset(tag_field), di_flags, tag_base_type_di_node, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index 9f6a5cc89e0..6792c307fdc 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -249,7 +249,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>( cx, struct_type_di_node, &field_name, - (field_layout.size, field_layout.align.abi), + field_layout, variant_layout.fields.offset(field_index), di_flags, type_di_node(cx, field_layout.ty), @@ -332,7 +332,7 @@ fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>( cx, variant_struct_type_di_node, &field_name, - cx.size_and_align_of(field_type), + cx.layout_of(field_type), variant_layout.fields.offset(field_index), DIFlags::FlagZero, type_di_node(cx, field_type), @@ -352,7 +352,7 @@ fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>( cx, variant_struct_type_di_node, upvar_name.as_str(), - cx.size_and_align_of(upvar_ty), + cx.layout_of(upvar_ty), coroutine_type_and_layout.fields.offset(index), DIFlags::FlagZero, type_di_node(cx, upvar_ty), @@ -363,6 +363,7 @@ fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>( state_specific_fields.into_iter().chain(common_fields).collect() }, + // FIXME: this is a no-op. `build_generic_type_param_di_nodes` only works for Adts. |cx| build_generic_type_param_di_nodes(cx, coroutine_type_and_layout.ty), ) .di_node diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index 187d97c54c8..bfd131cfd3d 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -13,9 +13,9 @@ use smallvec::smallvec; use crate::common::{AsCCharPtr, CodegenCx}; use crate::debuginfo::metadata::type_map::{self, Stub, StubInfo, UniqueTypeId}; use crate::debuginfo::metadata::{ - DINodeCreationResult, NO_GENERICS, SmallVec, UNKNOWN_LINE_NUMBER, file_metadata, - file_metadata_from_def_id, size_and_align_of, type_di_node, unknown_file_metadata, - visibility_di_flags, + DINodeCreationResult, NO_GENERICS, SmallVec, UNKNOWN_LINE_NUMBER, create_member_type, + file_metadata, file_metadata_from_def_id, size_and_align_of, type_di_node, + unknown_file_metadata, visibility_di_flags, }; use crate::debuginfo::utils::{DIB, create_DIArray, get_namespace_for_item}; use crate::llvm::debuginfo::{DIFile, DIFlags, DIType}; @@ -363,23 +363,22 @@ fn build_discr_member_di_node<'ll, 'tcx>( &Variants::Multiple { tag_field, .. } => { let tag_base_type = tag_base_type(cx.tcx, enum_or_coroutine_type_and_layout); - let (size, align) = cx.size_and_align_of(tag_base_type); - - unsafe { - Some(llvm::LLVMRustDIBuilderCreateMemberType( - DIB(cx), - containing_scope, - tag_name.as_c_char_ptr(), - tag_name.len(), - unknown_file_metadata(cx), - UNKNOWN_LINE_NUMBER, - size.bits(), - align.bits() as u32, - enum_or_coroutine_type_and_layout.fields.offset(tag_field).bits(), - DIFlags::FlagArtificial, - type_di_node(cx, tag_base_type), - )) - } + let ty = type_di_node(cx, tag_base_type); + let file = unknown_file_metadata(cx); + + let layout = cx.layout_of(tag_base_type); + + Some(create_member_type( + cx, + containing_scope, + &tag_name, + file, + UNKNOWN_LINE_NUMBER, + layout, + enum_or_coroutine_type_and_layout.fields.offset(tag_field), + DIFlags::FlagArtificial, + ty, + )) } } } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs index af1d503ad6a..ae2ab32ef53 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs @@ -257,7 +257,7 @@ pub(super) fn build_type_with_children<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, stub_info: StubInfo<'ll, 'tcx>, members: impl FnOnce(&CodegenCx<'ll, 'tcx>, &'ll DIType) -> SmallVec<&'ll DIType>, - generics: impl FnOnce(&CodegenCx<'ll, 'tcx>) -> SmallVec<&'ll DIType>, + generics: impl FnOnce(&CodegenCx<'ll, 'tcx>) -> SmallVec<Option<&'ll DIType>>, ) -> DINodeCreationResult<'ll> { assert_eq!(debug_context(cx).type_map.di_node_for_unique_id(stub_info.unique_type_id), None); @@ -265,8 +265,7 @@ pub(super) fn build_type_with_children<'ll, 'tcx>( let members: SmallVec<_> = members(cx, stub_info.metadata).into_iter().map(|node| Some(node)).collect(); - let generics: SmallVec<Option<&'ll DIType>> = - generics(cx).into_iter().map(|node| Some(node)).collect(); + let generics = generics(cx); if !(members.is_empty() && generics.is_empty()) { unsafe { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 10819a53b1d..ae7d080db66 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -2,10 +2,11 @@ use std::cell::{OnceCell, RefCell}; use std::ops::Range; +use std::ptr; use std::sync::Arc; -use std::{iter, ptr}; use libc::c_uint; +use metadata::create_subroutine_type; use rustc_abi::Size; use rustc_codegen_ssa::debuginfo::type_names; use rustc_codegen_ssa::mir::debuginfo::VariableKind::*; @@ -34,8 +35,8 @@ use crate::builder::Builder; use crate::common::{AsCCharPtr, CodegenCx}; use crate::llvm; use crate::llvm::debuginfo::{ - DIArray, DIBuilderBox, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, DIType, - DIVariable, + DIArray, DIBuilderBox, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, + DITemplateTypeParameter, DIType, DIVariable, }; use crate::value::Value; @@ -251,7 +252,7 @@ struct DebugLoc { col: u32, } -impl CodegenCx<'_, '_> { +impl<'ll> CodegenCx<'ll, '_> { /// Looks up debug source information about a `BytePos`. // FIXME(eddyb) rename this to better indicate it's a duplicate of // `lookup_char_pos` rather than `dbg_loc`, perhaps by making @@ -279,6 +280,22 @@ impl CodegenCx<'_, '_> { DebugLoc { file, line, col } } } + + fn create_template_type_parameter( + &self, + name: &str, + actual_type_metadata: &'ll DIType, + ) -> &'ll DITemplateTypeParameter { + unsafe { + llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( + DIB(self), + None, + name.as_c_char_ptr(), + name.len(), + actual_type_metadata, + ) + } + } } impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { @@ -325,10 +342,8 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { let loc = self.lookup_debug_loc(span.lo()); let file_metadata = file_metadata(self, &loc.file); - let function_type_metadata = unsafe { - let fn_signature = get_function_signature(self, fn_abi); - llvm::LLVMRustDIBuilderCreateSubroutineType(DIB(self), fn_signature) - }; + let function_type_metadata = + create_subroutine_type(self, get_function_signature(self, fn_abi)); let mut name = String::with_capacity(64); type_names::push_item_name(tcx, def_id, false, &mut name); @@ -471,46 +486,10 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { generics: &ty::Generics, args: GenericArgsRef<'tcx>, ) -> &'ll DIArray { - if args.types().next().is_none() { - return create_DIArray(DIB(cx), &[]); - } - - // Again, only create type information if full debuginfo is enabled - let template_params: Vec<_> = if cx.sess().opts.debuginfo == DebugInfo::Full { - let names = get_parameter_names(cx, generics); - iter::zip(args, names) - .filter_map(|(kind, name)| { - kind.as_type().map(|ty| { - let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty); - let actual_type_metadata = type_di_node(cx, actual_type); - let name = name.as_str(); - unsafe { - Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( - DIB(cx), - None, - name.as_c_char_ptr(), - name.len(), - actual_type_metadata, - )) - } - }) - }) - .collect() - } else { - vec![] - }; - + let template_params = metadata::get_template_parameters(cx, generics, args); create_DIArray(DIB(cx), &template_params) } - fn get_parameter_names(cx: &CodegenCx<'_, '_>, generics: &ty::Generics) -> Vec<Symbol> { - let mut names = generics.parent.map_or_else(Vec::new, |def_id| { - get_parameter_names(cx, cx.tcx.generics_of(def_id)) - }); - names.extend(generics.own_params.iter().map(|param| param.name)); - names - } - /// Returns a scope, plus `true` if that's a type scope for "class" methods, /// otherwise `false` for plain namespace scopes. fn get_containing_scope<'ll, 'tcx>( diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 660fc7ec4c4..67135fcc308 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -14,6 +14,7 @@ use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, GenericArgsRef, Ty}; use rustc_middle::{bug, span_bug}; use rustc_span::{Span, Symbol, sym}; +use rustc_symbol_mangling::mangle_internal_symbol; use rustc_target::callconv::{FnAbi, PassMode}; use rustc_target::spec::{HasTargetSpec, PanicStrategy}; use tracing::debug; @@ -812,7 +813,10 @@ fn codegen_msvc_try<'ll>( let type_name = bx.const_bytes(b"rust_panic\0"); let type_info = bx.const_struct(&[type_info_vtable, bx.const_null(bx.type_ptr()), type_name], false); - let tydesc = bx.declare_global("__rust_panic_type_info", bx.val_ty(type_info)); + let tydesc = bx.declare_global( + &mangle_internal_symbol(bx.tcx, "__rust_panic_type_info"), + bx.val_ty(type_info), + ); llvm::set_linkage(tydesc, llvm::Linkage::LinkOnceODRLinkage); if bx.cx.tcx.sess.target.supports_comdat() { diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index caa1db8274d..0a2f1d5bb67 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -19,7 +19,6 @@ regex = "1.4" rustc_abi = { path = "../rustc_abi" } rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } -rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } @@ -27,7 +26,6 @@ rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } -rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_incremental = { path = "../rustc_incremental" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 60af462b6b6..34c84c64070 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -389,11 +389,10 @@ impl<'a> ArchiveBuilder for ArArchiveBuilder<'a> { mut skip: Box<dyn FnMut(&str) -> bool + 'static>, ) -> io::Result<()> { let mut archive_path = archive_path.to_path_buf(); - if self.sess.target.llvm_target.contains("-apple-macosx") { - if let Some(new_archive_path) = try_extract_macho_fat_archive(self.sess, &archive_path)? - { - archive_path = new_archive_path - } + if self.sess.target.llvm_target.contains("-apple-macosx") + && let Some(new_archive_path) = try_extract_macho_fat_archive(self.sess, &archive_path)? + { + archive_path = new_archive_path } if self.src_archives.iter().any(|archive| archive.0 == archive_path) { diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index ea961f222db..74597f6263d 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -151,17 +151,17 @@ pub fn link_binary( sess.dcx().emit_artifact_notification(&out_filename, "link"); } - if sess.prof.enabled() { - if let Some(artifact_name) = out_filename.file_name() { - // Record size for self-profiling - let file_size = std::fs::metadata(&out_filename).map(|m| m.len()).unwrap_or(0); - - sess.prof.artifact_size( - "linked_artifact", - artifact_name.to_string_lossy(), - file_size, - ); - } + if sess.prof.enabled() + && let Some(artifact_name) = out_filename.file_name() + { + // Record size for self-profiling + let file_size = std::fs::metadata(&out_filename).map(|m| m.len()).unwrap_or(0); + + sess.prof.artifact_size( + "linked_artifact", + artifact_name.to_string_lossy(), + file_size, + ); } if output.is_stdout() { @@ -186,16 +186,12 @@ pub fn link_binary( let maybe_remove_temps_from_module = |preserve_objects: bool, preserve_dwarf_objects: bool, module: &CompiledModule| { - if !preserve_objects { - if let Some(ref obj) = module.object { - ensure_removed(sess.dcx(), obj); - } + if !preserve_objects && let Some(ref obj) = module.object { + ensure_removed(sess.dcx(), obj); } - if !preserve_dwarf_objects { - if let Some(ref dwo_obj) = module.dwarf_object { - ensure_removed(sess.dcx(), dwo_obj); - } + if !preserve_dwarf_objects && let Some(ref dwo_obj) = module.dwarf_object { + ensure_removed(sess.dcx(), dwo_obj); } }; @@ -1538,8 +1534,13 @@ fn print_native_static_libs( } let stem = path.file_stem().unwrap().to_str().unwrap(); // Convert library file-stem into a cc -l argument. - let prefix = if stem.starts_with("lib") && !sess.target.is_like_windows { 3 } else { 0 }; - let lib = &stem[prefix..]; + let lib = if let Some(lib) = stem.strip_prefix("lib") + && !sess.target.is_like_windows + { + lib + } else { + stem + }; let path = parent.unwrap_or_else(|| Path::new("")); if sess.target.is_like_msvc { // When producing a dll, the MSVC linker may not actually emit a @@ -2111,11 +2112,11 @@ fn add_local_crate_metadata_objects( // When linking a dynamic library, we put the metadata into a section of the // executable. This metadata is in a separate object file from the main // object file, so we link that in here. - if crate_type == CrateType::Dylib || crate_type == CrateType::ProcMacro { - if let Some(obj) = codegen_results.metadata_module.as_ref().and_then(|m| m.object.as_ref()) - { - cmd.add_object(obj); - } + if matches!(crate_type, CrateType::Dylib | CrateType::ProcMacro) + && let Some(m) = &codegen_results.metadata_module + && let Some(obj) = &m.object + { + cmd.add_object(obj); } } @@ -2131,7 +2132,7 @@ fn add_library_search_dirs( } let fallback = Some(NativeLibSearchFallback { self_contained_components, apple_sdk_root }); - walk_native_lib_search_dirs(sess, fallback, |dir, is_framework| { + let _ = walk_native_lib_search_dirs(sess, fallback, |dir, is_framework| { if is_framework { cmd.framework_path(dir); } else { @@ -2535,10 +2536,11 @@ fn add_order_independent_options( cmd.output_filename(out_filename); - if crate_type == CrateType::Executable && sess.target.is_like_windows { - if let Some(ref s) = codegen_results.crate_info.windows_subsystem { - cmd.subsystem(s); - } + if crate_type == CrateType::Executable + && sess.target.is_like_windows + && let Some(s) = &codegen_results.crate_info.windows_subsystem + { + cmd.subsystem(s); } // Try to strip as much out of the generated object by removing unused diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index a8405a2aec9..e2a59c6efb8 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -111,24 +111,22 @@ pub(crate) fn get_linker<'a>( // PATH for the child. let mut new_path = sess.get_tools_search_paths(self_contained); let mut msvc_changed_path = false; - if sess.target.is_like_msvc { - if let Some(ref tool) = msvc_tool { - cmd.args(tool.args()); - for (k, v) in tool.env() { - if k == "PATH" { - new_path.extend(env::split_paths(v)); - msvc_changed_path = true; - } else { - cmd.env(k, v); - } + if sess.target.is_like_msvc + && let Some(ref tool) = msvc_tool + { + cmd.args(tool.args()); + for (k, v) in tool.env() { + if k == "PATH" { + new_path.extend(env::split_paths(v)); + msvc_changed_path = true; + } else { + cmd.env(k, v); } } } - if !msvc_changed_path { - if let Some(path) = env::var_os("PATH") { - new_path.extend(env::split_paths(&path)); - } + if !msvc_changed_path && let Some(path) = env::var_os("PATH") { + new_path.extend(env::split_paths(&path)); } cmd.env("PATH", env::join_paths(new_path).unwrap()); diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 459f4329d6e..5c9e72ae0f1 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -1,6 +1,6 @@ use std::collections::hash_map::Entry::*; -use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE}; +use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE, global_fn_name}; use rustc_data_structures::unord::UnordMap; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId}; @@ -13,6 +13,7 @@ use rustc_middle::query::LocalCrate; use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolName, Ty, TyCtxt}; use rustc_middle::util::Providers; use rustc_session::config::{CrateType, OomStrategy}; +use rustc_symbol_mangling::mangle_internal_symbol; use rustc_target::callconv::Conv; use rustc_target::spec::{SanitizerSet, TlsModel}; use tracing::debug; @@ -219,8 +220,11 @@ fn exported_symbols_provider_local( if allocator_kind_for_codegen(tcx).is_some() { for symbol_name in ALLOCATOR_METHODS .iter() - .map(|method| format!("__rust_{}", method.name)) - .chain(["__rust_alloc_error_handler".to_string(), OomStrategy::SYMBOL.to_string()]) + .map(|method| mangle_internal_symbol(tcx, global_fn_name(method.name).as_str())) + .chain([ + mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), + mangle_internal_symbol(tcx, OomStrategy::SYMBOL), + ]) { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name)); @@ -234,8 +238,10 @@ fn exported_symbols_provider_local( )); } - let exported_symbol = - ExportedSymbol::NoDefId(SymbolName::new(tcx, NO_ALLOC_SHIM_IS_UNSTABLE)); + let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new( + tcx, + &mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), + )); symbols.push(( exported_symbol, SymbolExportInfo { diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 9cc737d194c..2ec203458a3 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -566,16 +566,13 @@ fn produce_final_output_artifacts( // Produce final compile outputs. let copy_gracefully = |from: &Path, to: &OutFileName| match to { - OutFileName::Stdout => { - if let Err(e) = copy_to_stdout(from) { - sess.dcx().emit_err(errors::CopyPath::new(from, to.as_path(), e)); - } + OutFileName::Stdout if let Err(e) = copy_to_stdout(from) => { + sess.dcx().emit_err(errors::CopyPath::new(from, to.as_path(), e)); } - OutFileName::Real(path) => { - if let Err(e) = fs::copy(from, path) { - sess.dcx().emit_err(errors::CopyPath::new(from, path, e)); - } + OutFileName::Real(path) if let Err(e) = fs::copy(from, path) => { + sess.dcx().emit_err(errors::CopyPath::new(from, path, e)); } + _ => {} }; let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| { @@ -685,14 +682,12 @@ fn produce_final_output_artifacts( needs_crate_object || (user_wants_objects && sess.codegen_units().as_usize() > 1); for module in compiled_modules.modules.iter() { - if let Some(ref path) = module.object { - if !keep_numbered_objects { + if !keep_numbered_objects { + if let Some(ref path) = module.object { ensure_removed(sess.dcx(), path); } - } - if let Some(ref path) = module.dwarf_object { - if !keep_numbered_objects { + if let Some(ref path) = module.dwarf_object { ensure_removed(sess.dcx(), path); } } @@ -704,12 +699,11 @@ fn produce_final_output_artifacts( } } - if !user_wants_bitcode { - if let Some(ref allocator_module) = compiled_modules.allocator_module { - if let Some(ref path) = allocator_module.bytecode { - ensure_removed(sess.dcx(), path); - } - } + if !user_wants_bitcode + && let Some(ref allocator_module) = compiled_modules.allocator_module + && let Some(ref path) = allocator_module.bytecode + { + ensure_removed(sess.dcx(), path); } } diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index e9c886d28ed..396febcc637 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -28,6 +28,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_session::Session; use rustc_session::config::{self, CrateType, EntryFnType, OutputType}; use rustc_span::{DUMMY_SP, Symbol, sym}; +use rustc_symbol_mangling::mangle_internal_symbol; use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt}; use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; use tracing::{debug, info}; @@ -989,7 +990,12 @@ impl CrateInfo { .for_each(|(_, linked_symbols)| { let mut symbols = missing_weak_lang_items .iter() - .map(|item| (format!("{prefix}{item}"), SymbolExportKind::Text)) + .map(|item| { + ( + format!("{prefix}{}", mangle_internal_symbol(tcx, item.as_str())), + SymbolExportKind::Text, + ) + }) .collect::<Vec<_>>(); symbols.sort_unstable_by(|a, b| a.0.cmp(&b.0)); linked_symbols.extend(symbols); @@ -1002,7 +1008,13 @@ impl CrateInfo { // errors. linked_symbols.extend(ALLOCATOR_METHODS.iter().map(|method| { ( - format!("{prefix}{}", global_fn_name(method.name).as_str()), + format!( + "{prefix}{}", + mangle_internal_symbol( + tcx, + global_fn_name(method.name).as_str() + ) + ), SymbolExportKind::Text, ) })); diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 998a4ff727e..d5972b5c9e6 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -601,25 +601,19 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { // strippable by the linker. // // Additionally weak lang items have predetermined symbol names. - if WEAK_LANG_ITEMS.iter().any(|&l| tcx.lang_items().get(l) == Some(did.to_def_id())) { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL; - } if let Some((name, _)) = lang_items::extract(attrs) && let Some(lang_item) = LangItem::from_name(name) - && let Some(link_name) = lang_item.link_name() { - codegen_fn_attrs.export_name = Some(link_name); - codegen_fn_attrs.link_name = Some(link_name); + if WEAK_LANG_ITEMS.iter().any(|&l| l == lang_item) { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL; + } + if let Some(link_name) = lang_item.link_name() { + codegen_fn_attrs.export_name = Some(link_name); + codegen_fn_attrs.link_name = Some(link_name); + } } check_link_name_xor_ordinal(tcx, &codegen_fn_attrs, link_ordinal_span); - // Internal symbols to the standard library all have no_mangle semantics in - // that they have defined symbol names present in the function name. This - // also applies to weak symbols where they all have known symbol names. - if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE; - } - // Any linkage to LLVM intrinsics for now forcibly marks them all as never // unwinds since LLVM sometimes can't handle codegen which `invoke`s // intrinsic functions. diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 84703a0a156..18279a4d05f 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -555,11 +555,9 @@ pub fn compute_debuginfo_vtable_name<'tcx>( pub fn push_item_name(tcx: TyCtxt<'_>, def_id: DefId, qualified: bool, output: &mut String) { let def_key = tcx.def_key(def_id); - if qualified { - if let Some(parent) = def_key.parent { - push_item_name(tcx, DefId { krate: def_id.krate, index: parent }, true, output); - output.push_str("::"); - } + if qualified && let Some(parent) = def_key.parent { + push_item_name(tcx, DefId { krate: def_id.krate, index: parent }, true, output); + output.push_str("::"); } push_unqualified_item_name(tcx, def_id, def_key.disambiguated_data, output); diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 6d1930a402d..d184ce3d61d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -163,25 +163,25 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { mergeable_succ: bool, ) -> MergingSucc { let tcx = bx.tcx(); - if let Some(instance) = instance { - if is_call_from_compiler_builtins_to_upstream_monomorphization(tcx, instance) { - if destination.is_some() { - let caller_def = fx.instance.def_id(); - let e = CompilerBuiltinsCannotCall { - span: tcx.def_span(caller_def), - caller: with_no_trimmed_paths!(tcx.def_path_str(caller_def)), - callee: with_no_trimmed_paths!(tcx.def_path_str(instance.def_id())), - }; - tcx.dcx().emit_err(e); - } else { - info!( - "compiler_builtins call to diverging function {:?} replaced with abort", - instance.def_id() - ); - bx.abort(); - bx.unreachable(); - return MergingSucc::False; - } + if let Some(instance) = instance + && is_call_from_compiler_builtins_to_upstream_monomorphization(tcx, instance) + { + if destination.is_some() { + let caller_def = fx.instance.def_id(); + let e = CompilerBuiltinsCannotCall { + span: tcx.def_span(caller_def), + caller: with_no_trimmed_paths!(tcx.def_path_str(caller_def)), + callee: with_no_trimmed_paths!(tcx.def_path_str(instance.def_id())), + }; + tcx.dcx().emit_err(e); + } else { + info!( + "compiler_builtins call to diverging function {:?} replaced with abort", + instance.def_id() + ); + bx.abort(); + bx.unreachable(); + return MergingSucc::False; } } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 96be44ee09f..0fe6a174735 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -747,7 +747,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let tcx = self.cx.tcx(); OperandRef { val: OperandValue::Immediate(val), - layout: self.cx.layout_of(tcx.types.usize), + layout: self.cx.layout_of(null_op.ty(tcx)), } } @@ -837,15 +837,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn evaluate_array_len(&mut self, bx: &mut Bx, place: mir::Place<'tcx>) -> Bx::Value { // ZST are passed as operands and require special handling // because codegen_place() panics if Local is operand. - if let Some(index) = place.as_local() { - if let LocalRef::Operand(op) = self.locals[index] { - if let ty::Array(_, n) = op.layout.ty.kind() { - let n = n - .try_to_target_usize(bx.tcx()) - .expect("expected monomorphic const in codegen"); - return bx.cx().const_usize(n); - } - } + if let Some(index) = place.as_local() + && let LocalRef::Operand(op) = self.locals[index] + && let ty::Array(_, n) = op.layout.ty.kind() + { + let n = n.try_to_target_usize(bx.tcx()).expect("expected monomorphic const in codegen"); + return bx.cx().const_usize(n); } // use common size calculation for non zero-sized types let cg_value = self.codegen_place(bx, place.as_ref()); diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index b9a5fc3a1fe..fcaf2750507 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -12,7 +12,7 @@ elsa = "1.11.0" ena = "0.14.3" indexmap = "2.4.0" jobserver_crate = { version = "0.1.28", package = "jobserver" } -measureme = "11" +measureme = "12.0.1" rustc-hash = "2.0.0" rustc-rayon = { version = "0.5.1", features = ["indexmap"] } rustc-stable-hash = { version = "0.1.0", features = ["nightly"] } diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 8593d1faba2..de643355f5f 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -54,7 +54,7 @@ time = { version = "0.3.36", default-features = false, features = ["alloc", "for tracing = { version = "0.1.35" } # tidy-alphabetical-end -[target.'cfg(unix)'.dependencies] +[target.'cfg(all(unix, any(target_env = "gnu", target_os = "macos")))'.dependencies] # tidy-alphabetical-start libc = "0.2" # tidy-alphabetical-end diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index ed5662da16d..8ede6e41336 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -44,6 +44,10 @@ use rustc_errors::emitter::stderr_destination; use rustc_errors::registry::Registry; use rustc_errors::{ColorConfig, DiagCtxt, ErrCode, FatalError, PResult, markdown}; use rustc_feature::find_gated_cfg; +// This avoids a false positive with `-Wunused_crate_dependencies`. +// `rust_index` isn't used in this crate's code, but it must be named in the +// `Cargo.toml` for the `rustc_randomized_layouts` feature. +use rustc_index as _; use rustc_interface::util::{self, get_codegen_backend}; use rustc_interface::{Linker, create_and_enter_global_ctxt, interface, passes}; use rustc_lint::unerased_lint_store; @@ -89,6 +93,10 @@ pub mod pretty; #[macro_use] mod print; mod session_diagnostics; + +// Keep the OS parts of this `cfg` in sync with the `cfg` on the `libc` +// dependency in `compiler/rustc_driver/Cargo.toml`, to keep +// `-Wunused-crated-dependencies` satisfied. #[cfg(all(not(miri), unix, any(target_env = "gnu", target_os = "macos")))] mod signal_handler; @@ -457,8 +465,7 @@ pub enum Compilation { fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, color: ColorConfig) { // Allow "E0123" or "0123" form. let upper_cased_code = code.to_ascii_uppercase(); - let start = if upper_cased_code.starts_with('E') { 1 } else { 0 }; - if let Ok(code) = upper_cased_code[start..].parse::<u32>() + if let Ok(code) = upper_cased_code.strip_prefix('E').unwrap_or(&upper_cased_code).parse::<u32>() && let Ok(description) = registry.try_find_description(ErrCode::from_u32(code)) { let mut is_in_code_block = false; @@ -649,10 +656,10 @@ fn print_crate_info( HostTuple => println_info!("{}", rustc_session::config::host_tuple()), Sysroot => println_info!("{}", sess.sysroot.display()), TargetLibdir => println_info!("{}", sess.target_tlib_path.dir.display()), - TargetSpec => { + TargetSpecJson => { println_info!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap()); } - AllTargetSpecs => { + AllTargetSpecsJson => { let mut targets = BTreeMap::new(); for name in rustc_target::spec::TARGETS { let triple = TargetTuple::from_tuple(name); diff --git a/compiler/rustc_error_codes/src/error_codes/E0515.md b/compiler/rustc_error_codes/src/error_codes/E0515.md index 0f4fbf67223..87bbe4aea70 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0515.md +++ b/compiler/rustc_error_codes/src/error_codes/E0515.md @@ -17,10 +17,13 @@ fn get_dangling_iterator<'a>() -> Iter<'a, i32> { } ``` -Local variables, function parameters and temporaries are all dropped before the -end of the function body. So a reference to them cannot be returned. +Local variables, function parameters and temporaries are all dropped before +the end of the function body. A returned reference (or struct containing a +reference) to such a dropped value would immediately be invalid. Therefore +it is not allowed to return such a reference. -Consider returning an owned value instead: +Consider returning a value that takes ownership of local data instead of +referencing it: ``` use std::vec::IntoIter; diff --git a/compiler/rustc_error_codes/src/error_codes/E0773.md b/compiler/rustc_error_codes/src/error_codes/E0773.md index aa65a475a4f..5ebb43c6683 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0773.md +++ b/compiler/rustc_error_codes/src/error_codes/E0773.md @@ -1,40 +1,4 @@ -A builtin-macro was defined more than once. +#### this error code is no longer emitted by the compiler. -Erroneous code example: - -```compile_fail,E0773 -#![feature(decl_macro)] -#![feature(rustc_attrs)] -#![allow(internal_features)] - -#[rustc_builtin_macro] -pub macro test($item:item) { - /* compiler built-in */ -} - -mod inner { - #[rustc_builtin_macro] - pub macro test($item:item) { - /* compiler built-in */ - } -} -``` - -To fix the issue, remove the duplicate declaration: - -``` -#![feature(decl_macro)] -#![feature(rustc_attrs)] -#![allow(internal_features)] - -#[rustc_builtin_macro] -pub macro test($item:item) { - /* compiler built-in */ -} -``` - -In very rare edge cases, this may happen when loading `core` or `std` twice, -once with `check` metadata and once with `build` metadata. -For more information, see [#75176]. - -[#75176]: https://github.com/rust-lang/rust/pull/75176#issuecomment-683234468 +This was triggered when multiple macro definitions used the same +`#[rustc_builtin_macro(..)]`. This is no longer an error. diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index c4b53962584..1dd152beb47 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -681,17 +681,18 @@ impl MacResult for DummyResult { } /// A syntax extension kind. +#[derive(Clone)] pub enum SyntaxExtensionKind { /// A token-based function-like macro. Bang( /// An expander with signature TokenStream -> TokenStream. - Box<dyn BangProcMacro + sync::DynSync + sync::DynSend>, + Arc<dyn BangProcMacro + sync::DynSync + sync::DynSend>, ), /// An AST-based function-like macro. LegacyBang( /// An expander with signature TokenStream -> AST. - Box<dyn TTMacroExpander + sync::DynSync + sync::DynSend>, + Arc<dyn TTMacroExpander + sync::DynSync + sync::DynSend>, ), /// A token-based attribute macro. @@ -699,7 +700,7 @@ pub enum SyntaxExtensionKind { /// An expander with signature (TokenStream, TokenStream) -> TokenStream. /// The first TokenStream is the attribute itself, the second is the annotated item. /// The produced TokenStream replaces the input TokenStream. - Box<dyn AttrProcMacro + sync::DynSync + sync::DynSend>, + Arc<dyn AttrProcMacro + sync::DynSync + sync::DynSend>, ), /// An AST-based attribute macro. @@ -707,7 +708,7 @@ pub enum SyntaxExtensionKind { /// An expander with signature (AST, AST) -> AST. /// The first AST fragment is the attribute itself, the second is the annotated item. /// The produced AST fragment replaces the input AST fragment. - Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>, + Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>, ), /// A trivial attribute "macro" that does nothing, @@ -724,18 +725,18 @@ pub enum SyntaxExtensionKind { /// is handled identically to `LegacyDerive`. It should be migrated to /// a token-based representation like `Bang` and `Attr`, instead of /// using `MultiItemModifier`. - Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>, + Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>, ), /// An AST-based derive macro. LegacyDerive( /// An expander with signature AST -> AST. /// The produced AST fragment is appended to the input AST fragment. - Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>, + Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>, ), /// A glob delegation. - GlobDelegation(Box<dyn GlobDelegationExpander + sync::DynSync + sync::DynSend>), + GlobDelegation(Arc<dyn GlobDelegationExpander + sync::DynSync + sync::DynSend>), } /// A struct representing a macro definition in "lowered" form ready for expansion. @@ -937,7 +938,7 @@ impl SyntaxExtension { cx.dcx().span_delayed_bug(span, "expanded a dummy bang macro"), )) } - SyntaxExtension::default(SyntaxExtensionKind::LegacyBang(Box::new(expander)), edition) + SyntaxExtension::default(SyntaxExtensionKind::LegacyBang(Arc::new(expander)), edition) } /// A dummy derive macro `#[derive(Foo)]`. @@ -950,7 +951,7 @@ impl SyntaxExtension { ) -> Vec<Annotatable> { Vec::new() } - SyntaxExtension::default(SyntaxExtensionKind::Derive(Box::new(expander)), edition) + SyntaxExtension::default(SyntaxExtensionKind::Derive(Arc::new(expander)), edition) } pub fn non_macro_attr(edition: Edition) -> SyntaxExtension { @@ -980,7 +981,7 @@ impl SyntaxExtension { } let expander = GlobDelegationExpanderImpl { trait_def_id, impl_def_id }; - SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Box::new(expander)), edition) + SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Arc::new(expander)), edition) } pub fn expn_data( diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 5577c8902da..77ec598e62a 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -1,5 +1,6 @@ use std::borrow::Cow; use std::collections::hash_map::Entry; +use std::sync::Arc; use std::{mem, slice}; use ast::token::IdentIsRaw; @@ -388,7 +389,7 @@ pub fn compile_declarative_macro( node_id != DUMMY_NODE_ID, ) }; - let dummy_syn_ext = |guar| (mk_syn_ext(Box::new(DummyExpander(guar))), Vec::new()); + let dummy_syn_ext = |guar| (mk_syn_ext(Arc::new(DummyExpander(guar))), Vec::new()); let lhs_nm = Ident::new(sym::lhs, span); let rhs_nm = Ident::new(sym::rhs, span); @@ -582,7 +583,7 @@ pub fn compile_declarative_macro( }) .collect(); - let expander = Box::new(MacroRulesMacroExpander { + let expander = Arc::new(MacroRulesMacroExpander { name: ident, span, node_id, diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index e0269eb6903..ee6306e3961 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -394,8 +394,8 @@ impl ToInternal<SmallVec<[tokenstream::TokenTree; 2]>> symbol, suffix, span, - }) if symbol.as_str().starts_with('-') => { - let symbol = Symbol::intern(&symbol.as_str()[1..]); + }) if let Some(symbol) = symbol.as_str().strip_prefix('-') => { + let symbol = Symbol::intern(symbol); let integer = TokenKind::lit(token::Integer, symbol, suffix); let a = tokenstream::TokenTree::token_joint_hidden(Minus, span); let b = tokenstream::TokenTree::token_alone(integer, span); @@ -406,8 +406,8 @@ impl ToInternal<SmallVec<[tokenstream::TokenTree; 2]>> symbol, suffix, span, - }) if symbol.as_str().starts_with('-') => { - let symbol = Symbol::intern(&symbol.as_str()[1..]); + }) if let Some(symbol) = symbol.as_str().strip_prefix('-') => { + let symbol = Symbol::intern(symbol); let float = TokenKind::lit(token::Float, symbol, suffix); let a = tokenstream::TokenTree::token_joint_hidden(Minus, span); let b = tokenstream::TokenTree::token_alone(float, span); diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index d50fe8c6a3e..980f3946035 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -62,6 +62,8 @@ declare_features! ( (accepted, arbitrary_enum_discriminant, "1.66.0", Some(60553)), /// Allows using `const` operands in inline assembly. (accepted, asm_const, "1.82.0", Some(93332)), + /// Allows using `label` operands in inline assembly. + (accepted, asm_goto, "CURRENT_RUSTC_VERSION", Some(119364)), /// Allows using `sym` operands in inline assembly. (accepted, asm_sym, "1.66.0", Some(93333)), /// Allows the definition of associated constants in `trait` or `impl` blocks. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 3c61bfd1c93..3b75c69132c 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -372,8 +372,6 @@ declare_features! ( (unstable, asm_experimental_arch, "1.58.0", Some(93335)), /// Enables experimental register support in inline assembly. (unstable, asm_experimental_reg, "1.85.0", Some(133416)), - /// Allows using `label` operands in inline assembly. - (unstable, asm_goto, "1.78.0", Some(119364)), /// Allows using `label` operands in inline assembly together with output operands. (unstable, asm_goto_with_outputs, "1.85.0", Some(119364)), /// Allows the `may_unwind` option in inline assembly. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 5cf231d5668..b5857e359a2 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3755,7 +3755,10 @@ pub enum UseKind { /// One import, e.g., `use foo::bar` or `use foo::bar as baz`. /// Also produced for each element of a list `use`, e.g. /// `use foo::{a, b}` lowers to `use foo::a; use foo::b;`. - Single, + /// + /// The identifier is the name defined by the import. E.g. for `use + /// foo::bar` it is `bar`, for `use foo::bar as baz` it is `baz`. + Single(Ident), /// Glob import, e.g., `use foo::*`. Glob, @@ -3897,8 +3900,6 @@ impl ItemId { /// An item /// -/// The name might be a dummy name in case of anonymous items -/// /// For more details, see the [rust lang reference]. /// Note that the reference does not document nightly-only features. /// There may be also slight differences in the names and representation of AST nodes between @@ -3907,7 +3908,6 @@ impl ItemId { /// [rust lang reference]: https://doc.rust-lang.org/reference/items.html #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Item<'hir> { - pub ident: Ident, pub owner_id: OwnerId, pub kind: ItemKind<'hir>, pub span: Span, @@ -3937,46 +3937,56 @@ impl<'hir> Item<'hir> { } expect_methods_self_kind! { - expect_extern_crate, Option<Symbol>, ItemKind::ExternCrate(s), *s; + expect_extern_crate, (Option<Symbol>, Ident), + ItemKind::ExternCrate(s, ident), (*s, *ident); expect_use, (&'hir UsePath<'hir>, UseKind), ItemKind::Use(p, uk), (p, *uk); - expect_static, (&'hir Ty<'hir>, Mutability, BodyId), - ItemKind::Static(ty, mutbl, body), (ty, *mutbl, *body); + expect_static, (Ident, &'hir Ty<'hir>, Mutability, BodyId), + ItemKind::Static(ident, ty, mutbl, body), (*ident, ty, *mutbl, *body); - expect_const, (&'hir Ty<'hir>, &'hir Generics<'hir>, BodyId), - ItemKind::Const(ty, generics, body), (ty, generics, *body); + expect_const, (Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, BodyId), + ItemKind::Const(ident, ty, generics, body), (*ident, ty, generics, *body); - expect_fn, (&FnSig<'hir>, &'hir Generics<'hir>, BodyId), - ItemKind::Fn { sig, generics, body, .. }, (sig, generics, *body); + expect_fn, (Ident, &FnSig<'hir>, &'hir Generics<'hir>, BodyId), + ItemKind::Fn { ident, sig, generics, body, .. }, (*ident, sig, generics, *body); - expect_macro, (&ast::MacroDef, MacroKind), ItemKind::Macro(def, mk), (def, *mk); + expect_macro, (Ident, &ast::MacroDef, MacroKind), + ItemKind::Macro(ident, def, mk), (*ident, def, *mk); - expect_mod, &'hir Mod<'hir>, ItemKind::Mod(m), m; + expect_mod, (Ident, &'hir Mod<'hir>), ItemKind::Mod(ident, m), (*ident, m); expect_foreign_mod, (ExternAbi, &'hir [ForeignItemRef]), ItemKind::ForeignMod { abi, items }, (*abi, items); expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm; - expect_ty_alias, (&'hir Ty<'hir>, &'hir Generics<'hir>), - ItemKind::TyAlias(ty, generics), (ty, generics); + expect_ty_alias, (Ident, &'hir Ty<'hir>, &'hir Generics<'hir>), + ItemKind::TyAlias(ident, ty, generics), (*ident, ty, generics); - expect_enum, (&EnumDef<'hir>, &'hir Generics<'hir>), ItemKind::Enum(def, generics), (def, generics); + expect_enum, (Ident, &EnumDef<'hir>, &'hir Generics<'hir>), + ItemKind::Enum(ident, def, generics), (*ident, def, generics); - expect_struct, (&VariantData<'hir>, &'hir Generics<'hir>), - ItemKind::Struct(data, generics), (data, generics); + expect_struct, (Ident, &VariantData<'hir>, &'hir Generics<'hir>), + ItemKind::Struct(ident, data, generics), (*ident, data, generics); - expect_union, (&VariantData<'hir>, &'hir Generics<'hir>), - ItemKind::Union(data, generics), (data, generics); + expect_union, (Ident, &VariantData<'hir>, &'hir Generics<'hir>), + ItemKind::Union(ident, data, generics), (*ident, data, generics); expect_trait, - (IsAuto, Safety, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]), - ItemKind::Trait(is_auto, safety, generics, bounds, items), - (*is_auto, *safety, generics, bounds, items); - - expect_trait_alias, (&'hir Generics<'hir>, GenericBounds<'hir>), - ItemKind::TraitAlias(generics, bounds), (generics, bounds); + ( + IsAuto, + Safety, + Ident, + &'hir Generics<'hir>, + GenericBounds<'hir>, + &'hir [TraitItemRef] + ), + ItemKind::Trait(is_auto, safety, ident, generics, bounds, items), + (*is_auto, *safety, *ident, generics, bounds, items); + + expect_trait_alias, (Ident, &'hir Generics<'hir>, GenericBounds<'hir>), + ItemKind::TraitAlias(ident, generics, bounds), (*ident, generics, bounds); expect_impl, &'hir Impl<'hir>, ItemKind::Impl(imp), imp; } @@ -4094,7 +4104,7 @@ pub enum ItemKind<'hir> { /// An `extern crate` item, with optional *original* crate name if the crate was renamed. /// /// E.g., `extern crate foo` or `extern crate foo_bar as foo`. - ExternCrate(Option<Symbol>), + ExternCrate(Option<Symbol>, Ident), /// `use foo::bar::*;` or `use foo::bar::baz as quux;` /// @@ -4104,11 +4114,12 @@ pub enum ItemKind<'hir> { Use(&'hir UsePath<'hir>, UseKind), /// A `static` item. - Static(&'hir Ty<'hir>, Mutability, BodyId), + Static(Ident, &'hir Ty<'hir>, Mutability, BodyId), /// A `const` item. - Const(&'hir Ty<'hir>, &'hir Generics<'hir>, BodyId), + Const(Ident, &'hir Ty<'hir>, &'hir Generics<'hir>, BodyId), /// A function declaration. Fn { + ident: Ident, sig: FnSig<'hir>, generics: &'hir Generics<'hir>, body: BodyId, @@ -4118,9 +4129,9 @@ pub enum ItemKind<'hir> { has_body: bool, }, /// A MBE macro definition (`macro_rules!` or `macro`). - Macro(&'hir ast::MacroDef, MacroKind), + Macro(Ident, &'hir ast::MacroDef, MacroKind), /// A module. - Mod(&'hir Mod<'hir>), + Mod(Ident, &'hir Mod<'hir>), /// An external module, e.g. `extern { .. }`. ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemRef] }, /// Module-level inline assembly (from `global_asm!`). @@ -4134,17 +4145,17 @@ pub enum ItemKind<'hir> { fake_body: BodyId, }, /// A type alias, e.g., `type Foo = Bar<u8>`. - TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>), - /// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`. - Enum(EnumDef<'hir>, &'hir Generics<'hir>), + TyAlias(Ident, &'hir Ty<'hir>, &'hir Generics<'hir>), + /// An enum definition, e.g., `enum Foo<A, B> { C<A>, D<B> }`. + Enum(Ident, EnumDef<'hir>, &'hir Generics<'hir>), /// A struct definition, e.g., `struct Foo<A> {x: A}`. - Struct(VariantData<'hir>, &'hir Generics<'hir>), + Struct(Ident, VariantData<'hir>, &'hir Generics<'hir>), /// A union definition, e.g., `union Foo<A, B> {x: A, y: B}`. - Union(VariantData<'hir>, &'hir Generics<'hir>), + Union(Ident, VariantData<'hir>, &'hir Generics<'hir>), /// A trait definition. - Trait(IsAuto, Safety, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]), + Trait(IsAuto, Safety, Ident, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]), /// A trait alias. - TraitAlias(&'hir Generics<'hir>, GenericBounds<'hir>), + TraitAlias(Ident, &'hir Generics<'hir>, GenericBounds<'hir>), /// An implementation, e.g., `impl<A> Trait for Foo { .. }`. Impl(&'hir Impl<'hir>), @@ -4173,16 +4184,39 @@ pub struct Impl<'hir> { } impl ItemKind<'_> { + pub fn ident(&self) -> Option<Ident> { + match *self { + ItemKind::ExternCrate(_, ident) + | ItemKind::Use(_, UseKind::Single(ident)) + | ItemKind::Static(ident, ..) + | ItemKind::Const(ident, ..) + | ItemKind::Fn { ident, .. } + | ItemKind::Macro(ident, ..) + | ItemKind::Mod(ident, ..) + | ItemKind::TyAlias(ident, ..) + | ItemKind::Enum(ident, ..) + | ItemKind::Struct(ident, ..) + | ItemKind::Union(ident, ..) + | ItemKind::Trait(_, _, ident, ..) + | ItemKind::TraitAlias(ident, ..) => Some(ident), + + ItemKind::Use(_, UseKind::Glob | UseKind::ListStem) + | ItemKind::ForeignMod { .. } + | ItemKind::GlobalAsm { .. } + | ItemKind::Impl(_) => None, + } + } + pub fn generics(&self) -> Option<&Generics<'_>> { Some(match self { ItemKind::Fn { generics, .. } - | ItemKind::TyAlias(_, generics) - | ItemKind::Const(_, generics, _) - | ItemKind::Enum(_, generics) - | ItemKind::Struct(_, generics) - | ItemKind::Union(_, generics) - | ItemKind::Trait(_, _, generics, _, _) - | ItemKind::TraitAlias(generics, _) + | ItemKind::TyAlias(_, _, generics) + | ItemKind::Const(_, _, generics, _) + | ItemKind::Enum(_, _, generics) + | ItemKind::Struct(_, _, generics) + | ItemKind::Union(_, _, generics) + | ItemKind::Trait(_, _, _, generics, _, _) + | ItemKind::TraitAlias(_, generics, _) | ItemKind::Impl(Impl { generics, .. }) => generics, _ => return None, }) @@ -4374,8 +4408,8 @@ impl<'hir> OwnerNode<'hir> { match self { OwnerNode::Item(Item { kind: - ItemKind::Static(_, _, body) - | ItemKind::Const(_, _, body) + ItemKind::Static(_, _, _, body) + | ItemKind::Const(_, _, _, body) | ItemKind::Fn { body, .. }, .. }) @@ -4518,12 +4552,12 @@ impl<'hir> Node<'hir> { /// ``` pub fn ident(&self) -> Option<Ident> { match self { + Node::Item(item) => item.kind.ident(), Node::TraitItem(TraitItem { ident, .. }) | Node::ImplItem(ImplItem { ident, .. }) | Node::ForeignItem(ForeignItem { ident, .. }) | Node::Field(FieldDef { ident, .. }) | Node::Variant(Variant { ident, .. }) - | Node::Item(Item { ident, .. }) | Node::PathSegment(PathSegment { ident, .. }) => Some(*ident), Node::Lifetime(lt) => Some(lt.ident), Node::GenericParam(p) => Some(p.name.ident()), @@ -4599,9 +4633,9 @@ impl<'hir> Node<'hir> { pub fn ty(self) -> Option<&'hir Ty<'hir>> { match self { Node::Item(it) => match it.kind { - ItemKind::TyAlias(ty, _) - | ItemKind::Static(ty, _, _) - | ItemKind::Const(ty, _, _) => Some(ty), + ItemKind::TyAlias(_, ty, _) + | ItemKind::Static(_, ty, _, _) + | ItemKind::Const(_, ty, _, _) => Some(ty), ItemKind::Impl(impl_item) => Some(&impl_item.self_ty), _ => None, }, @@ -4621,7 +4655,7 @@ impl<'hir> Node<'hir> { pub fn alias_ty(self) -> Option<&'hir Ty<'hir>> { match self { - Node::Item(Item { kind: ItemKind::TyAlias(ty, ..), .. }) => Some(ty), + Node::Item(Item { kind: ItemKind::TyAlias(_, ty, _), .. }) => Some(ty), _ => None, } } @@ -4632,7 +4666,9 @@ impl<'hir> Node<'hir> { Node::Item(Item { owner_id, kind: - ItemKind::Const(_, _, body) | ItemKind::Static(.., body) | ItemKind::Fn { body, .. }, + ItemKind::Const(_, _, _, body) + | ItemKind::Static(.., body) + | ItemKind::Fn { body, .. }, .. }) | Node::TraitItem(TraitItem { @@ -4693,8 +4729,8 @@ impl<'hir> Node<'hir> { pub fn fn_kind(self) -> Option<FnKind<'hir>> { match self { Node::Item(i) => match i.kind { - ItemKind::Fn { sig, generics, .. } => { - Some(FnKind::ItemFn(i.ident, generics, sig.header)) + ItemKind::Fn { ident, sig, generics, .. } => { + Some(FnKind::ItemFn(ident, generics, sig.header)) } _ => None, }, @@ -4767,7 +4803,7 @@ mod size_asserts { static_assert_size!(ImplItem<'_>, 88); static_assert_size!(ImplItemKind<'_>, 40); static_assert_size!(Item<'_>, 88); - static_assert_size!(ItemKind<'_>, 56); + static_assert_size!(ItemKind<'_>, 64); static_assert_size!(LetStmt<'_>, 64); static_assert_size!(Param<'_>, 32); static_assert_size!(Pat<'_>, 72); diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 3ef645a5f61..b79ae1e7cc2 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -533,34 +533,44 @@ pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) -> pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::Result { try_visit!(visitor.visit_id(item.hir_id())); - try_visit!(visitor.visit_ident(item.ident)); match item.kind { - ItemKind::ExternCrate(orig_name) => { + ItemKind::ExternCrate(orig_name, ident) => { visit_opt!(visitor, visit_name, orig_name); + try_visit!(visitor.visit_ident(ident)); } - ItemKind::Use(ref path, _) => { + ItemKind::Use(ref path, kind) => { try_visit!(visitor.visit_use(path, item.hir_id())); + match kind { + UseKind::Single(ident) => try_visit!(visitor.visit_ident(ident)), + UseKind::Glob | UseKind::ListStem => {} + } } - ItemKind::Static(ref typ, _, body) => { + ItemKind::Static(ident, ref typ, _, body) => { + try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_ty_unambig(typ)); try_visit!(visitor.visit_nested_body(body)); } - ItemKind::Const(ref typ, ref generics, body) => { + ItemKind::Const(ident, ref typ, ref generics, body) => { + try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_ty_unambig(typ)); try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_nested_body(body)); } - ItemKind::Fn { sig, generics, body: body_id, .. } => { + ItemKind::Fn { ident, sig, generics, body: body_id, .. } => { + try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_fn( - FnKind::ItemFn(item.ident, generics, sig.header), + FnKind::ItemFn(ident, generics, sig.header), sig.decl, body_id, item.span, item.owner_id.def_id, )); } - ItemKind::Macro(..) => {} - ItemKind::Mod(ref module) => { + ItemKind::Macro(ident, _def, _kind) => { + try_visit!(visitor.visit_ident(ident)); + } + ItemKind::Mod(ident, ref module) => { + try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_mod(module, item.span, item.hir_id())); } ItemKind::ForeignMod { abi: _, items } => { @@ -573,11 +583,13 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: // typeck results set correctly. try_visit!(visitor.visit_nested_body(fake_body)); } - ItemKind::TyAlias(ref ty, ref generics) => { + ItemKind::TyAlias(ident, ref ty, ref generics) => { + try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_ty_unambig(ty)); try_visit!(visitor.visit_generics(generics)); } - ItemKind::Enum(ref enum_definition, ref generics) => { + ItemKind::Enum(ident, ref enum_definition, ref generics) => { + try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_enum_def(enum_definition)); } @@ -597,17 +609,20 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_ty_unambig(self_ty)); walk_list!(visitor, visit_impl_item_ref, *items); } - ItemKind::Struct(ref struct_definition, ref generics) - | ItemKind::Union(ref struct_definition, ref generics) => { + ItemKind::Struct(ident, ref struct_definition, ref generics) + | ItemKind::Union(ident, ref struct_definition, ref generics) => { + try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_variant_data(struct_definition)); } - ItemKind::Trait(.., ref generics, bounds, trait_item_refs) => { + ItemKind::Trait(_is_auto, _safety, ident, ref generics, bounds, trait_item_refs) => { + try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_generics(generics)); walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_trait_item_ref, trait_item_refs); } - ItemKind::TraitAlias(ref generics, bounds) => { + ItemKind::TraitAlias(ident, ref generics, bounds) => { + try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_generics(generics)); walk_list!(visitor, visit_param_bound, bounds); } diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index b4a16b2b805..d8ae4214527 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -153,10 +153,9 @@ pub(super) fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDef } // If `#[link_section]` is missing, then nothing to verify - let attrs = tcx.codegen_fn_attrs(id); - if attrs.link_section.is_none() { + let Some(link_section) = tcx.codegen_fn_attrs(id).link_section else { return; - } + }; // For the wasm32 target statics with `#[link_section]` other than `.init_array` // are placed into custom sections of the final output file, but this isn't like @@ -182,11 +181,8 @@ pub(super) fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDef // continue to work, but would no longer be necessary. if let Ok(alloc) = tcx.eval_static_initializer(id.to_def_id()) - && alloc.inner().provenance().ptrs().len() != 0 - && attrs - .link_section - .map(|link_section| !link_section.as_str().starts_with(".init_array")) - .unwrap() + && !alloc.inner().provenance().ptrs().is_empty() + && !link_section.as_str().starts_with(".init_array") { let msg = "statics with a custom `#[link_section]` must be a \ simple list of bytes on the wasm target with no \ diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 4769153ff4d..952af592311 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -269,26 +269,26 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() } res } - hir::ItemKind::Fn { sig, .. } => { - check_item_fn(tcx, def_id, item.ident, item.span, sig.decl) + hir::ItemKind::Fn { ident, sig, .. } => { + check_item_fn(tcx, def_id, ident, item.span, sig.decl) } - hir::ItemKind::Static(ty, ..) => { + hir::ItemKind::Static(_, ty, ..) => { check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid) } - hir::ItemKind::Const(ty, ..) => { + hir::ItemKind::Const(_, ty, ..) => { check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid) } - hir::ItemKind::Struct(_, hir_generics) => { + hir::ItemKind::Struct(_, _, hir_generics) => { let res = check_type_defn(tcx, item, false); check_variances_for_type_defn(tcx, item, hir_generics); res } - hir::ItemKind::Union(_, hir_generics) => { + hir::ItemKind::Union(_, _, hir_generics) => { let res = check_type_defn(tcx, item, true); check_variances_for_type_defn(tcx, item, hir_generics); res } - hir::ItemKind::Enum(_, hir_generics) => { + hir::ItemKind::Enum(_, _, hir_generics) => { let res = check_type_defn(tcx, item, true); check_variances_for_type_defn(tcx, item, hir_generics); res @@ -297,7 +297,9 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() hir::ItemKind::TraitAlias(..) => check_trait(tcx, item), // `ForeignItem`s are handled separately. hir::ItemKind::ForeignMod { .. } => Ok(()), - hir::ItemKind::TyAlias(hir_ty, hir_generics) if tcx.type_alias_is_lazy(item.owner_id) => { + hir::ItemKind::TyAlias(_, hir_ty, hir_generics) + if tcx.type_alias_is_lazy(item.owner_id) => + { let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| { let ty = tcx.type_of(def_id).instantiate_identity(); let item_ty = wfcx.normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty); @@ -822,10 +824,10 @@ fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool { /// /// In such cases, suggest using `Self` instead. fn check_dyn_incompatible_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) { - let (trait_name, trait_def_id) = + let (trait_ident, trait_def_id) = match tcx.hir_node_by_def_id(tcx.hir_get_parent_item(item.hir_id()).def_id) { hir::Node::Item(item) => match item.kind { - hir::ItemKind::Trait(..) => (item.ident, item.owner_id), + hir::ItemKind::Trait(_, _, ident, ..) => (ident, item.owner_id), _ => return, }, _ => return, @@ -862,7 +864,7 @@ fn check_dyn_incompatible_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitI trait_should_be_self, "associated item referring to unboxed trait object for its own trait", ) - .with_span_label(trait_name.span, "in this trait") + .with_span_label(trait_ident.span, "in this trait") .with_multipart_suggestion( "you might have meant to use `Self` to refer to the implementing type", sugg, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 54a630f5b00..075abc32594 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -247,13 +247,13 @@ fn reject_placeholder_type_signatures_in_item<'tcx>( item: &'tcx hir::Item<'tcx>, ) { let (generics, suggest) = match &item.kind { - hir::ItemKind::Union(_, generics) - | hir::ItemKind::Enum(_, generics) - | hir::ItemKind::TraitAlias(generics, _) - | hir::ItemKind::Trait(_, _, generics, ..) + hir::ItemKind::Union(_, _, generics) + | hir::ItemKind::Enum(_, _, generics) + | hir::ItemKind::TraitAlias(_, generics, _) + | hir::ItemKind::Trait(_, _, _, generics, ..) | hir::ItemKind::Impl(hir::Impl { generics, .. }) - | hir::ItemKind::Struct(_, generics) => (generics, true), - hir::ItemKind::TyAlias(_, generics) => (generics, false), + | hir::ItemKind::Struct(_, _, generics) => (generics, true), + hir::ItemKind::TyAlias(_, _, generics) => (generics, false), // `static`, `fn` and `const` are handled elsewhere to suggest appropriate type. _ => return, }; @@ -470,9 +470,9 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { .tcx .hir_expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id); match &item.kind { - hir::ItemKind::Enum(_, generics) - | hir::ItemKind::Struct(_, generics) - | hir::ItemKind::Union(_, generics) => { + hir::ItemKind::Enum(_, _, generics) + | hir::ItemKind::Struct(_, _, generics) + | hir::ItemKind::Union(_, _, generics) => { let lt_name = get_new_lifetime_name(self.tcx, poly_trait_ref, generics); let (lt_sp, sugg) = match generics.params { [] => (generics.span, format!("<{lt_name}>")), @@ -667,16 +667,16 @@ fn get_new_lifetime_name<'tcx>( #[instrument(level = "debug", skip_all)] fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { let it = tcx.hir_item(item_id); - debug!(item = %it.ident, id = %it.hir_id()); + debug!(item = ?it.kind.ident(), id = %it.hir_id()); let def_id = item_id.owner_id.def_id; let icx = ItemCtxt::new(tcx, def_id); match &it.kind { // These don't define types. - hir::ItemKind::ExternCrate(_) + hir::ItemKind::ExternCrate(..) | hir::ItemKind::Use(..) | hir::ItemKind::Macro(..) - | hir::ItemKind::Mod(_) + | hir::ItemKind::Mod(..) | hir::ItemKind::GlobalAsm { .. } => {} hir::ItemKind::ForeignMod { items, .. } => { for item in *items { @@ -736,7 +736,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { tcx.at(it.span).explicit_super_predicates_of(def_id); tcx.ensure_ok().predicates_of(def_id); } - hir::ItemKind::Struct(struct_def, _) | hir::ItemKind::Union(struct_def, _) => { + hir::ItemKind::Struct(_, struct_def, _) | hir::ItemKind::Union(_, struct_def, _) => { tcx.ensure_ok().generics_of(def_id); tcx.ensure_ok().type_of(def_id); tcx.ensure_ok().predicates_of(def_id); @@ -758,7 +758,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { tcx.ensure_ok().predicates_of(def_id); } - hir::ItemKind::Static(ty, ..) | hir::ItemKind::Const(ty, ..) => { + hir::ItemKind::Static(_, ty, ..) | hir::ItemKind::Const(_, ty, ..) => { tcx.ensure_ok().generics_of(def_id); tcx.ensure_ok().type_of(def_id); tcx.ensure_ok().predicates_of(def_id); @@ -1089,7 +1089,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> { let repr = tcx.repr_options_of_def(def_id); let (kind, variants) = match &item.kind { - ItemKind::Enum(def, _) => { + ItemKind::Enum(_, def, _) => { let mut distance_from_explicit = 0; let variants = def .variants @@ -1117,7 +1117,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> { (AdtKind::Enum, variants) } - ItemKind::Struct(def, _) | ItemKind::Union(def, _) => { + ItemKind::Struct(ident, def, _) | ItemKind::Union(ident, def, _) => { let adt_kind = match item.kind { ItemKind::Struct(..) => AdtKind::Struct, _ => AdtKind::Union, @@ -1125,7 +1125,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> { let variants = std::iter::once(lower_variant( tcx, None, - item.ident, + *ident, ty::VariantDiscr::Relative(0), def, adt_kind, diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index 7cbd31de6ba..c3f965d8456 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -134,7 +134,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) { }; tcx.vtable_entries(trait_ref) } - hir::ItemKind::TyAlias(_, _) => { + hir::ItemKind::TyAlias(..) => { let ty = tcx.type_of(def_id).instantiate_identity(); if ty.has_non_region_param() { tcx.dcx().span_err( diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 2022127a15b..4bd89861a9e 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -163,7 +163,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } } - ItemKind::Trait(_, _, _, self_bounds, ..) | ItemKind::TraitAlias(_, self_bounds) => { + ItemKind::Trait(_, _, _, _, self_bounds, ..) + | ItemKind::TraitAlias(_, _, self_bounds) => { is_trait = Some(self_bounds); } _ => {} @@ -615,7 +616,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>( let (generics, superbounds) = match item.kind { hir::ItemKind::Trait(.., generics, supertraits, _) => (generics, supertraits), - hir::ItemKind::TraitAlias(generics, supertraits) => (generics, supertraits), + hir::ItemKind::TraitAlias(_, generics, supertraits) => (generics, supertraits), _ => span_bug!(item.span, "super_predicates invoked on non-trait"), }; @@ -959,7 +960,7 @@ pub(super) fn const_conditions<'tcx>( Node::Item(item) => match item.kind { hir::ItemKind::Impl(impl_) => (impl_.generics, None, false), hir::ItemKind::Fn { generics, .. } => (generics, None, false), - hir::ItemKind::Trait(_, _, generics, supertraits, _) => { + hir::ItemKind::Trait(_, _, _, generics, supertraits, _) => { (generics, Some((item.owner_id.def_id, supertraits)), false) } _ => bug!("const_conditions called on wrong item: {def_id:?}"), diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 883a1acdb30..9b0d57bd75b 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -617,7 +617,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { }); } - hir::ItemKind::ExternCrate(_) + hir::ItemKind::ExternCrate(..) | hir::ItemKind::Use(..) | hir::ItemKind::Macro(..) | hir::ItemKind::Mod(..) @@ -627,13 +627,13 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { // These sorts of items have no lifetime parameters at all. intravisit::walk_item(self, item); } - hir::ItemKind::TyAlias(_, generics) - | hir::ItemKind::Const(_, generics, _) - | hir::ItemKind::Enum(_, generics) - | hir::ItemKind::Struct(_, generics) - | hir::ItemKind::Union(_, generics) - | hir::ItemKind::Trait(_, _, generics, ..) - | hir::ItemKind::TraitAlias(generics, ..) + hir::ItemKind::TyAlias(_, _, generics) + | hir::ItemKind::Const(_, _, generics, _) + | hir::ItemKind::Enum(_, _, generics) + | hir::ItemKind::Struct(_, _, generics) + | hir::ItemKind::Union(_, _, generics) + | hir::ItemKind::Trait(_, _, _, generics, ..) + | hir::ItemKind::TraitAlias(_, generics, ..) | hir::ItemKind::Impl(&hir::Impl { generics, .. }) => { // These kinds of items have only early-bound lifetime parameters. self.visit_early(item.hir_id(), generics, |this| intravisit::walk_item(this, item)); diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 4e8f5ce3986..afda2c142e2 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -202,35 +202,35 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ }, Node::Item(item) => match item.kind { - ItemKind::Static(ty, .., body_id) => { + ItemKind::Static(ident, ty, .., body_id) => { if ty.is_suggestable_infer_ty() { infer_placeholder_type( icx.lowerer(), def_id, body_id, ty.span, - item.ident, + ident, "static variable", ) } else { icx.lower_ty(ty) } } - ItemKind::Const(ty, _, body_id) => { + ItemKind::Const(ident, ty, _, body_id) => { if ty.is_suggestable_infer_ty() { infer_placeholder_type( icx.lowerer(), def_id, body_id, ty.span, - item.ident, + ident, "constant", ) } else { icx.lower_ty(ty) } } - ItemKind::TyAlias(self_ty, _) => icx.lower_ty(self_ty), + ItemKind::TyAlias(_, self_ty, _) => icx.lower_ty(self_ty), ItemKind::Impl(hir::Impl { self_ty, .. }) => match self_ty.find_self_aliases() { spans if spans.len() > 0 => { let guar = tcx @@ -479,5 +479,5 @@ pub(crate) fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> } } } - HasTait.visit_ty_unambig(tcx.hir_expect_item(def_id).expect_ty_alias().0).is_break() + HasTait.visit_ty_unambig(tcx.hir_expect_item(def_id).expect_ty_alias().1).is_break() } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 7e1f35627e3..27643e715e6 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -176,7 +176,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .in_definition_order() // We only care about associated types. .filter(|item| item.kind == ty::AssocKind::Type) - // No RPITITs -- even with `async_fn_in_dyn_trait`, they are implicit. + // No RPITITs -- they're not dyn-compatible for now. .filter(|item| !item.is_impl_trait_in_trait()) // If the associated type has a `where Self: Sized` bound, // we do not need to constrain the associated type. 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 fa061c80618..3b007c77198 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -901,12 +901,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .iter() .map(|(item, _)| format!("{} = Type", item.name)) .collect(); - let code = if snippet.ends_with('>') { + let code = if let Some(snippet) = snippet.strip_suffix('>') { // The user wrote `Trait<'a>` or similar and we don't have a type we can // suggest, but at least we can clue them to the correct syntax // `Trait<'a, Item = Type>` while accounting for the `<'a>` in the // suggestion. - format!("{}, {}>", &snippet[..snippet.len() - 1], types.join(", ")) + format!("{}, {}>", snippet, types.join(", ")) } else if in_expr_or_pat { // The user wrote `Iterator`, so we don't have a type we can suggest, but at // least we can clue them to the correct syntax `Iterator::<Item = Type>`. diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index be726c042da..55886312284 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -140,14 +140,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let generics = match tcx.hir_node_by_def_id(parent_item) { hir::Node::Item(hir::Item { - kind: hir::ItemKind::Struct(variant, generics), .. + kind: hir::ItemKind::Struct(_, variant, generics), + .. }) => { if !variant.fields().iter().any(|field| field.hir_id == parent_hir_id) { return false; } generics } - hir::Node::Item(hir::Item { kind: hir::ItemKind::Enum(def, generics), .. }) => { + hir::Node::Item(hir::Item { kind: hir::ItemKind::Enum(_, def, generics), .. }) => { if !def .variants .iter() @@ -267,7 +268,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::Node::Field(field) => { // Enums can't have unsized fields, fields can only have an unsized tail field. if let hir::Node::Item(hir::Item { - kind: hir::ItemKind::Struct(variant, _), .. + kind: hir::ItemKind::Struct(_, variant, _), .. }) = tcx.parent_hir_node(field.hir_id) && variant .fields() diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index 1f5d69bd1b3..e27a81d4976 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -136,9 +136,9 @@ fn diagnostic_hir_wf_check<'tcx>( ref item => bug!("Unexpected TraitItem {:?}", item), }, hir::Node::Item(item) => match item.kind { - hir::ItemKind::TyAlias(ty, _) - | hir::ItemKind::Static(ty, _, _) - | hir::ItemKind::Const(ty, _, _) => vec![ty], + hir::ItemKind::TyAlias(_, ty, _) + | hir::ItemKind::Static(_, ty, _, _) + | hir::ItemKind::Const(_, ty, _, _) => vec![ty], hir::ItemKind::Impl(impl_) => match &impl_.of_trait { Some(t) => t .path diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index cb3cdc5e8d3..e7ecd727a85 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -252,7 +252,9 @@ pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { // def-ID that will be used to determine the traits/predicates in // scope. This is derived from the enclosing item-like thing. let env_def_id = tcx.hir_get_parent_item(hir_ty.hir_id); - collect::ItemCtxt::new(tcx, env_def_id.def_id).lower_ty(hir_ty) + collect::ItemCtxt::new(tcx, env_def_id.def_id) + .lowerer() + .lower_ty_maybe_return_type_notation(hir_ty) } /// This is for rustdoc. diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 1409310339a..98b81dd3def 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -559,7 +559,7 @@ impl<'a> State<'a> { self.print_attrs_as_outer(attrs); self.ann.pre(self, AnnNode::Item(item)); match item.kind { - hir::ItemKind::ExternCrate(orig_name) => { + hir::ItemKind::ExternCrate(orig_name, ident) => { self.head("extern crate"); if let Some(orig_name) = orig_name { self.print_name(orig_name); @@ -567,7 +567,7 @@ impl<'a> State<'a> { self.word("as"); self.space(); } - self.print_ident(item.ident); + self.print_ident(ident); self.word(";"); self.end(); // end inner head-block self.end(); // end outer head-block @@ -577,11 +577,11 @@ impl<'a> State<'a> { self.print_path(path, false); match kind { - hir::UseKind::Single => { - if path.segments.last().unwrap().ident != item.ident { + hir::UseKind::Single(ident) => { + if path.segments.last().unwrap().ident != ident { self.space(); self.word_space("as"); - self.print_ident(item.ident); + self.print_ident(ident); } self.word(";"); } @@ -591,12 +591,12 @@ impl<'a> State<'a> { self.end(); // end inner head-block self.end(); // end outer head-block } - hir::ItemKind::Static(ty, m, expr) => { + hir::ItemKind::Static(ident, ty, m, expr) => { self.head("static"); if m.is_mut() { self.word_space("mut"); } - self.print_ident(item.ident); + self.print_ident(ident); self.word_space(":"); self.print_type(ty); self.space(); @@ -607,9 +607,9 @@ impl<'a> State<'a> { self.word(";"); self.end(); // end the outer cbox } - hir::ItemKind::Const(ty, generics, expr) => { + hir::ItemKind::Const(ident, ty, generics, expr) => { self.head("const"); - self.print_ident(item.ident); + self.print_ident(ident); self.print_generic_params(generics.params); self.word_space(":"); self.print_type(ty); @@ -622,30 +622,23 @@ impl<'a> State<'a> { self.word(";"); self.end(); // end the outer cbox } - hir::ItemKind::Fn { sig, generics, body, .. } => { + hir::ItemKind::Fn { ident, sig, generics, body, .. } => { self.head(""); - self.print_fn( - sig.decl, - sig.header, - Some(item.ident.name), - generics, - &[], - Some(body), - ); + self.print_fn(sig.decl, sig.header, Some(ident.name), generics, &[], Some(body)); self.word(" "); self.end(); // need to close a box self.end(); // need to close a box self.ann.nested(self, Nested::Body(body)); } - hir::ItemKind::Macro(macro_def, _) => { - self.print_mac_def(macro_def, &item.ident, item.span, |_| {}); + hir::ItemKind::Macro(ident, macro_def, _) => { + self.print_mac_def(macro_def, &ident, item.span, |_| {}); } - hir::ItemKind::Mod(_mod) => { + hir::ItemKind::Mod(ident, mod_) => { self.head("mod"); - self.print_ident(item.ident); + self.print_ident(ident); self.nbsp(); self.bopen(); - self.print_mod(_mod, attrs); + self.print_mod(mod_, attrs); self.bclose(item.span); } hir::ItemKind::ForeignMod { abi, items } => { @@ -663,9 +656,9 @@ impl<'a> State<'a> { self.print_inline_asm(asm); self.end() } - hir::ItemKind::TyAlias(ty, generics) => { + hir::ItemKind::TyAlias(ident, ty, generics) => { self.head("type"); - self.print_ident(item.ident); + self.print_ident(ident); self.print_generic_params(generics.params); self.end(); // end the inner ibox @@ -676,16 +669,16 @@ impl<'a> State<'a> { self.word(";"); self.end(); // end the outer ibox } - hir::ItemKind::Enum(ref enum_definition, params) => { - self.print_enum_def(enum_definition, params, item.ident.name, item.span); + hir::ItemKind::Enum(ident, ref enum_definition, params) => { + self.print_enum_def(enum_definition, params, ident.name, item.span); } - hir::ItemKind::Struct(ref struct_def, generics) => { + hir::ItemKind::Struct(ident, ref struct_def, generics) => { self.head("struct"); - self.print_struct(struct_def, generics, item.ident.name, item.span, true); + self.print_struct(struct_def, generics, ident.name, item.span, true); } - hir::ItemKind::Union(ref struct_def, generics) => { + hir::ItemKind::Union(ident, ref struct_def, generics) => { self.head("union"); - self.print_struct(struct_def, generics, item.ident.name, item.span, true); + self.print_struct(struct_def, generics, ident.name, item.span, true); } hir::ItemKind::Impl(&hir::Impl { constness, @@ -733,12 +726,12 @@ impl<'a> State<'a> { } self.bclose(item.span); } - hir::ItemKind::Trait(is_auto, safety, generics, bounds, trait_items) => { + hir::ItemKind::Trait(is_auto, safety, ident, generics, bounds, trait_items) => { self.head(""); self.print_is_auto(is_auto); self.print_safety(safety); self.word_nbsp("trait"); - self.print_ident(item.ident); + self.print_ident(ident); self.print_generic_params(generics.params); self.print_bounds(":", bounds); self.print_where_clause(generics); @@ -749,9 +742,9 @@ impl<'a> State<'a> { } self.bclose(item.span); } - hir::ItemKind::TraitAlias(generics, bounds) => { + hir::ItemKind::TraitAlias(ident, generics, bounds) => { self.head("trait"); - self.print_ident(item.ident); + self.print_ident(ident); self.print_generic_params(generics.params); self.nbsp(); self.print_bounds("=", bounds); diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 2a24d626ac3..5e2daa69628 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -713,8 +713,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for id in self.tcx.hir_free_items() { if let Some(node) = self.tcx.hir_get_if_local(id.owner_id.into()) && let hir::Node::Item(item) = node - && let hir::ItemKind::Fn { .. } = item.kind - && item.ident.name == segment.ident.name + && let hir::ItemKind::Fn { ident, .. } = item.kind + && ident.name == segment.ident.name { err.span_label( self.tcx.def_span(id.owner_id), diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index c85c3b90ce7..8f5fddd19d7 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -43,7 +43,6 @@ use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{self, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, VariantDef, elaborate}; use rustc_middle::{bug, span_bug}; use rustc_session::lint; -use rustc_span::def_id::LOCAL_CRATE; use rustc_span::{DUMMY_SP, Span, sym}; use rustc_trait_selection::infer::InferCtxtExt; use tracing::{debug, instrument}; @@ -805,7 +804,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { _ => return Err(CastError::NonScalar), }; if let ty::Adt(adt_def, _) = *self.expr_ty.kind() - && adt_def.did().krate != LOCAL_CRATE + && !adt_def.did().is_local() && adt_def.variants().iter().any(VariantDef::is_field_list_non_exhaustive) { return Err(CastError::ForeignNonExhaustiveAdt); diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 3eef32aa7c1..41bdd0ca43e 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -721,8 +721,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, )) => { if let Some(hir::Node::Item(hir::Item { - ident, - kind: hir::ItemKind::Static(ty, ..) | hir::ItemKind::Const(ty, ..), + kind: + hir::ItemKind::Static(ident, ty, ..) + | hir::ItemKind::Const(ident, ty, ..), .. })) = self.tcx.hir_get_if_local(*def_id) { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 7e8e4e3a561..a75f6f4caac 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1977,7 +1977,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Prohibit struct expressions when non-exhaustive flag is set. let adt = adt_ty.ty_adt_def().expect("`check_struct_path` returned non-ADT type"); - if !adt.did().is_local() && variant.is_field_list_non_exhaustive() { + if variant.field_list_has_applicable_non_exhaustive() { self.dcx() .emit_err(StructExprNonExhaustive { span: expr.span, what: adt.variant_descr() }); } diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 35e687f2b0f..c71a5ea8b97 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -20,7 +20,7 @@ use rustc_middle::hir::place::ProjectionKind; pub use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection}; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{ - self, AdtKind, BorrowKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt as _, adjustment, + self, BorrowKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt as _, adjustment, }; use rustc_middle::{bug, span_bug}; use rustc_span::{ErrorGuaranteed, Span}; @@ -1899,14 +1899,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // to assume that more cases will be added to the variant in the future. This mean // that we should handle non-exhaustive SingleVariant the same way we would handle // a MultiVariant. - // If the variant is not local it must be defined in another crate. - let is_non_exhaustive = match def.adt_kind() { - AdtKind::Struct | AdtKind::Union => { - def.non_enum_variant().is_field_list_non_exhaustive() - } - AdtKind::Enum => def.is_variant_list_non_exhaustive(), - }; - def.variants().len() > 1 || (!def.did().is_local() && is_non_exhaustive) + def.variants().len() > 1 || def.variant_list_has_applicable_non_exhaustive() } else { false } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 37aaaed5477..264719ca569 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -904,7 +904,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Assumes given function doesn't have a explicit return type. fn can_add_return_type(&self, fn_id: LocalDefId) -> bool { match self.tcx.hir_node_by_def_id(fn_id) { - Node::Item(&hir::Item { ident, .. }) => { + Node::Item(item) => { + let (ident, _, _, _) = item.expect_fn(); // This is less than ideal, it will not suggest a return type span on any // method called `main`, regardless of whether it is actually the entry point, // but it will still present it as the reason for the expected type. @@ -1532,30 +1533,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.may_coerce(blk_ty, *elem_ty) && blk.stmts.is_empty() && blk.rules == hir::BlockCheckMode::DefaultBlock + && let source_map = self.tcx.sess.source_map() + && let Ok(snippet) = source_map.span_to_snippet(blk.span) + && snippet.starts_with('{') + && snippet.ends_with('}') { - let source_map = self.tcx.sess.source_map(); - if let Ok(snippet) = source_map.span_to_snippet(blk.span) { - if snippet.starts_with('{') && snippet.ends_with('}') { - diag.multipart_suggestion_verbose( - "to create an array, use square brackets instead of curly braces", - vec![ - ( - blk.span - .shrink_to_lo() - .with_hi(rustc_span::BytePos(blk.span.lo().0 + 1)), - "[".to_string(), - ), - ( - blk.span - .shrink_to_hi() - .with_lo(rustc_span::BytePos(blk.span.hi().0 - 1)), - "]".to_string(), - ), - ], - Applicability::MachineApplicable, - ); - } - } + diag.multipart_suggestion_verbose( + "to create an array, use square brackets instead of curly braces", + vec![ + ( + blk.span + .shrink_to_lo() + .with_hi(rustc_span::BytePos(blk.span.lo().0 + 1)), + "[".to_string(), + ), + ( + blk.span + .shrink_to_hi() + .with_lo(rustc_span::BytePos(blk.span.hi().0 - 1)), + "]".to_string(), + ), + ], + Applicability::MachineApplicable, + ); } } } @@ -2983,7 +2983,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } - let Ok(src) = self.tcx.sess.source_map().span_to_snippet(expr.span) else { + let span = if let hir::ExprKind::Lit(lit) = &expr.kind { lit.span } else { expr.span }; + let Ok(src) = self.tcx.sess.source_map().span_to_snippet(span) else { return false; }; @@ -3078,10 +3079,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Remove fractional part from literal, for example `42.0f32` into `42` let src = src.trim_end_matches(&checked_ty.to_string()); let len = src.split('.').next().unwrap().len(); - expr.span.with_lo(expr.span.lo() + BytePos(len as u32)) + span.with_lo(span.lo() + BytePos(len as u32)) } else { let len = src.trim_end_matches(&checked_ty.to_string()).len(); - expr.span.with_lo(expr.span.lo() + BytePos(len as u32)) + span.with_lo(span.lo() + BytePos(len as u32)) }, if expr.precedence() < ExprPrecedence::Unambiguous { // Readd `)` diff --git a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs index 72f8793d783..0037d5ac042 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs @@ -367,20 +367,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .collect(); // Find an identifier with which this trait was imported (note that `_` doesn't count). - let any_id = import_items.iter().find_map(|item| { - if item.ident.name != kw::Underscore { Some(item.ident) } else { None } - }); - if let Some(any_id) = any_id { - if any_id.name == kw::Empty { - // Glob import, so just use its name. - return None; - } else { - return Some(format!("{any_id}")); + for item in import_items.iter() { + let (_, kind) = item.expect_use(); + match kind { + hir::UseKind::Single(ident) => { + if ident.name != kw::Underscore { + return Some(format!("{}", ident.name)); + } + } + hir::UseKind::Glob => return None, // Glob import, so just use its name. + hir::UseKind::ListStem => unreachable!(), } } - // All that is left is `_`! We need to use the full path. It doesn't matter which one we pick, - // so just take the first one. + // All that is left is `_`! We need to use the full path. It doesn't matter which one we + // pick, so just take the first one. match import_items[0].kind { ItemKind::Use(path, _) => Some( path.segments diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 1a1540f505d..cdfae51583b 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -533,7 +533,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } _ => { - intravisit::walk_pat(self, p); + let _ = intravisit::walk_pat(self, p); } } ControlFlow::Continue(()) @@ -556,7 +556,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { method_name, sugg_let: None, }; - let_visitor.visit_body(&body); + let _ = let_visitor.visit_body(&body); if let Some(sugg_let) = let_visitor.sugg_let && let Some(self_ty) = self.node_ty_opt(sugg_let.init_hir_id) { @@ -1204,13 +1204,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } Some( Node::Item(hir::Item { - ident, - kind: hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..), + kind: + hir::ItemKind::Trait(_, _, ident, ..) + | hir::ItemKind::TraitAlias(ident, ..), .. }) // We may also encounter unsatisfied GAT or method bounds | Node::TraitItem(hir::TraitItem { ident, .. }) - | Node::ImplItem(hir::ImplItem { ident, .. }), + | Node::ImplItem(hir::ImplItem { ident, .. }) ) => { skip_list.insert(p); let entry = spanned_predicates.entry(ident.span); @@ -3960,8 +3961,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } Node::Item(hir::Item { - kind: hir::ItemKind::Trait(.., bounds, _), - ident, + kind: hir::ItemKind::Trait(_, _, ident, _, bounds, _), .. }) => { let (sp, sep, article) = if bounds.is_empty() { diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 3d1c61a9c34..f1f956779c9 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1250,7 +1250,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match opt_def_id { Some(def_id) => match self.tcx.hir_get_if_local(def_id) { Some(hir::Node::Item(hir::Item { - kind: hir::ItemKind::Const(_, _, body_id), + kind: hir::ItemKind::Const(_, _, _, body_id), .. })) => match self.tcx.hir_node(body_id.hir_id) { hir::Node::Expr(expr) => { @@ -1724,7 +1724,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Require `..` if struct has non_exhaustive attribute. - let non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did().is_local(); + let non_exhaustive = variant.field_list_has_applicable_non_exhaustive(); if non_exhaustive && !has_rest_pat { self.error_foreign_non_exhaustive_spat(pat, adt.variant_descr(), fields.is_empty()); } diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 37f3786c00a..fc98a603dd8 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -1862,8 +1862,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// /// (1.) Are we borrowing data owned by the parent closure? We can determine if /// that is the case by checking if the parent capture is by move, EXCEPT if we -/// apply a deref projection, which means we're reborrowing a reference that we -/// captured by move. +/// apply a deref projection of an immutable reference, reborrows of immutable +/// references which aren't restricted to the LUB of the lifetimes of the deref +/// chain. This is why `&'short mut &'long T` can be reborrowed as `&'long T`. /// /// ```rust /// let x = &1i32; // Let's call this lifetime `'1`. @@ -1902,10 +1903,22 @@ fn should_reborrow_from_env_of_parent_coroutine_closure<'tcx>( ) -> bool { // (1.) (!parent_capture.is_by_ref() - && !matches!( - child_capture.place.projections.get(parent_capture.place.projections.len()), - Some(Projection { kind: ProjectionKind::Deref, .. }) - )) + // This is just inlined `place.deref_tys()` but truncated to just + // the child projections. Namely, look for a `&T` deref, since we + // can always extend `&'short mut &'long T` to `&'long T`. + && !child_capture + .place + .projections + .iter() + .enumerate() + .skip(parent_capture.place.projections.len()) + .any(|(idx, proj)| { + matches!(proj.kind, ProjectionKind::Deref) + && matches!( + child_capture.place.ty_before_projection(idx).kind(), + ty::Ref(.., ty::Mutability::Not) + ) + })) // (2.) || matches!(child_capture.info.capture_kind, UpvarCapture::ByRef(ty::BorrowKind::Mutable)) } diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index 9c9660cf504..e3673935664 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -7,7 +7,6 @@ edition = "2024" # tidy-alphabetical-start rustc-rayon = { version = "0.5.0" } rustc-rayon-core = { version = "0.5.0" } -rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_ast_lowering = { path = "../rustc_ast_lowering" } rustc_ast_passes = { path = "../rustc_ast_passes" } @@ -41,7 +40,6 @@ rustc_privacy = { path = "../rustc_privacy" } rustc_query_impl = { path = "../rustc_query_impl" } rustc_query_system = { path = "../rustc_query_system" } rustc_resolve = { path = "../rustc_resolve" } -rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } @@ -52,6 +50,11 @@ rustc_ty_utils = { path = "../rustc_ty_utils" } tracing = "0.1" # tidy-alphabetical-end +[dev-dependencies] +# tidy-alphabetical-start +rustc_abi = { path = "../rustc_abi" } +# tidy-alphabetical-end + [features] # tidy-alphabetical-start llvm = ['dep:rustc_codegen_llvm'] diff --git a/compiler/rustc_interface/src/callbacks.rs b/compiler/rustc_interface/src/callbacks.rs index f66b9eb3a28..7c6b7157f71 100644 --- a/compiler/rustc_interface/src/callbacks.rs +++ b/compiler/rustc_interface/src/callbacks.rs @@ -14,6 +14,7 @@ use std::fmt; use rustc_errors::{DiagInner, TRACK_DIAGNOSTIC}; use rustc_middle::dep_graph::{DepNodeExt, TaskDepsRef}; use rustc_middle::ty::tls; +use rustc_query_impl::QueryCtxt; use rustc_query_system::dep_graph::dep_node::default_dep_kind_debug; use rustc_query_system::dep_graph::{DepContext, DepKind, DepNode}; @@ -41,9 +42,7 @@ fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) { fn track_diagnostic<R>(diagnostic: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R { tls::with_context_opt(|icx| { if let Some(icx) = icx { - if let Some(diagnostics) = icx.diagnostics { - diagnostics.lock().extend(Some(diagnostic.clone())); - } + icx.tcx.dep_graph.record_diagnostic(QueryCtxt::new(icx.tcx), &diagnostic); // Diagnostics are tracked, we can ignore the dependency. let icx = tls::ImplicitCtxt { task_deps: TaskDepsRef::Ignore, ..icx.clone() }; diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index b4892e73842..9dccd4a0552 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -441,7 +441,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { // so we will continue to exclude them for compatibility. // // The documentation on `ExternCrate` is not used at the moment so no need to warn for it. - if let hir::ItemKind::Impl(..) | hir::ItemKind::Use(..) | hir::ItemKind::ExternCrate(_) = + if let hir::ItemKind::Impl(..) | hir::ItemKind::Use(..) | hir::ItemKind::ExternCrate(..) = it.kind { return; @@ -545,21 +545,21 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { return; } let (def, ty) = match item.kind { - hir::ItemKind::Struct(_, ast_generics) => { + hir::ItemKind::Struct(_, _, ast_generics) => { if !ast_generics.params.is_empty() { return; } let def = cx.tcx.adt_def(item.owner_id); (def, Ty::new_adt(cx.tcx, def, ty::List::empty())) } - hir::ItemKind::Union(_, ast_generics) => { + hir::ItemKind::Union(_, _, ast_generics) => { if !ast_generics.params.is_empty() { return; } let def = cx.tcx.adt_def(item.owner_id); (def, Ty::new_adt(cx.tcx, def, ty::List::empty())) } - hir::ItemKind::Enum(_, ast_generics) => { + hir::ItemKind::Enum(_, _, ast_generics) => { if !ast_generics.params.is_empty() { return; } @@ -1416,7 +1416,7 @@ impl TypeAliasBounds { impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) { - let hir::ItemKind::TyAlias(hir_ty, generics) = item.kind else { return }; + let hir::ItemKind::TyAlias(_, hir_ty, generics) = item.kind else { return }; // There must not be a where clause. if generics.predicates.is_empty() { @@ -2119,9 +2119,9 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { use rustc_middle::middle::resolve_bound_vars::ResolvedArg; let def_id = item.owner_id.def_id; - if let hir::ItemKind::Struct(_, hir_generics) - | hir::ItemKind::Enum(_, hir_generics) - | hir::ItemKind::Union(_, hir_generics) = item.kind + if let hir::ItemKind::Struct(_, _, hir_generics) + | hir::ItemKind::Enum(_, _, hir_generics) + | hir::ItemKind::Union(_, _, hir_generics) = item.kind { let inferred_outlives = cx.tcx.inferred_outlives_of(def_id); if inferred_outlives.is_empty() { @@ -2257,7 +2257,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { // generics, except for tuple struct, which have the `where` // after the fields of the struct. let full_where_span = - if let hir::ItemKind::Struct(hir::VariantData::Tuple(..), _) = item.kind { + if let hir::ItemKind::Struct(_, hir::VariantData::Tuple(..), _) = item.kind { where_span } else { hir_generics.span.shrink_to_hi().to(where_span) diff --git a/compiler/rustc_lint/src/default_could_be_derived.rs b/compiler/rustc_lint/src/default_could_be_derived.rs index 58efca5e994..78d129642dc 100644 --- a/compiler/rustc_lint/src/default_could_be_derived.rs +++ b/compiler/rustc_lint/src/default_could_be_derived.rs @@ -93,7 +93,11 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived { let orig_fields = match cx.tcx.hir_get_if_local(type_def_id) { Some(hir::Node::Item(hir::Item { kind: - hir::ItemKind::Struct(hir::VariantData::Struct { fields, recovered: _ }, _generics), + hir::ItemKind::Struct( + _, + hir::VariantData::Struct { fields, recovered: _ }, + _generics, + ), .. })) => fields.iter().map(|f| (f.ident.name, f)).collect::<FxHashMap<_, _>>(), _ => return, diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 1f999bbea5f..b359ee790a5 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -308,18 +308,18 @@ impl<'tcx> LateLintPass<'tcx> for TypeIr { [.., penultimate, segment] if penultimate.res.opt_def_id().is_some_and(is_mod_inherent) => { - (segment.ident.span, item.ident.span, "*") + (segment.ident.span, item.kind.ident().unwrap().span, "*") } [.., segment] if path.res.iter().flat_map(Res::opt_def_id).any(is_mod_inherent) - && let rustc_hir::UseKind::Single = kind => + && let rustc_hir::UseKind::Single(ident) = kind => { let (lo, snippet) = match cx.tcx.sess.source_map().span_to_snippet(path.span).as_deref() { Ok("self") => (path.span, "*"), _ => (segment.ident.span.shrink_to_hi(), "::*"), }; - (lo, if segment.ident == item.ident { lo } else { item.ident.span }, snippet) + (lo, if segment.ident == ident { lo } else { ident.span }, snippet) } _ => return, }; diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs index 35db8632625..dea7c8ac708 100644 --- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs +++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs @@ -39,7 +39,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable { let def_id = item.owner_id.to_def_id(); // NOTE(nbdd0121): use `dyn_compatibility_violations` instead of `is_dyn_compatible` because // the latter will report `where_clause_object_safety` lint. - if let hir::ItemKind::Trait(_, _, _, _, _) = item.kind + if let hir::ItemKind::Trait(_, _, ident, ..) = item.kind && cx.tcx.is_dyn_compatible(def_id) { let direct_super_traits_iter = cx @@ -51,7 +51,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable { cx.emit_span_lint( MULTIPLE_SUPERTRAIT_UPCASTABLE, cx.tcx.def_span(def_id), - crate::lints::MultipleSupertraitUpcastable { ident: item.ident }, + crate::lints::MultipleSupertraitUpcastable { ident }, ); } } diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 0890890d12c..f8e0a94f9ec 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -181,10 +181,10 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { && parent_opt_item_name != Some(kw::Underscore) && let Some(parent) = parent.as_local() && let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent) - && let ItemKind::Const(ty, _, _) = item.kind + && let ItemKind::Const(ident, ty, _, _) = item.kind && let TyKind::Tup(&[]) = ty.kind { - Some(item.ident.span) + Some(ident.span) } else { None }; @@ -238,7 +238,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { }, ) } - ItemKind::Macro(_macro, MacroKind::Bang) + ItemKind::Macro(_, _macro, MacroKind::Bang) if cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) => { cx.emit_span_lint( diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 9e4fdd2b3ce..715e3506ab8 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -415,8 +415,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { } fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { - if let hir::ItemKind::Mod(_) = it.kind { - self.check_snake_case(cx, "module", &it.ident); + if let hir::ItemKind::Mod(ident, _) = it.kind { + self.check_snake_case(cx, "module", &ident); } } @@ -498,11 +498,13 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { let attrs = cx.tcx.hir_attrs(it.hir_id()); match it.kind { - hir::ItemKind::Static(..) if !ast::attr::contains_name(attrs, sym::no_mangle) => { - NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident); + hir::ItemKind::Static(ident, ..) + if !ast::attr::contains_name(attrs, sym::no_mangle) => + { + NonUpperCaseGlobals::check_upper_case(cx, "static variable", &ident); } - hir::ItemKind::Const(..) => { - NonUpperCaseGlobals::check_upper_case(cx, "constant", &it.ident); + hir::ItemKind::Const(ident, ..) => { + NonUpperCaseGlobals::check_upper_case(cx, "constant", &ident); } _ => {} } diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 7be48a769fe..7109fefbe78 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1193,9 +1193,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { }; } - let is_non_exhaustive = - def.non_enum_variant().is_field_list_non_exhaustive(); - if is_non_exhaustive && !def.did().is_local() { + if def.non_enum_variant().field_list_has_applicable_non_exhaustive() { return FfiUnsafe { ty, reason: if def.is_struct() { @@ -1248,14 +1246,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { }; } - use improper_ctypes::{ - check_non_exhaustive_variant, non_local_and_non_exhaustive, - }; + use improper_ctypes::check_non_exhaustive_variant; - let non_local_def = non_local_and_non_exhaustive(def); + let non_exhaustive = def.variant_list_has_applicable_non_exhaustive(); // Check the contained variants. let ret = def.variants().iter().try_for_each(|variant| { - check_non_exhaustive_variant(non_local_def, variant) + check_non_exhaustive_variant(non_exhaustive, variant) .map_break(|reason| FfiUnsafe { ty, reason, help: None })?; match self.check_variant_for_ffi(acc, ty, def, variant, args) { @@ -1664,7 +1660,7 @@ impl ImproperCTypesDefinitions { && cx.tcx.sess.target.os == "aix" && !adt_def.all_fields().next().is_none() { - let struct_variant_data = item.expect_struct().0; + let struct_variant_data = item.expect_struct().1; for (index, ..) in struct_variant_data.fields().iter().enumerate() { // Struct fields (after the first field) are checked for the // power alignment rule, as fields after the first are likely @@ -1696,9 +1692,9 @@ impl ImproperCTypesDefinitions { impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { match item.kind { - hir::ItemKind::Static(ty, ..) - | hir::ItemKind::Const(ty, ..) - | hir::ItemKind::TyAlias(ty, ..) => { + hir::ItemKind::Static(_, ty, ..) + | hir::ItemKind::Const(_, ty, ..) + | hir::ItemKind::TyAlias(_, ty, ..) => { self.check_ty_maybe_containing_foreign_fnptr( cx, ty, @@ -1765,7 +1761,7 @@ declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]); 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 { + 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 Ok(layout) = cx.layout_of(ty) else { return }; diff --git a/compiler/rustc_lint/src/types/improper_ctypes.rs b/compiler/rustc_lint/src/types/improper_ctypes.rs index 1030101c545..13afa540afc 100644 --- a/compiler/rustc_lint/src/types/improper_ctypes.rs +++ b/compiler/rustc_lint/src/types/improper_ctypes.rs @@ -15,13 +15,13 @@ use crate::fluent_generated as fluent; /// so we don't need the lint to account for it. /// e.g. going from enum Foo { A, B, C } to enum Foo { A, B, C, D(u32) }. pub(crate) fn check_non_exhaustive_variant( - non_local_def: bool, + non_exhaustive_variant_list: bool, variant: &ty::VariantDef, ) -> ControlFlow<DiagMessage, ()> { // non_exhaustive suggests it is possible that someone might break ABI // see: https://github.com/rust-lang/rust/issues/44109#issuecomment-537583344 // so warn on complex enums being used outside their crate - if non_local_def { + if non_exhaustive_variant_list { // which is why we only warn about really_tagged_union reprs from https://rust.tf/rfc2195 // with an enum like `#[repr(u8)] enum Enum { A(DataA), B(DataB), }` // but exempt enums with unit ctors like C's (e.g. from rust-bindgen) @@ -30,8 +30,7 @@ pub(crate) fn check_non_exhaustive_variant( } } - let non_exhaustive_variant_fields = variant.is_field_list_non_exhaustive(); - if non_exhaustive_variant_fields && !variant.def_id.is_local() { + if variant.field_list_has_applicable_non_exhaustive() { return ControlFlow::Break(fluent::lint_improper_ctypes_non_exhaustive_variant); } @@ -42,10 +41,3 @@ fn variant_has_complex_ctor(variant: &ty::VariantDef) -> bool { // CtorKind::Const means a "unit" ctor !matches!(variant.ctor_kind(), Some(CtorKind::Const)) } - -// non_exhaustive suggests it is possible that someone might break ABI -// see: https://github.com/rust-lang/rust/issues/44109#issuecomment-537583344 -// so warn on complex enums being used outside their crate -pub(crate) fn non_local_and_non_exhaustive(def: ty::AdtDef<'_>) -> bool { - def.is_variant_list_non_exhaustive() && !def.did().is_local() -} diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 3d1f3b2cd4d..6692ea73540 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -241,7 +241,7 @@ fn main() { println!("cargo:rustc-link-lib=kstat"); } - if (target.starts_with("arm") && !target.contains("freebsd")) + if (target.starts_with("arm") && !target.contains("freebsd")) && !target.contains("ohos") || target.starts_with("mips-") || target.starts_with("mipsel-") || target.starts_with("powerpc-") @@ -371,6 +371,7 @@ fn main() { || target.contains("freebsd") || target.contains("windows-gnullvm") || target.contains("aix") + || target.contains("ohos") { "c++" } else if target.contains("netbsd") && llvm_static_stdcpp.is_some() { diff --git a/compiler/rustc_log/Cargo.toml b/compiler/rustc_log/Cargo.toml index 30f6e9ba805..c673d51a1d4 100644 --- a/compiler/rustc_log/Cargo.toml +++ b/compiler/rustc_log/Cargo.toml @@ -11,11 +11,6 @@ tracing-subscriber = { version = "0.3.3", default-features = false, features = [ tracing-tree = "0.3.1" # tidy-alphabetical-end -[dev-dependencies] -# tidy-alphabetical-start -rustc_span = { path = "../rustc_span" } -# tidy-alphabetical-end - [features] # tidy-alphabetical-start max_level_info = ['tracing/max_level_info'] diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs index d0ef82f4a6c..49dd388f14c 100644 --- a/compiler/rustc_log/src/lib.rs +++ b/compiler/rustc_log/src/lib.rs @@ -9,17 +9,12 @@ //! [dependencies] //! rustc_ast = { path = "../rust/compiler/rustc_ast" } //! rustc_log = { path = "../rust/compiler/rustc_log" } -//! rustc_span = { path = "../rust/compiler/rustc_span" } //! ``` //! //! ``` //! fn main() { //! rustc_log::init_logger(rustc_log::LoggerConfig::from_env("LOG")).unwrap(); -//! -//! let edition = rustc_span::edition::Edition::Edition2021; -//! rustc_span::create_session_globals_then(edition, None, || { -//! /* ... */ -//! }); +//! /* ... */ //! } //! ``` //! diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index 1f5d41014d4..08dcc3d519a 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -6,7 +6,6 @@ edition = "2024" [dependencies] # tidy-alphabetical-start bitflags = "2.4.1" -libc = "0.2" libloading = "0.8.0" odht = { version = "0.3.1", features = ["nightly"] } rustc_abi = { path = "../rustc_abi" } @@ -30,3 +29,8 @@ rustc_target = { path = "../rustc_target" } tempfile = "3.2" tracing = "0.1" # tidy-alphabetical-end + +[target.'cfg(target_os = "aix")'.dependencies] +# tidy-alphabetical-start +libc = "0.2" +# tidy-alphabetical-end diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index e60904eebeb..f6cf218db9d 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1053,15 +1053,15 @@ impl<'a> CrateMetadataRef<'a> { attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>(); ( trait_name, - SyntaxExtensionKind::Derive(Box::new(DeriveProcMacro { client })), + SyntaxExtensionKind::Derive(Arc::new(DeriveProcMacro { client })), helper_attrs, ) } ProcMacro::Attr { name, client } => { - (name, SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client })), Vec::new()) + (name, SyntaxExtensionKind::Attr(Arc::new(AttrProcMacro { client })), Vec::new()) } ProcMacro::Bang { name, client } => { - (name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new()) + (name, SyntaxExtensionKind::Bang(Arc::new(BangProcMacro { client })), Vec::new()) } }; diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 2b9113242aa..7ab3d432bdf 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -843,9 +843,8 @@ fn analyze_attr(attr: &impl AttributeExt, state: &mut AnalyzeAttrState<'_>) -> b } } } - } else if attr.path().starts_with(&[sym::diagnostic]) && attr.path().len() == 2 { - should_encode = - rustc_feature::is_stable_diagnostic_attribute(attr.path()[1], state.features); + } else if let &[sym::diagnostic, seg] = &*attr.path() { + should_encode = rustc_feature::is_stable_diagnostic_attribute(seg, state.features); } else { should_encode = true; } @@ -1836,7 +1835,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_info_for_macro(&mut self, def_id: LocalDefId) { let tcx = self.tcx; - let hir::ItemKind::Macro(macro_def, _) = tcx.hir_expect_item(def_id).kind else { bug!() }; + let (_, macro_def, _) = tcx.hir_expect_item(def_id).expect_macro(); self.tables.is_macro_rules.set(def_id.local_def_index, macro_def.macro_rules); record!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body); } diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 7525aeb9227..f967d8b92c7 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -79,6 +79,7 @@ rustc_query_append!(define_dep_nodes![ [] fn Null() -> (), /// We use this to create a forever-red node. [] fn Red() -> (), + [] fn SideEffect() -> (), [] fn TraitSelect() -> (), [] fn CompileCodegenUnit() -> (), [] fn CompileMonoItem() -> (), diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 2090c3e6da6..c927538b4cf 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -46,6 +46,7 @@ impl Deps for DepsType { const DEP_KIND_NULL: DepKind = dep_kinds::Null; const DEP_KIND_RED: DepKind = dep_kinds::Red; + const DEP_KIND_SIDE_EFFECT: DepKind = dep_kinds::SideEffect; const DEP_KIND_MAX: u16 = dep_node::DEP_KIND_VARIANTS - 1; } diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index c61c7a4fb02..2e589150d3e 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -385,7 +385,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn hir_get_module(self, module: LocalModDefId) -> (&'tcx Mod<'tcx>, Span, HirId) { let hir_id = HirId::make_owner(module.to_local_def_id()); match self.hir_owner_node(hir_id.owner) { - OwnerNode::Item(&Item { span, kind: ItemKind::Mod(m), .. }) => (m, span, hir_id), + OwnerNode::Item(&Item { span, kind: ItemKind::Mod(_, m), .. }) => (m, span, hir_id), OwnerNode::Crate(item) => (item, item.spans.inner_span, hir_id), node => panic!("not a module: {node:?}"), } @@ -847,7 +847,7 @@ impl<'tcx> TyCtxt<'tcx> { // A `Ctor` doesn't have an identifier itself, but its parent // struct/variant does. Compare with `hir::Map::span`. Node::Ctor(..) => match self.parent_hir_node(id) { - Node::Item(item) => Some(item.ident), + Node::Item(item) => Some(item.kind.ident().unwrap()), Node::Variant(variant) => Some(variant.ident), _ => unreachable!(), }, @@ -894,18 +894,14 @@ impl<'hir> Map<'hir> { } fn named_span(item_span: Span, ident: Ident, generics: Option<&Generics<'_>>) -> Span { - if ident.name != kw::Empty { - let mut span = until_within(item_span, ident.span); - if let Some(g) = generics - && !g.span.is_dummy() - && let Some(g_span) = g.span.find_ancestor_inside(item_span) - { - span = span.to(g_span); - } - span - } else { - item_span + let mut span = until_within(item_span, ident.span); + if let Some(g) = generics + && !g.span.is_dummy() + && let Some(g_span) = g.span.find_ancestor_inside(item_span) + { + span = span.to(g_span); } + span } let span = match self.tcx.hir_node(hir_id) { @@ -936,7 +932,7 @@ impl<'hir> Map<'hir> { }) => until_within(*outer_span, generics.where_clause_span), // Constants and Statics. Node::Item(Item { - kind: ItemKind::Const(ty, ..) | ItemKind::Static(ty, ..), + kind: ItemKind::Const(_, ty, ..) | ItemKind::Static(_, ty, ..), span: outer_span, .. }) @@ -957,7 +953,7 @@ impl<'hir> Map<'hir> { }) => until_within(*outer_span, ty.span), // With generics and bounds. Node::Item(Item { - kind: ItemKind::Trait(_, _, generics, bounds, _), + kind: ItemKind::Trait(_, _, _, generics, bounds, _), span: outer_span, .. }) @@ -977,7 +973,13 @@ impl<'hir> Map<'hir> { // SyntaxContext of the path. path.span.find_ancestor_in_same_ctxt(item.span).unwrap_or(item.span) } - _ => named_span(item.span, item.ident, item.kind.generics()), + _ => { + if let Some(ident) = item.kind.ident() { + named_span(item.span, ident, item.kind.generics()) + } else { + item.span + } + } }, Node::Variant(variant) => named_span(variant.span, variant.ident, None), Node::ImplItem(item) => named_span(item.span, item.ident, Some(item.generics)), @@ -1327,7 +1329,7 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> { self.items.push(item.item_id()); // Items that are modules are handled here instead of in visit_mod. - if let ItemKind::Mod(module) = &item.kind { + if let ItemKind::Mod(_, module) = &item.kind { self.submodules.push(item.owner_id); // A module collector does not recurse inside nested modules. if self.crate_collector { diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index a94ead161c3..0cc72a261a5 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -174,6 +174,7 @@ impl CodegenFnAttrs { /// * `#[linkage]` is present pub fn contains_extern_indicator(&self) -> bool { self.flags.contains(CodegenFnAttrFlags::NO_MANGLE) + || self.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) || self.export_name.is_some() || match self.linkage { // These are private, so make sure we don't try to consider diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index 8c6b11a681e..e26575b552e 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -194,7 +194,6 @@ pub struct Mapping { #[derive(TyEncodable, TyDecodable, Hash, HashStable)] pub struct FunctionCoverageInfo { pub function_source_hash: u64, - pub body_span: Span, /// Used in conjunction with `priority_list` to create physical counters /// and counter expressions, after MIR optimizations. diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 573f7895da2..5a038b27337 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -620,9 +620,8 @@ fn write_function_coverage_info( function_coverage_info: &coverage::FunctionCoverageInfo, w: &mut dyn io::Write, ) -> io::Result<()> { - let coverage::FunctionCoverageInfo { body_span, mappings, .. } = function_coverage_info; + let coverage::FunctionCoverageInfo { mappings, .. } = function_coverage_info; - writeln!(w, "{INDENT}coverage body span: {body_span:?}")?; for coverage::Mapping { kind, span } in mappings { writeln!(w, "{INDENT}coverage {kind:?} => {span:?};")?; } diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index f05a798949b..d59b6df44ed 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -774,6 +774,15 @@ impl BorrowKind { } } +impl<'tcx> NullOp<'tcx> { + pub fn ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { + match self { + NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) => tcx.types.usize, + NullOp::UbChecks | NullOp::ContractChecks => tcx.types.bool, + } + } +} + impl<'tcx> UnOp { pub fn ty(&self, tcx: TyCtxt<'tcx>, arg_ty: Ty<'tcx>) -> Ty<'tcx> { match self { diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index e66958dfcb8..14e3ce8bef6 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs @@ -11,7 +11,7 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, LocalDefId, Stab use rustc_hir::definitions::DefPathHash; use rustc_index::{Idx, IndexVec}; use rustc_macros::{Decodable, Encodable}; -use rustc_query_system::query::QuerySideEffects; +use rustc_query_system::query::QuerySideEffect; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixedSize, MemDecoder}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_session::Session; @@ -55,9 +55,9 @@ pub struct OnDiskCache { // The complete cache data in serialized form. serialized_data: RwLock<Option<Mmap>>, - // Collects all `QuerySideEffects` created during the current compilation + // Collects all `QuerySideEffect` created during the current compilation // session. - current_side_effects: Lock<FxHashMap<DepNodeIndex, QuerySideEffects>>, + current_side_effects: Lock<FxHashMap<DepNodeIndex, QuerySideEffect>>, file_index_to_stable_id: FxHashMap<SourceFileIndex, EncodedSourceFileId>, @@ -68,7 +68,7 @@ pub struct OnDiskCache { // `serialized_data`. query_result_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>, - // A map from dep-node to the position of any associated `QuerySideEffects` in + // A map from dep-node to the position of any associated `QuerySideEffect` in // `serialized_data`. prev_side_effects_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>, @@ -270,10 +270,10 @@ impl OnDiskCache { .current_side_effects .borrow() .iter() - .map(|(dep_node_index, side_effects)| { + .map(|(dep_node_index, side_effect)| { let pos = AbsoluteBytePos::new(encoder.position()); let dep_node_index = SerializedDepNodeIndex::new(dep_node_index.index()); - encoder.encode_tagged(dep_node_index, side_effects); + encoder.encode_tagged(dep_node_index, side_effect); (dep_node_index, pos) }) @@ -352,24 +352,23 @@ impl OnDiskCache { }) } - /// Loads a `QuerySideEffects` created during the previous compilation session. - pub fn load_side_effects( + /// Loads a `QuerySideEffect` created during the previous compilation session. + pub fn load_side_effect( &self, tcx: TyCtxt<'_>, dep_node_index: SerializedDepNodeIndex, - ) -> QuerySideEffects { - let side_effects: Option<QuerySideEffects> = + ) -> Option<QuerySideEffect> { + let side_effect: Option<QuerySideEffect> = self.load_indexed(tcx, dep_node_index, &self.prev_side_effects_index); - - side_effects.unwrap_or_default() + side_effect } - /// Stores a `QuerySideEffects` emitted during the current compilation session. - /// Anything stored like this will be available via `load_side_effects` in + /// Stores a `QuerySideEffect` emitted during the current compilation session. + /// Anything stored like this will be available via `load_side_effect` in /// the next compilation session. - pub fn store_side_effects(&self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects) { + pub fn store_side_effect(&self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect) { let mut current_side_effects = self.current_side_effects.borrow_mut(); - let prev = current_side_effects.insert(dep_node_index, side_effects); + let prev = current_side_effects.insert(dep_node_index, side_effect); debug_assert!(prev.is_none()); } @@ -395,21 +394,6 @@ impl OnDiskCache { opt_value } - /// Stores side effect emitted during computation of an anonymous query. - /// Since many anonymous queries can share the same `DepNode`, we aggregate - /// them -- as opposed to regular queries where we assume that there is a - /// 1:1 relationship between query-key and `DepNode`. - pub fn store_side_effects_for_anon_node( - &self, - dep_node_index: DepNodeIndex, - side_effects: QuerySideEffects, - ) { - let mut current_side_effects = self.current_side_effects.borrow_mut(); - - let x = current_side_effects.entry(dep_node_index).or_default(); - x.append(side_effects); - } - fn load_indexed<'tcx, T>( &self, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 1056644b813..bbcd509c558 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -28,6 +28,7 @@ use tracing::instrument; use crate::middle::region; use crate::mir::interpret::AllocId; use crate::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp}; +use crate::thir::visit::for_each_immediate_subpat; use crate::ty::adjustment::PointerCoercion; use crate::ty::layout::IntegerExt; use crate::ty::{ @@ -672,27 +673,7 @@ impl<'tcx> Pat<'tcx> { return; } - use PatKind::*; - match &self.kind { - Wild - | Never - | Range(..) - | Binding { subpattern: None, .. } - | Constant { .. } - | Error(_) => {} - AscribeUserType { subpattern, .. } - | Binding { subpattern: Some(subpattern), .. } - | Deref { subpattern } - | DerefPattern { subpattern, .. } - | ExpandedConstant { subpattern, .. } => subpattern.walk_(it), - Leaf { subpatterns } | Variant { subpatterns, .. } => { - subpatterns.iter().for_each(|field| field.pattern.walk_(it)) - } - Or { pats } => pats.iter().for_each(|p| p.walk_(it)), - Array { box prefix, slice, box suffix } | Slice { box prefix, slice, box suffix } => { - prefix.iter().chain(slice.as_deref()).chain(suffix.iter()).for_each(|p| p.walk_(it)) - } - } + for_each_immediate_subpat(self, |p| p.walk_(it)); } /// Whether the pattern has a `PatKind::Error` nested within. diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index d208692f4e7..7d62ab7970d 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -240,36 +240,45 @@ pub fn walk_pat<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( visitor: &mut V, pat: &'thir Pat<'tcx>, ) { - use PatKind::*; + for_each_immediate_subpat(pat, |p| visitor.visit_pat(p)); +} + +/// Invokes `callback` on each immediate subpattern of `pat`, if any. +/// A building block for assembling THIR pattern visitors. +pub(crate) fn for_each_immediate_subpat<'a, 'tcx>( + pat: &'a Pat<'tcx>, + mut callback: impl FnMut(&'a Pat<'tcx>), +) { match &pat.kind { - AscribeUserType { subpattern, ascription: _ } - | Deref { subpattern } - | DerefPattern { subpattern, .. } - | Binding { subpattern: Some(subpattern), .. } => visitor.visit_pat(subpattern), - Binding { .. } | Wild | Never | Error(_) => {} - Variant { subpatterns, adt_def: _, args: _, variant_index: _ } | Leaf { subpatterns } => { - for subpattern in subpatterns { - visitor.visit_pat(&subpattern.pattern); + PatKind::Wild + | PatKind::Binding { subpattern: None, .. } + | PatKind::Constant { value: _ } + | PatKind::Range(_) + | PatKind::Never + | PatKind::Error(_) => {} + + PatKind::AscribeUserType { subpattern, .. } + | PatKind::Binding { subpattern: Some(subpattern), .. } + | PatKind::Deref { subpattern } + | PatKind::DerefPattern { subpattern, .. } + | PatKind::ExpandedConstant { subpattern, .. } => callback(subpattern), + + PatKind::Variant { subpatterns, .. } | PatKind::Leaf { subpatterns } => { + for field_pat in subpatterns { + callback(&field_pat.pattern); } } - Constant { value: _ } => {} - ExpandedConstant { def_id: _, is_inline: _, subpattern } => visitor.visit_pat(subpattern), - Range(_) => {} - Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => { - for subpattern in prefix.iter() { - visitor.visit_pat(subpattern); - } - if let Some(pat) = slice { - visitor.visit_pat(pat); - } - for subpattern in suffix.iter() { - visitor.visit_pat(subpattern); + + PatKind::Slice { prefix, slice, suffix } | PatKind::Array { prefix, slice, suffix } => { + for pat in prefix.iter().chain(slice.as_deref()).chain(suffix) { + callback(pat); } } - Or { pats } => { - for pat in pats.iter() { - visitor.visit_pat(pat); + + PatKind::Or { pats } => { + for pat in pats { + callback(pat); } } - }; + } } diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index c1dc6a894ca..cb245c0aec4 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -327,11 +327,22 @@ impl<'tcx> AdtDef<'tcx> { } /// Returns `true` if the variant list of this ADT is `#[non_exhaustive]`. + /// + /// Note that this function will return `true` even if the ADT has been + /// defined in the crate currently being compiled. If that's not what you + /// want, see [`Self::variant_list_has_applicable_non_exhaustive`]. #[inline] pub fn is_variant_list_non_exhaustive(self) -> bool { self.flags().contains(AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE) } + /// Returns `true` if the variant list of this ADT is `#[non_exhaustive]` + /// and has been defined in another crate. + #[inline] + pub fn variant_list_has_applicable_non_exhaustive(self) -> bool { + self.is_variant_list_non_exhaustive() && !self.did().is_local() + } + /// Returns the kind of the ADT. #[inline] pub fn adt_kind(self) -> AdtKind { diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs index eaab8474dd2..5fc80bc7936 100644 --- a/compiler/rustc_middle/src/ty/context/tls.rs +++ b/compiler/rustc_middle/src/ty/context/tls.rs @@ -1,8 +1,6 @@ use std::{mem, ptr}; -use rustc_data_structures::sync::{self, Lock}; -use rustc_errors::DiagInner; -use thin_vec::ThinVec; +use rustc_data_structures::sync; use super::{GlobalCtxt, TyCtxt}; use crate::dep_graph::TaskDepsRef; @@ -22,10 +20,6 @@ pub struct ImplicitCtxt<'a, 'tcx> { /// `ty::query::plumbing` when executing a query. pub query: Option<QueryJobId>, - /// Where to store diagnostics for the current query job, if any. - /// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query. - pub diagnostics: Option<&'a Lock<ThinVec<DiagInner>>>, - /// Used to prevent queries from calling too deeply. pub query_depth: usize, @@ -37,13 +31,7 @@ pub struct ImplicitCtxt<'a, 'tcx> { impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> { pub fn new(gcx: &'tcx GlobalCtxt<'tcx>) -> Self { let tcx = TyCtxt { gcx }; - ImplicitCtxt { - tcx, - query: None, - diagnostics: None, - query_depth: 0, - task_deps: TaskDepsRef::Ignore, - } + ImplicitCtxt { tcx, query: None, query_depth: 0, task_deps: TaskDepsRef::Ignore } } } diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 881381a5ee6..d3abb3d64b8 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -142,8 +142,8 @@ pub fn suggest_arbitrary_trait_bound<'tcx>( if let Some((name, term)) = associated_ty { // FIXME: this case overlaps with code in TyCtxt::note_and_explain_type_err. // That should be extracted into a helper function. - if constraint.ends_with('>') { - constraint = format!("{}, {} = {}>", &constraint[..constraint.len() - 1], name, term); + if let Some(stripped) = constraint.strip_suffix('>') { + constraint = format!("{stripped}, {name} = {term}>"); } else { constraint.push_str(&format!("<{name} = {term}>")); } @@ -641,21 +641,19 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsSuggestableVisitor<'tcx> { } } - Alias(Projection, AliasTy { def_id, .. }) => { - if self.tcx.def_kind(def_id) != DefKind::AssocTy { - return ControlFlow::Break(()); - } + Alias(Projection, AliasTy { def_id, .. }) + if self.tcx.def_kind(def_id) != DefKind::AssocTy => + { + return ControlFlow::Break(()); } - Param(param) => { - // FIXME: It would be nice to make this not use string manipulation, - // but it's pretty hard to do this, since `ty::ParamTy` is missing - // sufficient info to determine if it is synthetic, and we don't - // always have a convenient way of getting `ty::Generics` at the call - // sites we invoke `IsSuggestable::is_suggestable`. - if param.name.as_str().starts_with("impl ") { - return ControlFlow::Break(()); - } + // FIXME: It would be nice to make this not use string manipulation, + // but it's pretty hard to do this, since `ty::ParamTy` is missing + // sufficient info to determine if it is synthetic, and we don't + // always have a convenient way of getting `ty::Generics` at the call + // sites we invoke `IsSuggestable::is_suggestable`. + Param(param) if param.name.as_str().starts_with("impl ") => { + return ControlFlow::Break(()); } _ => {} @@ -733,17 +731,13 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for MakeSuggestableFolder<'tcx> { } } - Param(param) => { - // FIXME: It would be nice to make this not use string manipulation, - // but it's pretty hard to do this, since `ty::ParamTy` is missing - // sufficient info to determine if it is synthetic, and we don't - // always have a convenient way of getting `ty::Generics` at the call - // sites we invoke `IsSuggestable::is_suggestable`. - if param.name.as_str().starts_with("impl ") { - return Err(()); - } - - t + // FIXME: It would be nice to make this not use string manipulation, + // but it's pretty hard to do this, since `ty::ParamTy` is missing + // sufficient info to determine if it is synthetic, and we don't + // always have a convenient way of getting `ty::Generics` at the call + // sites we invoke `IsSuggestable::is_suggestable`. + Param(param) if param.name.as_str().starts_with("impl ") => { + return Err(()); } _ => t, diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 4a5f6d80f24..855e5043e84 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -107,7 +107,7 @@ impl<'tcx> Ty<'tcx> { // For now, unions are always considered inhabited Adt(adt, _) if adt.is_union() => InhabitedPredicate::True, // Non-exhaustive ADTs from other crates are always considered inhabited - Adt(adt, _) if adt.is_variant_list_non_exhaustive() && !adt.did().is_local() => { + Adt(adt, _) if adt.variant_list_has_applicable_non_exhaustive() => { InhabitedPredicate::True } Never => InhabitedPredicate::False, diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index b99148f3368..980d20f9d3b 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -712,10 +712,7 @@ impl<'tcx> Instance<'tcx> { .. }) ); - // We also need to generate a shim if this is an AFIT. - let needs_rpitit_shim = - tcx.return_position_impl_trait_in_trait_shim_data(def).is_some(); - if needs_track_caller_shim || needs_rpitit_shim { + if needs_track_caller_shim { if tcx.is_closure_like(def) { debug!( " => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}", diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a508487c796..6bdd0a0647d 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -149,7 +149,6 @@ mod opaque_types; mod parameterized; mod predicate; mod region; -mod return_position_impl_trait_in_trait; mod rvalue_scopes; mod structural_impls; #[allow(hidden_glob_reexports)] @@ -1209,12 +1208,23 @@ impl VariantDef { } } - /// Is this field list non-exhaustive? + /// Returns `true` if the field list of this variant is `#[non_exhaustive]`. + /// + /// Note that this function will return `true` even if the type has been + /// defined in the crate currently being compiled. If that's not what you + /// want, see [`Self::field_list_has_applicable_non_exhaustive`]. #[inline] pub fn is_field_list_non_exhaustive(&self) -> bool { self.flags.intersects(VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE) } + /// Returns `true` if the field list of this variant is `#[non_exhaustive]` + /// and the type has been defined in another crate. + #[inline] + pub fn field_list_has_applicable_non_exhaustive(&self) -> bool { + self.is_field_list_non_exhaustive() && !self.def_id.is_local() + } + /// Computes the `Ident` of this variant by looking up the `Span` pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident { Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap()) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index d200b1437c5..3ef8ecc59e4 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3406,20 +3406,18 @@ define_print_and_forward_display! { } fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, Namespace, DefId)) { - // Iterate all local crate items no matter where they are defined. + // Iterate all (non-anonymous) local crate items no matter where they are defined. for id in tcx.hir_free_items() { if matches!(tcx.def_kind(id.owner_id), DefKind::Use) { continue; } let item = tcx.hir_item(id); - if item.ident.name == kw::Empty { - continue; - } + let Some(ident) = item.kind.ident() else { continue }; let def_id = item.owner_id.to_def_id(); let ns = tcx.def_kind(def_id).ns().unwrap_or(Namespace::TypeNS); - collect_fn(&item.ident, ns, def_id); + collect_fn(&ident, ns, def_id); } // Now take care of extern crate items. diff --git a/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs b/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs deleted file mode 100644 index 568e504b940..00000000000 --- a/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs +++ /dev/null @@ -1,95 +0,0 @@ -use rustc_hir::def_id::DefId; - -use crate::ty::{self, ExistentialPredicateStableCmpExt, TyCtxt}; - -impl<'tcx> TyCtxt<'tcx> { - /// Given a `def_id` of a trait or impl method, compute whether that method needs to - /// have an RPITIT shim applied to it for it to be dyn compatible. If so, return the - /// `def_id` of the RPITIT, and also the args of trait method that returns the RPITIT. - /// - /// NOTE that these args are not, in general, the same as than the RPITIT's args. They - /// are a subset of those args, since they do not include the late-bound lifetimes of - /// the RPITIT. Depending on the context, these will need to be dealt with in different - /// ways -- in codegen, it's okay to fill them with ReErased. - pub fn return_position_impl_trait_in_trait_shim_data( - self, - def_id: DefId, - ) -> Option<(DefId, ty::EarlyBinder<'tcx, ty::GenericArgsRef<'tcx>>)> { - let assoc_item = self.opt_associated_item(def_id)?; - - let (trait_item_def_id, opt_impl_def_id) = match assoc_item.container { - ty::AssocItemContainer::Impl => { - (assoc_item.trait_item_def_id?, Some(self.parent(def_id))) - } - ty::AssocItemContainer::Trait => (def_id, None), - }; - - let sig = self.fn_sig(trait_item_def_id); - - // Check if the trait returns an RPITIT. - let ty::Alias(ty::Projection, ty::AliasTy { def_id, .. }) = - *sig.skip_binder().skip_binder().output().kind() - else { - return None; - }; - if !self.is_impl_trait_in_trait(def_id) { - return None; - } - - let args = if let Some(impl_def_id) = opt_impl_def_id { - // Rebase the args from the RPITIT onto the impl trait ref, so we can later - // substitute them with the method args of the *impl* method, since that's - // the instance we're building a vtable shim for. - ty::GenericArgs::identity_for_item(self, trait_item_def_id).rebase_onto( - self, - self.parent(trait_item_def_id), - self.impl_trait_ref(impl_def_id) - .expect("expected impl trait ref from parent of impl item") - .instantiate_identity() - .args, - ) - } else { - // This is when we have a default trait implementation. - ty::GenericArgs::identity_for_item(self, trait_item_def_id) - }; - - Some((def_id, ty::EarlyBinder::bind(args))) - } - - /// Given a `DefId` of an RPITIT and its args, return the existential predicates - /// that corresponds to the RPITIT's bounds with the self type erased. - pub fn item_bounds_to_existential_predicates( - self, - def_id: DefId, - args: ty::GenericArgsRef<'tcx>, - ) -> &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { - let mut bounds: Vec<_> = self - .item_self_bounds(def_id) - .iter_instantiated(self, args) - .filter_map(|clause| { - clause - .kind() - .map_bound(|clause| match clause { - ty::ClauseKind::Trait(trait_pred) => Some(ty::ExistentialPredicate::Trait( - ty::ExistentialTraitRef::erase_self_ty(self, trait_pred.trait_ref), - )), - ty::ClauseKind::Projection(projection_pred) => { - Some(ty::ExistentialPredicate::Projection( - ty::ExistentialProjection::erase_self_ty(self, projection_pred), - )) - } - ty::ClauseKind::TypeOutlives(_) => { - // Type outlives bounds don't really turn into anything, - // since we must use an intersection region for the `dyn*`'s - // region anyways. - None - } - _ => unreachable!("unexpected clause in item bounds: {clause:?}"), - }) - .transpose() - }) - .collect(); - bounds.sort_by(|a, b| a.skip_binder().stable_cmp(self, &b.skip_binder())); - self.mk_poly_existential_predicates(&bounds) - } -} diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index d70d70a31a4..1534865cdd3 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -5,14 +5,12 @@ edition = "2024" [dependencies] # tidy-alphabetical-start -either = "1.5.0" itertools = "0.12" rustc_abi = { path = "../rustc_abi" } rustc_apfloat = "0.2.0" rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } -rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs index c6f3e22e95f..f2ce0c46dd3 100644 --- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs +++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs @@ -273,12 +273,12 @@ impl<'tcx> MatchPairTree<'tcx> { let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| { i == variant_index - || !v - .inhabited_predicate(cx.tcx, adt_def) - .instantiate(cx.tcx, args) - .apply_ignore_module(cx.tcx, cx.infcx.typing_env(cx.param_env)) - }) && (adt_def.did().is_local() - || !adt_def.is_variant_list_non_exhaustive()); + || !v.inhabited_predicate(cx.tcx, adt_def).instantiate(cx.tcx, args).apply( + cx.tcx, + cx.infcx.typing_env(cx.param_env), + cx.def_id.into(), + ) + }) && !adt_def.variant_list_has_applicable_non_exhaustive(); if irrefutable { None } else { Some(TestCase::Variant { adt_def, variant_index }) } } diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 2909dea98b7..c8b69a6ec62 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -563,7 +563,7 @@ fn construct_const<'a, 'tcx>( // Figure out what primary body this item has. let (span, const_ty_span) = match tcx.hir_node(hir_id) { Node::Item(hir::Item { - kind: hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _, _), + kind: hir::ItemKind::Static(_, ty, _, _) | hir::ItemKind::Const(_, ty, _, _), span, .. }) diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 17b22f25dbb..0e16f871b16 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -613,9 +613,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNo diag.span_note(span, fluent::mir_build_def_note); } - let is_variant_list_non_exhaustive = matches!(self.ty.kind(), - ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local()); - if is_variant_list_non_exhaustive { + let is_non_exhaustive = matches!(self.ty.kind(), + ty::Adt(def, _) if def.variant_list_has_applicable_non_exhaustive()); + if is_non_exhaustive { diag.note(fluent::mir_build_non_exhaustive_type_note); } else { diag.note(fluent::mir_build_type_note); diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index cbd29ba837e..095d3e75da1 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -1044,7 +1044,6 @@ fn find_fallback_pattern_typo<'tcx>( if let DefKind::Use = cx.tcx.def_kind(item.owner_id) { // Look for consts being re-exported. let item = cx.tcx.hir_expect_item(item.owner_id.def_id); - let use_name = item.ident.name; let hir::ItemKind::Use(path, _) = item.kind else { continue; }; @@ -1064,8 +1063,9 @@ fn find_fallback_pattern_typo<'tcx>( { // The const is accessible only through the re-export, point at // the `use`. - imported.push(use_name); - imported_spans.push(item.ident.span); + let ident = item.kind.ident().unwrap(); + imported.push(ident.name); + imported_spans.push(ident.span); } } } diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 1ccae0fd7fe..572dbae8fd2 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -107,7 +107,6 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir: mir_body.function_coverage_info = Some(Box::new(FunctionCoverageInfo { function_source_hash: hir_info.function_source_hash, - body_span: hir_info.body_span, node_flow_data, priority_list, diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 981dedd5b5c..0a54c780f31 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -872,8 +872,14 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { self.simplify_place_projection(place, location); return self.new_pointer(*place, AddressKind::Address(mutbl)); } - Rvalue::WrapUnsafeBinder(ref mut op, _) => { - return self.simplify_operand(op, location); + Rvalue::WrapUnsafeBinder(ref mut op, ty) => { + let value = self.simplify_operand(op, location)?; + Value::Cast { + kind: CastKind::Transmute, + value, + from: op.ty(self.local_decls, self.tcx), + to: ty, + } } // Operations. diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 34074a84e28..c9771467e49 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -8,7 +8,6 @@ use rustc_hir::lang_items::LangItem; use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::*; use rustc_middle::query::Providers; -use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::{ self, CoroutineArgs, CoroutineArgsExt, EarlyBinder, GenericArgs, Ty, TyCtxt, }; @@ -718,12 +717,6 @@ fn build_call_shim<'tcx>( let def_id = instance.def_id(); - let rpitit_shim = if let ty::InstanceKind::ReifyShim(..) = instance { - tcx.return_position_impl_trait_in_trait_shim_data(def_id) - } else { - None - }; - let sig = tcx.fn_sig(def_id); let sig = sig.map_bound(|sig| tcx.instantiate_bound_regions_with_erased(sig)); @@ -779,30 +772,7 @@ fn build_call_shim<'tcx>( let mut local_decls = local_decls_for_sig(&sig, span); let source_info = SourceInfo::outermost(span); - let mut destination = Place::return_place(); - if let Some((rpitit_def_id, fn_args)) = rpitit_shim { - let rpitit_args = - fn_args.instantiate_identity().extend_to(tcx, rpitit_def_id, |param, _| { - match param.kind { - ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), - ty::GenericParamDefKind::Type { .. } - | ty::GenericParamDefKind::Const { .. } => { - unreachable!("rpitit should have no addition ty/ct") - } - } - }); - let dyn_star_ty = Ty::new_dynamic( - tcx, - tcx.item_bounds_to_existential_predicates(rpitit_def_id, rpitit_args), - tcx.lifetimes.re_erased, - ty::DynStar, - ); - destination = local_decls.push(local_decls[RETURN_PLACE].clone()).into(); - local_decls[RETURN_PLACE].ty = dyn_star_ty; - let mut inputs_and_output = sig.inputs_and_output.to_vec(); - *inputs_and_output.last_mut().unwrap() = dyn_star_ty; - sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); - } + let destination = Place::return_place(); let rcvr_place = || { assert!(rcvr_adjustment.is_some()); @@ -921,23 +891,7 @@ fn build_call_shim<'tcx>( ); } // BB #1/#2 - return - // NOTE: If this is an RPITIT in dyn, we also want to coerce - // the return type of the function into a `dyn*`. - let stmts = if rpitit_shim.is_some() { - vec![Statement { - source_info, - kind: StatementKind::Assign(Box::new(( - Place::return_place(), - Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::DynStar, CoercionSource::Implicit), - Operand::Move(destination), - sig.output(), - ), - ))), - }] - } else { - vec![] - }; + let stmts = vec![]; block(&mut blocks, stmts, TerminatorKind::Return, false); if let Some(Adjustment::RefMut) = rcvr_adjustment { // BB #3 - drop if closure panics diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 716ababb008..c1cca1186af 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2874,7 +2874,12 @@ impl<'a> Parser<'a> { first_pat } - pub(crate) fn maybe_recover_unexpected_block_label(&mut self) -> bool { + /// If `loop_header` is `Some` and an unexpected block label is encountered, + /// it is suggested to be moved just before `loop_header`, else it is suggested to be removed. + pub(crate) fn maybe_recover_unexpected_block_label( + &mut self, + loop_header: Option<Span>, + ) -> bool { // Check for `'a : {` if !(self.check_lifetime() && self.look_ahead(1, |t| *t == token::Colon) @@ -2885,16 +2890,28 @@ impl<'a> Parser<'a> { let label = self.eat_label().expect("just checked if a label exists"); self.bump(); // eat `:` let span = label.ident.span.to(self.prev_token.span); - self.dcx() + let mut diag = self + .dcx() .struct_span_err(span, "block label not supported here") - .with_span_label(span, "not supported here") - .with_tool_only_span_suggestion( + .with_span_label(span, "not supported here"); + if let Some(loop_header) = loop_header { + diag.multipart_suggestion( + "if you meant to label the loop, move this label before the loop", + vec![ + (label.ident.span.until(self.token.span), String::from("")), + (loop_header.shrink_to_lo(), format!("{}: ", label.ident)), + ], + Applicability::MachineApplicable, + ); + } else { + diag.tool_only_span_suggestion( label.ident.span.until(self.token.span), "remove this block label", "", Applicability::MachineApplicable, - ) - .emit(); + ); + } + diag.emit(); true } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 41720e99e3b..c48f91643e8 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2296,7 +2296,7 @@ impl<'a> Parser<'a> { }); } - let (attrs, blk) = self.parse_block_common(lo, blk_mode, true)?; + let (attrs, blk) = self.parse_block_common(lo, blk_mode, true, None)?; Ok(self.mk_expr_with_attrs(blk.span, ExprKind::Block(blk, opt_label), attrs)) } @@ -2861,7 +2861,11 @@ impl<'a> Parser<'a> { )); } - let (attrs, loop_block) = self.parse_inner_attrs_and_block()?; + let (attrs, loop_block) = self.parse_inner_attrs_and_block( + // Only suggest moving erroneous block label to the loop header + // if there is not already a label there + opt_label.is_none().then_some(lo), + )?; let kind = ExprKind::ForLoop { pat, iter: expr, body: loop_block, label: opt_label, kind }; @@ -2904,11 +2908,17 @@ impl<'a> Parser<'a> { err.span_label(lo, "while parsing the condition of this `while` expression"); err })?; - let (attrs, body) = self.parse_inner_attrs_and_block().map_err(|mut err| { - err.span_label(lo, "while parsing the body of this `while` expression"); - err.span_label(cond.span, "this `while` condition successfully parsed"); - err - })?; + let (attrs, body) = self + .parse_inner_attrs_and_block( + // Only suggest moving erroneous block label to the loop header + // if there is not already a label there + opt_label.is_none().then_some(lo), + ) + .map_err(|mut err| { + err.span_label(lo, "while parsing the body of this `while` expression"); + err.span_label(cond.span, "this `while` condition successfully parsed"); + err + })?; self.recover_loop_else("while", lo)?; @@ -2922,7 +2932,11 @@ impl<'a> Parser<'a> { /// Parses `loop { ... }` (`loop` token already eaten). fn parse_expr_loop(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> { let loop_span = self.prev_token.span; - let (attrs, body) = self.parse_inner_attrs_and_block()?; + let (attrs, body) = self.parse_inner_attrs_and_block( + // Only suggest moving erroneous block label to the loop header + // if there is not already a label there + opt_label.is_none().then_some(lo), + )?; self.recover_loop_else("loop", lo)?; Ok(self.mk_expr_with_attrs( lo.to(self.prev_token.span), @@ -2972,7 +2986,7 @@ impl<'a> Parser<'a> { Applicability::MaybeIncorrect, // speculative ); } - if self.maybe_recover_unexpected_block_label() { + if self.maybe_recover_unexpected_block_label(None) { e.cancel(); self.bump(); } else { @@ -3386,7 +3400,7 @@ impl<'a> Parser<'a> { /// Parses a `try {...}` expression (`try` token already eaten). fn parse_try_block(&mut self, span_lo: Span) -> PResult<'a, P<Expr>> { - let (attrs, body) = self.parse_inner_attrs_and_block()?; + let (attrs, body) = self.parse_inner_attrs_and_block(None)?; if self.eat_keyword(exp!(Catch)) { Err(self.dcx().create_err(errors::CatchAfterTry { span: self.prev_token.span })) } else { @@ -3434,7 +3448,7 @@ impl<'a> Parser<'a> { } let capture_clause = self.parse_capture_clause()?; let decl_span = lo.to(self.prev_token.span); - let (attrs, body) = self.parse_inner_attrs_and_block()?; + let (attrs, body) = self.parse_inner_attrs_and_block(None)?; let kind = ExprKind::Gen(capture_clause, body, kind, decl_span); Ok(self.mk_expr_with_attrs(lo.to(self.prev_token.span), kind, attrs)) } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 2388463ecfc..f4df4044dd2 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2529,7 +2529,7 @@ impl<'a> Parser<'a> { *sig_hi = self.prev_token.span; (AttrVec::new(), None) } else if self.check(exp!(OpenBrace)) || self.token.is_whole_block() { - self.parse_block_common(self.token.span, BlockCheckMode::Default, false) + self.parse_block_common(self.token.span, BlockCheckMode::Default, false, None) .map(|(attrs, body)| (attrs, Some(body)))? } else if self.token == token::Eq { // Recover `fn foo() = $expr;`. diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 323c0c1d6d0..a79b4048288 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1374,7 +1374,7 @@ impl<'a> Parser<'a> { self.psess.gated_spans.gate(sym::inline_const_pat, span); } self.expect_keyword(exp!(Const))?; - let (attrs, blk) = self.parse_inner_attrs_and_block()?; + let (attrs, blk) = self.parse_inner_attrs_and_block(None)?; let anon_const = AnonConst { id: DUMMY_NODE_ID, value: self.mk_expr(blk.span, ExprKind::Block(blk, None)), diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 0896bd88b4c..0fe247078d5 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -482,7 +482,7 @@ impl<'a> Parser<'a> { /// Parses a block. No inner attributes are allowed. pub fn parse_block(&mut self) -> PResult<'a, P<Block>> { - let (attrs, block) = self.parse_inner_attrs_and_block()?; + let (attrs, block) = self.parse_inner_attrs_and_block(None)?; if let [.., last] = &*attrs { let suggest_to_outer = match &last.kind { ast::AttrKind::Normal(attr) => attr.item.is_valid_for_outer_style(), @@ -660,22 +660,32 @@ impl<'a> Parser<'a> { Err(self.error_block_no_opening_brace_msg(Cow::from(msg))) } - /// Parses a block. Inner attributes are allowed. - pub(super) fn parse_inner_attrs_and_block(&mut self) -> PResult<'a, (AttrVec, P<Block>)> { - self.parse_block_common(self.token.span, BlockCheckMode::Default, true) + /// Parses a block. Inner attributes are allowed, block labels are not. + /// + /// If `loop_header` is `Some` and an unexpected block label is encountered, + /// it is suggested to be moved just before `loop_header`, else it is suggested to be removed. + pub(super) fn parse_inner_attrs_and_block( + &mut self, + loop_header: Option<Span>, + ) -> PResult<'a, (AttrVec, P<Block>)> { + self.parse_block_common(self.token.span, BlockCheckMode::Default, true, loop_header) } - /// Parses a block. Inner attributes are allowed. + /// Parses a block. Inner attributes are allowed, block labels are not. + /// + /// If `loop_header` is `Some` and an unexpected block label is encountered, + /// it is suggested to be moved just before `loop_header`, else it is suggested to be removed. pub(super) fn parse_block_common( &mut self, lo: Span, blk_mode: BlockCheckMode, can_be_struct_literal: bool, + loop_header: Option<Span>, ) -> PResult<'a, (AttrVec, P<Block>)> { maybe_whole!(self, NtBlock, |block| (AttrVec::new(), block)); let maybe_ident = self.prev_token.clone(); - self.maybe_recover_unexpected_block_label(); + self.maybe_recover_unexpected_block_label(loop_header); if !self.eat(exp!(OpenBrace)) { return self.error_block_no_opening_brace(); } diff --git a/compiler/rustc_parse_format/Cargo.toml b/compiler/rustc_parse_format/Cargo.toml index a39cca716d2..d6c3bd9877c 100644 --- a/compiler/rustc_parse_format/Cargo.toml +++ b/compiler/rustc_parse_format/Cargo.toml @@ -5,6 +5,8 @@ edition = "2024" [dependencies] # tidy-alphabetical-start -rustc_index = { path = "../rustc_index", default-features = false } rustc_lexer = { path = "../rustc_lexer" } # tidy-alphabetical-end + +[target.'cfg(target_pointer_width = "64")'.dependencies] +rustc_index = { path = "../rustc_index", default-features = false } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index ece5a53aaa9..d1917f39c07 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -743,7 +743,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { match target { Target::Struct => { if let Some(ItemLike::Item(hir::Item { - kind: hir::ItemKind::Struct(hir::VariantData::Struct { fields, .. }, _), + kind: hir::ItemKind::Struct(_, hir::VariantData::Struct { fields, .. }, _), .. })) = item && !fields.is_empty() @@ -1019,7 +1019,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { _ => None, }; match item_kind { - Some(ItemKind::Mod(module)) => { + Some(ItemKind::Mod(_, module)) => { if !module.item_ids.is_empty() { self.dcx().emit_err(errors::DocKeywordEmptyMod { span: meta.span() }); return; @@ -1072,9 +1072,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { return; }; match item.kind { - ItemKind::Enum(_, generics) | ItemKind::Struct(_, generics) + ItemKind::Enum(_, _, generics) | ItemKind::Struct(_, _, generics) if generics.params.len() != 0 => {} - ItemKind::Trait(_, _, generics, _, items) + ItemKind::Trait(_, _, _, generics, _, items) if generics.params.len() != 0 || items.iter().any(|item| matches!(item.kind, AssocItemKind::Type)) => {} _ => { @@ -2203,7 +2203,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { fn check_rustc_std_internal_symbol(&self, attr: &Attribute, span: Span, target: Target) { match target { - Target::Fn | Target::Static => {} + Target::Fn | Target::Static | Target::ForeignFn | Target::ForeignStatic => {} _ => { self.tcx .dcx() @@ -2293,7 +2293,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } else { // special case when `#[macro_export]` is applied to a macro 2.0 - let (macro_definition, _) = self.tcx.hir_node(hir_id).expect_item().expect_macro(); + let (_, macro_definition, _) = self.tcx.hir_node(hir_id).expect_item().expect_macro(); let is_decl_macro = !macro_definition.macro_rules; if is_decl_macro { @@ -2624,7 +2624,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> { // Historically we've run more checks on non-exported than exported macros, // so this lets us continue to run them while maintaining backwards compatibility. // In the long run, the checks should be harmonized. - if let ItemKind::Macro(macro_def, _) = item.kind { + if let ItemKind::Macro(_, macro_def, _) = item.kind { let def_id = item.owner_id.to_def_id(); if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) { check_non_exported_macro_for_invalid_attrs(self.tcx, item); @@ -2736,7 +2736,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> { } fn is_c_like_enum(item: &Item<'_>) -> bool { - if let ItemKind::Enum(ref def, _) = item.kind { + if let ItemKind::Enum(_, ref def, _) = item.kind { for variant in def.variants { match variant.data { hir::VariantData::Unit(..) => { /* continue */ } @@ -2784,7 +2784,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { .map(|id| tcx.hir_item(id)) .find(|item| !item.span.is_dummy()) // Skip prelude `use`s .map(|item| errors::ItemFollowingInnerAttr { - span: item.ident.span, + span: if let Some(ident) = item.kind.ident() { ident.span } else { item.span }, kind: item.kind.descr(), }); let err = tcx.dcx().create_err(errors::InvalidAttrAtCrateLevel { diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 7029c60c343..f77e1db42d4 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -751,7 +751,7 @@ fn check_item<'tcx>( match tcx.def_kind(id.owner_id) { DefKind::Enum => { let item = tcx.hir_item(id); - if let hir::ItemKind::Enum(ref enum_def, _) = item.kind { + if let hir::ItemKind::Enum(_, ref enum_def, _) = item.kind { if let Some(comes_from_allow) = allow_dead_code { worklist.extend( enum_def.variants.iter().map(|variant| (variant.def_id, comes_from_allow)), @@ -806,7 +806,7 @@ fn check_item<'tcx>( } DefKind::Struct => { let item = tcx.hir_item(id); - if let hir::ItemKind::Struct(ref variant_data, _) = item.kind + if let hir::ItemKind::Struct(_, ref variant_data, _) = item.kind && let Some(ctor_def_id) = variant_data.ctor_def_id() { struct_constructors.insert(ctor_def_id, item.owner_id.def_id); @@ -987,7 +987,7 @@ impl<'tcx> DeadVisitor<'tcx> { && let Some(enum_did) = tcx.opt_parent(may_variant.to_def_id()) && let Some(enum_local_id) = enum_did.as_local() && let Node::Item(item) = tcx.hir_node_by_def_id(enum_local_id) - && let ItemKind::Enum(_, _) = item.kind + && let ItemKind::Enum(..) = item.kind { enum_local_id } else { @@ -1062,7 +1062,7 @@ impl<'tcx> DeadVisitor<'tcx> { let tuple_fields = if let Some(parent_id) = parent_item && let node = tcx.hir_node_by_def_id(parent_id) && let hir::Node::Item(hir::Item { - kind: hir::ItemKind::Struct(hir::VariantData::Tuple(fields, _, _), _), + kind: hir::ItemKind::Struct(_, hir::VariantData::Tuple(fields, _, _), _), .. }) = node { @@ -1132,7 +1132,7 @@ impl<'tcx> DeadVisitor<'tcx> { return; } dead_codes.sort_by_key(|v| v.level); - for group in dead_codes[..].chunk_by(|a, b| a.level == b.level) { + for group in dead_codes.chunk_by(|a, b| a.level == b.level) { self.lint_at_single_level(&group, participle, Some(def_id), report_on); } } diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 599a08bac20..321e5729b72 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -184,9 +184,7 @@ impl<'tcx> ReachableContext<'tcx> { CodegenFnAttrs::EMPTY }; let is_extern = codegen_attrs.contains_extern_indicator(); - let std_internal = - codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL); - if is_extern || std_internal { + if is_extern { self.reachable_symbols.insert(search_item); } } else { @@ -206,7 +204,7 @@ impl<'tcx> ReachableContext<'tcx> { } } - hir::ItemKind::Const(_, _, init) => { + hir::ItemKind::Const(_, _, _, init) => { // Only things actually ending up in the final constant value are reachable // for codegen. Everything else is only needed during const-eval, so even if // const-eval happens in a downstream crate, all they need is @@ -234,7 +232,7 @@ impl<'tcx> ReachableContext<'tcx> { // These are normal, nothing reachable about these // inherently and their children are already in the // worklist, as determined by the privacy pass - hir::ItemKind::ExternCrate(_) + hir::ItemKind::ExternCrate(..) | hir::ItemKind::Use(..) | hir::ItemKind::TyAlias(..) | hir::ItemKind::Macro(..) @@ -426,7 +424,6 @@ fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { } let codegen_attrs = tcx.codegen_fn_attrs(def_id); codegen_attrs.contains_extern_indicator() - || codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) // FIXME(nbdd0121): `#[used]` are marked as reachable here so it's picked up by // `linked_symbols` in cg_ssa. They won't be exported in binary or cdylib due to their // `SymbolExportLevel::Rust` export level but may end up being exported in dylibs. diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index aea4386295f..9e55914f8f2 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -430,7 +430,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { kind = AnnotationKind::DeprecationProhibited; const_stab_inherit = InheritConstStability::Yes; } - hir::ItemKind::Struct(ref sd, _) => { + hir::ItemKind::Struct(_, ref sd, _) => { if let Some(ctor_def_id) = sd.ctor_def_id() { self.annotate( ctor_def_id, @@ -773,10 +773,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { match item.kind { - hir::ItemKind::ExternCrate(_) => { + hir::ItemKind::ExternCrate(_, ident) => { // compiler-generated `extern crate` items have a dummy span. // `std` is still checked for the `restricted-std` feature. - if item.span.is_dummy() && item.ident.name != sym::std { + if item.span.is_dummy() && ident.name != sym::std { return; } diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index eeea724a29b..176dcbf6da4 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -5,6 +5,7 @@ // tidy-alphabetical-start #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![allow(unused_crate_dependencies)] #![cfg_attr(feature = "rustc", feature(let_chains))] // tidy-alphabetical-end diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 88194c737a6..fec525c9e8c 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -150,9 +150,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { /// Returns whether the given type is an enum from another crate declared `#[non_exhaustive]`. pub fn is_foreign_non_exhaustive_enum(&self, ty: RevealedTy<'tcx>) -> bool { match ty.kind() { - ty::Adt(def, ..) => { - def.is_enum() && def.is_variant_list_non_exhaustive() && !def.did().is_local() - } + ty::Adt(def, ..) => def.variant_list_has_applicable_non_exhaustive(), _ => false, } } diff --git a/compiler/rustc_pattern_analysis/tests/complexity.rs b/compiler/rustc_pattern_analysis/tests/complexity.rs index abd1ec24d93..93aecafe48d 100644 --- a/compiler/rustc_pattern_analysis/tests/complexity.rs +++ b/compiler/rustc_pattern_analysis/tests/complexity.rs @@ -1,5 +1,7 @@ //! Test the pattern complexity limit. +#![allow(unused_crate_dependencies)] + use common::*; use rustc_pattern_analysis::MatchArm; use rustc_pattern_analysis::pat::DeconstructedPat; diff --git a/compiler/rustc_pattern_analysis/tests/exhaustiveness.rs b/compiler/rustc_pattern_analysis/tests/exhaustiveness.rs index 61ce0fd11e7..3b8f346ef19 100644 --- a/compiler/rustc_pattern_analysis/tests/exhaustiveness.rs +++ b/compiler/rustc_pattern_analysis/tests/exhaustiveness.rs @@ -1,5 +1,7 @@ //! Test exhaustiveness checking. +#![allow(unused_crate_dependencies)] + use common::*; use rustc_pattern_analysis::MatchArm; use rustc_pattern_analysis::pat::{DeconstructedPat, WitnessPat}; diff --git a/compiler/rustc_pattern_analysis/tests/intersection.rs b/compiler/rustc_pattern_analysis/tests/intersection.rs index 45674338efd..8e6f84dcbc8 100644 --- a/compiler/rustc_pattern_analysis/tests/intersection.rs +++ b/compiler/rustc_pattern_analysis/tests/intersection.rs @@ -1,5 +1,7 @@ //! Test the computation of arm intersections. +#![allow(unused_crate_dependencies)] + use common::*; use rustc_pattern_analysis::MatchArm; use rustc_pattern_analysis::pat::DeconstructedPat; diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index cf32f237b86..ed00d97c31d 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -574,7 +574,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { // privacy and mark them reachable. DefKind::Macro(_) => { let item = self.tcx.hir_expect_item(def_id); - if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }, _) = item.kind { + if let hir::ItemKind::Macro(_, MacroDef { macro_rules: false, .. }, _) = item.kind { if vis.is_accessible_from(module, self.tcx) { self.update(def_id, macro_ev, Level::Reachable); } @@ -598,8 +598,8 @@ impl<'tcx> EmbargoVisitor<'tcx> { DefKind::Struct | DefKind::Union => { // While structs and unions have type privacy, their fields do not. let item = self.tcx.hir_expect_item(def_id); - if let hir::ItemKind::Struct(ref struct_def, _) - | hir::ItemKind::Union(ref struct_def, _) = item.kind + if let hir::ItemKind::Struct(_, ref struct_def, _) + | hir::ItemKind::Union(_, ref struct_def, _) = item.kind { for field in struct_def.fields() { let field_vis = self.tcx.local_visibility(field.def_id); @@ -653,7 +653,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { | hir::ItemKind::GlobalAsm { .. } => {} // The interface is empty, and all nested items are processed by `visit_item`. hir::ItemKind::Mod(..) => {} - hir::ItemKind::Macro(macro_def, _) => { + hir::ItemKind::Macro(_, macro_def, _) => { if let Some(item_ev) = item_ev { self.update_reachability_from_macro(item.owner_id.def_id, macro_def, item_ev); } @@ -724,7 +724,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { } } } - hir::ItemKind::Enum(ref def, _) => { + hir::ItemKind::Enum(_, ref def, _) => { if let Some(item_ev) = item_ev { self.reach(item.owner_id.def_id, item_ev).generics().predicates(); } @@ -762,7 +762,8 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { } } } - hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => { + hir::ItemKind::Struct(_, ref struct_def, _) + | hir::ItemKind::Union(_, ref struct_def, _) => { if let Some(item_ev) = item_ev { self.reach(item.owner_id.def_id, item_ev).generics().predicates(); for field in struct_def.fields() { @@ -866,7 +867,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TestReachabilityVisitor<'a, 'tcx> { self.effective_visibility_diagnostic(item.owner_id.def_id); match item.kind { - hir::ItemKind::Enum(ref def, _) => { + hir::ItemKind::Enum(_, ref def, _) => { for variant in def.variants.iter() { self.effective_visibility_diagnostic(variant.def_id); if let Some(ctor_def_id) = variant.data.ctor_def_id() { @@ -877,7 +878,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TestReachabilityVisitor<'a, 'tcx> { } } } - hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => { + hir::ItemKind::Struct(_, ref def, _) | hir::ItemKind::Union(_, ref def, _) => { if let Some(ctor_def_id) = def.ctor_def_id() { self.effective_visibility_diagnostic(ctor_def_id); } @@ -1361,12 +1362,12 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { GenericParamDefKind::Lifetime => {} GenericParamDefKind::Type { has_default, .. } => { if has_default { - self.visit(self.tcx.type_of(param.def_id).instantiate_identity()); + let _ = self.visit(self.tcx.type_of(param.def_id).instantiate_identity()); } } // FIXME(generic_const_exprs): May want to look inside const here GenericParamDefKind::Const { .. } => { - self.visit(self.tcx.type_of(param.def_id).instantiate_identity()); + let _ = self.visit(self.tcx.type_of(param.def_id).instantiate_identity()); } } } @@ -1381,19 +1382,19 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { // consider the ones that the user wrote. This is important // for the inferred outlives rules; see // `tests/ui/rfc-2093-infer-outlives/privacy.rs`. - self.visit_predicates(self.tcx.explicit_predicates_of(self.item_def_id)); + let _ = self.visit_predicates(self.tcx.explicit_predicates_of(self.item_def_id)); self } fn bounds(&mut self) -> &mut Self { self.in_primary_interface = false; - self.visit_clauses(self.tcx.explicit_item_bounds(self.item_def_id).skip_binder()); + let _ = self.visit_clauses(self.tcx.explicit_item_bounds(self.item_def_id).skip_binder()); self } fn ty(&mut self) -> &mut Self { self.in_primary_interface = true; - self.visit(self.tcx.type_of(self.item_def_id).instantiate_identity()); + let _ = self.visit(self.tcx.type_of(self.item_def_id).instantiate_identity()); self } @@ -1636,7 +1637,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> { } DefKind::Enum => { let item = tcx.hir_item(id); - if let hir::ItemKind::Enum(ref def, _) = item.kind { + if let hir::ItemKind::Enum(_, ref def, _) = item.kind { self.check_unnameable(item.owner_id.def_id, effective_vis); self.check(item.owner_id.def_id, item_visibility, effective_vis) @@ -1674,8 +1675,8 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> { // Subitems of structs and unions have their own publicity. DefKind::Struct | DefKind::Union => { let item = tcx.hir_item(id); - if let hir::ItemKind::Struct(ref struct_def, _) - | hir::ItemKind::Union(ref struct_def, _) = item.kind + if let hir::ItemKind::Struct(_, ref struct_def, _) + | hir::ItemKind::Union(_, ref struct_def, _) = item.kind { self.check_unnameable(item.owner_id.def_id, effective_vis); self.check(item.owner_id.def_id, item_visibility, effective_vis) @@ -1785,7 +1786,7 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { let module = tcx.hir_module_items(module_def_id); for def_id in module.definitions() { - rustc_ty_utils::sig_types::walk_types(tcx, def_id, &mut visitor); + let _ = rustc_ty_utils::sig_types::walk_types(tcx, def_id, &mut visitor); if let Some(body_id) = tcx.hir_maybe_body_owned_by(def_id) { visitor.visit_nested_body(body_id.id()); @@ -1798,7 +1799,11 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { let trait_ref = tcx.impl_trait_ref(id.owner_id.def_id).unwrap(); let trait_ref = trait_ref.instantiate_identity(); visitor.span = item.path.span; - visitor.visit_def_id(trait_ref.def_id, "trait", &trait_ref.print_only_trait_path()); + let _ = visitor.visit_def_id( + trait_ref.def_id, + "trait", + &trait_ref.print_only_trait_path(), + ); } } } diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index c85156e059e..e5cceacf15d 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -5,10 +5,8 @@ edition = "2024" [dependencies] # tidy-alphabetical-start -measureme = "11" -rustc_attr_data_structures = { path = "../rustc_attr_data_structures" } +measureme = "12.0.1" rustc_data_structures = { path = "../rustc_data_structures" } -rustc_errors = { path = "../rustc_errors" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } @@ -17,6 +15,5 @@ rustc_query_system = { path = "../rustc_query_system" } rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } -thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index fa31ef5eeb0..2b8457ace8e 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -5,9 +5,7 @@ use std::num::NonZero; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::Lock; use rustc_data_structures::unord::UnordMap; -use rustc_errors::DiagInner; use rustc_hashes::Hash64; use rustc_index::Idx; use rustc_middle::bug; @@ -26,14 +24,13 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext}; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ - QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffects, QueryStackFrame, + QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffect, QueryStackFrame, force_query, }; use rustc_query_system::{QueryOverflow, QueryOverflowNote}; use rustc_serialize::{Decodable, Encodable}; use rustc_session::Limit; use rustc_span::def_id::LOCAL_CRATE; -use thin_vec::ThinVec; use crate::QueryConfigRestored; @@ -93,43 +90,31 @@ impl QueryContext for QueryCtxt<'_> { } // Interactions with on_disk_cache - fn load_side_effects(self, prev_dep_node_index: SerializedDepNodeIndex) -> QuerySideEffects { + fn load_side_effect( + self, + prev_dep_node_index: SerializedDepNodeIndex, + ) -> Option<QuerySideEffect> { self.query_system .on_disk_cache .as_ref() - .map(|c| c.load_side_effects(self.tcx, prev_dep_node_index)) - .unwrap_or_default() + .and_then(|c| c.load_side_effect(self.tcx, prev_dep_node_index)) } #[inline(never)] #[cold] - fn store_side_effects(self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects) { + fn store_side_effect(self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect) { if let Some(c) = self.query_system.on_disk_cache.as_ref() { - c.store_side_effects(dep_node_index, side_effects) - } - } - - #[inline(never)] - #[cold] - fn store_side_effects_for_anon_node( - self, - dep_node_index: DepNodeIndex, - side_effects: QuerySideEffects, - ) { - if let Some(c) = self.query_system.on_disk_cache.as_ref() { - c.store_side_effects_for_anon_node(dep_node_index, side_effects) + c.store_side_effect(dep_node_index, side_effect) } } /// Executes a job by changing the `ImplicitCtxt` to point to the - /// new query job while it executes. It returns the diagnostics - /// captured during execution and the actual result. + /// new query job while it executes. #[inline(always)] fn start_query<R>( self, token: QueryJobId, depth_limit: bool, - diagnostics: Option<&Lock<ThinVec<DiagInner>>>, compute: impl FnOnce() -> R, ) -> R { // The `TyCtxt` stored in TLS has the same global interner lifetime @@ -144,7 +129,6 @@ impl QueryContext for QueryCtxt<'_> { let new_icx = ImplicitCtxt { tcx: self.tcx, query: Some(token), - diagnostics, query_depth: current_icx.query_depth + depth_limit as usize, task_deps: current_icx.task_deps, }; @@ -501,7 +485,7 @@ where is_anon, is_eval_always, fingerprint_style, - force_from_dep_node: Some(|tcx, dep_node| { + force_from_dep_node: Some(|tcx, dep_node, _| { force_from_dep_node(Q::config(tcx), tcx, dep_node) }), try_load_from_on_disk_cache: Some(|tcx, dep_node| { @@ -803,7 +787,7 @@ macro_rules! define_queries { is_anon: false, is_eval_always: false, fingerprint_style: FingerprintStyle::Unit, - force_from_dep_node: Some(|_, dep_node| bug!("force_from_dep_node: encountered {:?}", dep_node)), + force_from_dep_node: Some(|_, dep_node, _| bug!("force_from_dep_node: encountered {:?}", dep_node)), try_load_from_on_disk_cache: None, name: &"Null", } @@ -815,12 +799,26 @@ macro_rules! define_queries { is_anon: false, is_eval_always: false, fingerprint_style: FingerprintStyle::Unit, - force_from_dep_node: Some(|_, dep_node| bug!("force_from_dep_node: encountered {:?}", dep_node)), + force_from_dep_node: Some(|_, dep_node, _| bug!("force_from_dep_node: encountered {:?}", dep_node)), try_load_from_on_disk_cache: None, name: &"Red", } } + pub(crate) fn SideEffect<'tcx>() -> DepKindStruct<'tcx> { + DepKindStruct { + is_anon: false, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Unit, + force_from_dep_node: Some(|tcx, _, prev_index| { + tcx.dep_graph.force_diagnostic_node(QueryCtxt::new(tcx), prev_index); + true + }), + try_load_from_on_disk_cache: None, + name: &"SideEffect", + } + } + pub(crate) fn TraitSelect<'tcx>() -> DepKindStruct<'tcx> { DepKindStruct { is_anon: true, diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index 3e8ccb51021..78710efb7a9 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -22,6 +22,5 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs index 9d3368607a2..c0b3bd43e25 100644 --- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs +++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs @@ -64,7 +64,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, use rustc_hir::definitions::DefPathHash; use rustc_macros::{Decodable, Encodable}; -use super::{DepContext, FingerprintStyle}; +use super::{DepContext, FingerprintStyle, SerializedDepNodeIndex}; use crate::ich::StableHashingContext; /// This serves as an index into arrays built by `make_dep_kind_array`. @@ -275,7 +275,8 @@ pub struct DepKindStruct<Tcx: DepContext> { /// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode` /// is actually a `DefPathHash`, and can therefore just look up the corresponding /// `DefId` in `tcx.def_path_hash_to_def_id`. - pub force_from_dep_node: Option<fn(tcx: Tcx, dep_node: DepNode) -> bool>, + pub force_from_dep_node: + Option<fn(tcx: Tcx, dep_node: DepNode, prev_index: SerializedDepNodeIndex) -> bool>, /// Invoke a query to put the on-disk cached value in memory. pub try_load_from_on_disk_cache: Option<fn(Tcx, DepNode)>, diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 3109d53cd2c..bfd8b320715 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -5,13 +5,14 @@ use std::marker::PhantomData; use std::sync::Arc; use std::sync::atomic::{AtomicU32, Ordering}; -use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::profiling::{QueryInvocationId, SelfProfilerRef}; use rustc_data_structures::sharded::{self, ShardedHashMap}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{AtomicU64, Lock}; use rustc_data_structures::unord::UnordMap; +use rustc_errors::DiagInner; use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable}; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; @@ -24,7 +25,7 @@ use super::serialized::{GraphEncoder, SerializedDepGraph, SerializedDepNodeIndex use super::{DepContext, DepKind, DepNode, Deps, HasDepContext, WorkProductId}; use crate::dep_graph::edges::EdgesVec; use crate::ich::StableHashingContext; -use crate::query::{QueryContext, QuerySideEffects}; +use crate::query::{QueryContext, QuerySideEffect}; #[derive(Clone)] pub struct DepGraph<D: Deps> { @@ -91,8 +92,6 @@ pub(crate) struct DepGraphData<D: Deps> { colors: DepNodeColorMap, - processed_side_effects: Lock<FxHashSet<DepNodeIndex>>, - /// When we load, there may be `.o` files, cached MIR, or other such /// things available to us. If we find that they are not dirty, we /// load the path to the file storing those work-products here into @@ -174,7 +173,6 @@ impl<D: Deps> DepGraph<D> { previous_work_products: prev_work_products, dep_node_debug: Default::default(), current, - processed_side_effects: Default::default(), previous: prev_graph, colors, debug_loaded_from_disk: Default::default(), @@ -535,6 +533,32 @@ impl<D: Deps> DepGraph<D> { } } + /// This encodes a diagnostic by creating a node with an unique index and assoicating + /// `diagnostic` with it, for use in the next session. + #[inline] + pub fn record_diagnostic<Qcx: QueryContext>(&self, qcx: Qcx, diagnostic: &DiagInner) { + if let Some(ref data) = self.data { + D::read_deps(|task_deps| match task_deps { + TaskDepsRef::EvalAlways | TaskDepsRef::Ignore => return, + TaskDepsRef::Forbid | TaskDepsRef::Allow(..) => { + self.read_index(data.encode_diagnostic(qcx, diagnostic)); + } + }) + } + } + /// This forces a diagnostic node green by running its side effect. `prev_index` would + /// refer to a node created used `encode_diagnostic` in the previous session. + #[inline] + pub fn force_diagnostic_node<Qcx: QueryContext>( + &self, + qcx: Qcx, + prev_index: SerializedDepNodeIndex, + ) { + if let Some(ref data) = self.data { + data.force_diagnostic_node(qcx, prev_index); + } + } + /// Create a node when we force-feed a value into the query cache. /// This is used to remove cycles during type-checking const generic parameters. /// @@ -656,6 +680,57 @@ impl<D: Deps> DepGraphData<D> { pub(crate) fn mark_debug_loaded_from_disk(&self, dep_node: DepNode) { self.debug_loaded_from_disk.lock().insert(dep_node); } + + /// This encodes a diagnostic by creating a node with an unique index and assoicating + /// `diagnostic` with it, for use in the next session. + #[inline] + fn encode_diagnostic<Qcx: QueryContext>( + &self, + qcx: Qcx, + diagnostic: &DiagInner, + ) -> DepNodeIndex { + // Use `send` so we get an unique index, even though the dep node is not. + let dep_node_index = self.current.encoder.send( + DepNode { + kind: D::DEP_KIND_SIDE_EFFECT, + hash: PackedFingerprint::from(Fingerprint::ZERO), + }, + Fingerprint::ZERO, + // We want the side effect node to always be red so it will be forced and emit the + // diagnostic. + std::iter::once(DepNodeIndex::FOREVER_RED_NODE).collect(), + ); + let side_effect = QuerySideEffect::Diagnostic(diagnostic.clone()); + qcx.store_side_effect(dep_node_index, side_effect); + dep_node_index + } + + /// This forces a diagnostic node green by running its side effect. `prev_index` would + /// refer to a node created used `encode_diagnostic` in the previous session. + #[inline] + fn force_diagnostic_node<Qcx: QueryContext>( + &self, + qcx: Qcx, + prev_index: SerializedDepNodeIndex, + ) { + D::with_deps(TaskDepsRef::Ignore, || { + let side_effect = qcx.load_side_effect(prev_index).unwrap(); + + match &side_effect { + QuerySideEffect::Diagnostic(diagnostic) => { + qcx.dep_context().sess().dcx().emit_diagnostic(diagnostic.clone()); + } + } + + // Promote the previous diagnostics to the current session. + let index = self.current.promote_node_and_deps_to_current(&self.previous, prev_index); + // FIXME: Can this race with a parallel compiler? + qcx.store_side_effect(index, side_effect); + + // Mark the node as green. + self.colors.insert(prev_index, DepNodeColor::Green(index)); + }) + } } impl<D: Deps> DepGraph<D> { @@ -794,7 +869,7 @@ impl<D: Deps> DepGraphData<D> { // We failed to mark it green, so we try to force the query. debug!("trying to force dependency {dep_dep_node:?}"); - if !qcx.dep_context().try_force_from_dep_node(*dep_dep_node, frame) { + if !qcx.dep_context().try_force_from_dep_node(*dep_dep_node, parent_dep_node_index, frame) { // The DepNode could not be forced. debug!("dependency {dep_dep_node:?} could not be forced"); return None; @@ -867,16 +942,6 @@ impl<D: Deps> DepGraphData<D> { // ... emitting any stored diagnostic ... - // FIXME: Store the fact that a node has diagnostics in a bit in the dep graph somewhere - // Maybe store a list on disk and encode this fact in the DepNodeState - let side_effects = qcx.load_side_effects(prev_dep_node_index); - - if side_effects.maybe_any() { - qcx.dep_context().dep_graph().with_query_deserialization(|| { - self.emit_side_effects(qcx, dep_node_index, side_effects) - }); - } - // ... and finally storing a "Green" entry in the color map. // Multiple threads can all write the same color here self.colors.insert(prev_dep_node_index, DepNodeColor::Green(dep_node_index)); @@ -884,33 +949,6 @@ impl<D: Deps> DepGraphData<D> { debug!("successfully marked {dep_node:?} as green"); Some(dep_node_index) } - - /// Atomically emits some loaded diagnostics. - /// This may be called concurrently on multiple threads for the same dep node. - #[cold] - #[inline(never)] - fn emit_side_effects<Qcx: QueryContext<Deps = D>>( - &self, - qcx: Qcx, - dep_node_index: DepNodeIndex, - side_effects: QuerySideEffects, - ) { - let mut processed = self.processed_side_effects.lock(); - - if processed.insert(dep_node_index) { - // We were the first to insert the node in the set so this thread - // must process side effects - - // Promote the previous diagnostics to the current session. - qcx.store_side_effects(dep_node_index, side_effects.clone()); - - let dcx = qcx.dep_context().sess().dcx(); - - for diagnostic in side_effects.diagnostics { - dcx.emit_diagnostic(diagnostic); - } - } - } } impl<D: Deps> DepGraph<D> { diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index e564ae0cec7..e3d64d1c0f8 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -58,10 +58,15 @@ pub trait DepContext: Copy { /// dep-node or when the query kind outright does not support it. #[inline] #[instrument(skip(self, frame), level = "debug")] - fn try_force_from_dep_node(self, dep_node: DepNode, frame: Option<&MarkFrame<'_>>) -> bool { + fn try_force_from_dep_node( + self, + dep_node: DepNode, + prev_index: SerializedDepNodeIndex, + frame: Option<&MarkFrame<'_>>, + ) -> bool { let cb = self.dep_kind_info(dep_node.kind); if let Some(f) = cb.force_from_dep_node { - match panic::catch_unwind(panic::AssertUnwindSafe(|| f(self, dep_node))) { + match panic::catch_unwind(panic::AssertUnwindSafe(|| f(self, dep_node, prev_index))) { Err(value) => { if !value.is::<rustc_errors::FatalErrorMarker>() { print_markframe_trace(self.dep_graph(), frame); @@ -101,6 +106,9 @@ pub trait Deps { /// We use this to create a forever-red node. const DEP_KIND_RED: DepKind; + /// We use this to create a side effect node. + const DEP_KIND_SIDE_EFFECT: DepKind; + /// This is the highest value a `DepKind` can have. It's used during encoding to /// pack information into the unused bits. const DEP_KIND_MAX: u16; diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 7490a3f3503..2ed0c810b75 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -11,14 +11,12 @@ mod caches; pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCache}; mod config; -use rustc_data_structures::sync::Lock; use rustc_errors::DiagInner; use rustc_hashes::Hash64; use rustc_hir::def::DefKind; use rustc_macros::{Decodable, Encodable}; use rustc_span::Span; use rustc_span::def_id::DefId; -use thin_vec::ThinVec; pub use self::config::{HashResult, QueryConfig}; use crate::dep_graph::{DepKind, DepNodeIndex, HasDepContext, SerializedDepNodeIndex}; @@ -64,33 +62,22 @@ impl QueryStackFrame { } } -/// Tracks 'side effects' for a particular query. +/// Track a 'side effects' for a particular query. /// This struct is saved to disk along with the query result, /// and loaded from disk if we mark the query as green. /// This allows us to 'replay' changes to global state /// that would otherwise only occur if we actually /// executed the query method. -#[derive(Debug, Clone, Default, Encodable, Decodable)] -pub struct QuerySideEffects { - /// Stores any diagnostics emitted during query execution. - /// These diagnostics will be re-emitted if we mark - /// the query as green. - pub(super) diagnostics: ThinVec<DiagInner>, -} - -impl QuerySideEffects { - /// Returns true if there might be side effects. - #[inline] - pub fn maybe_any(&self) -> bool { - let QuerySideEffects { diagnostics } = self; - // Use `has_capacity` so that the destructor for `self.diagnostics` can be skipped - // if `maybe_any` is known to be false. - diagnostics.has_capacity() - } - pub fn append(&mut self, other: QuerySideEffects) { - let QuerySideEffects { diagnostics } = self; - diagnostics.extend(other.diagnostics); - } +/// +/// Each side effect gets an unique dep node index which is added +/// as a dependency of the query which had the effect. +#[derive(Debug, Encodable, Decodable)] +pub enum QuerySideEffect { + /// Stores a diagnostic emitted during query execution. + /// This diagnostic will be re-emitted if we mark + /// the query as green, as that query will have the side + /// effect dep node as a dependency. + Diagnostic(DiagInner), } pub trait QueryContext: HasDepContext { @@ -101,29 +88,19 @@ pub trait QueryContext: HasDepContext { fn collect_active_jobs(self) -> QueryMap; - /// Load side effects associated to the node in the previous session. - fn load_side_effects(self, prev_dep_node_index: SerializedDepNodeIndex) -> QuerySideEffects; - - /// Register diagnostics for the given node, for use in next session. - fn store_side_effects(self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects); - - /// Register diagnostics for the given node, for use in next session. - fn store_side_effects_for_anon_node( + /// Load a side effect associated to the node in the previous session. + fn load_side_effect( self, - dep_node_index: DepNodeIndex, - side_effects: QuerySideEffects, - ); + prev_dep_node_index: SerializedDepNodeIndex, + ) -> Option<QuerySideEffect>; + + /// Register a side effect for the given node, for use in next session. + fn store_side_effect(self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect); /// Executes a job by changing the `ImplicitCtxt` to point to the - /// new query job while it executes. It returns the diagnostics - /// captured during execution and the actual result. - fn start_query<R>( - self, - token: QueryJobId, - depth_limit: bool, - diagnostics: Option<&Lock<ThinVec<DiagInner>>>, - compute: impl FnOnce() -> R, - ) -> R; + /// new query job while it executes. + fn start_query<R>(self, token: QueryJobId, depth_limit: bool, compute: impl FnOnce() -> R) + -> R; fn depth_limit_error(self, job: QueryJobId); } diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 18aae8c00b2..7578cb5e2ae 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -12,11 +12,9 @@ use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sharded::Sharded; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_data_structures::sync::Lock; use rustc_data_structures::{outline, sync}; use rustc_errors::{Diag, FatalError, StashKey}; use rustc_span::{DUMMY_SP, Span}; -use thin_vec::ThinVec; use tracing::instrument; use super::QueryConfig; @@ -25,9 +23,7 @@ use crate::dep_graph::{DepContext, DepGraphData, DepNode, DepNodeIndex, DepNodeP use crate::ich::StableHashingContext; use crate::query::caches::QueryCache; use crate::query::job::{QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryLatch, report_cycle}; -use crate::query::{ - QueryContext, QueryMap, QuerySideEffects, QueryStackFrame, SerializedDepNodeIndex, -}; +use crate::query::{QueryContext, QueryMap, QueryStackFrame, SerializedDepNodeIndex}; pub struct QueryState<K> { active: Sharded<FxHashMap<K, QueryResult>>, @@ -470,7 +466,7 @@ where } let prof_timer = qcx.dep_context().profiler().query_provider(); - let result = qcx.start_query(job_id, query.depth_limit(), None, || query.compute(qcx, key)); + let result = qcx.start_query(job_id, query.depth_limit(), || query.compute(qcx, key)); let dep_node_index = qcx.dep_context().dep_graph().next_virtual_depnode_index(); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); @@ -507,7 +503,7 @@ where // The diagnostics for this query will be promoted to the current session during // `try_mark_green()`, so we can ignore them here. - if let Some(ret) = qcx.start_query(job_id, false, None, || { + if let Some(ret) = qcx.start_query(job_id, false, || { try_load_from_disk_and_cache_in_memory(query, dep_graph_data, qcx, &key, dep_node) }) { return ret; @@ -515,43 +511,31 @@ where } let prof_timer = qcx.dep_context().profiler().query_provider(); - let diagnostics = Lock::new(ThinVec::new()); - let (result, dep_node_index) = - qcx.start_query(job_id, query.depth_limit(), Some(&diagnostics), || { - if query.anon() { - return dep_graph_data.with_anon_task_inner( - *qcx.dep_context(), - query.dep_kind(), - || query.compute(qcx, key), - ); - } + let (result, dep_node_index) = qcx.start_query(job_id, query.depth_limit(), || { + if query.anon() { + return dep_graph_data.with_anon_task_inner( + *qcx.dep_context(), + query.dep_kind(), + || query.compute(qcx, key), + ); + } - // `to_dep_node` is expensive for some `DepKind`s. - let dep_node = - dep_node_opt.unwrap_or_else(|| query.construct_dep_node(*qcx.dep_context(), &key)); + // `to_dep_node` is expensive for some `DepKind`s. + let dep_node = + dep_node_opt.unwrap_or_else(|| query.construct_dep_node(*qcx.dep_context(), &key)); - dep_graph_data.with_task( - dep_node, - (qcx, query), - key, - |(qcx, query), key| query.compute(qcx, key), - query.hash_result(), - ) - }); + dep_graph_data.with_task( + dep_node, + (qcx, query), + key, + |(qcx, query), key| query.compute(qcx, key), + query.hash_result(), + ) + }); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); - let side_effects = QuerySideEffects { diagnostics: diagnostics.into_inner() }; - - if std::intrinsics::unlikely(side_effects.maybe_any()) { - if query.anon() { - qcx.store_side_effects_for_anon_node(dep_node_index, side_effects); - } else { - qcx.store_side_effects(dep_node_index, side_effects); - } - } - (result, dep_node_index) } diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 817aa5b4385..558a01713dc 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -26,10 +26,6 @@ resolve_associated_fn_with_similar_name_exists = resolve_associated_type_with_similar_name_exists = there is an associated type with a similar name -resolve_attempt_to_define_builtin_macro_twice = - attempted to define built-in macro more than once - .note = previously defined here - resolve_attempt_to_use_non_constant_value_in_constant = attempt to use a non-constant value in a constant diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 2ae6892bc93..e26b300f13e 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -966,15 +966,6 @@ pub(crate) struct StaticLifetimeIsReserved { } #[derive(Diagnostic)] -#[diag(resolve_attempt_to_define_builtin_macro_twice, code = E0773)] -pub(crate) struct AttemptToDefineBuiltinMacroTwice { - #[primary_span] - pub(crate) span: Span, - #[note] - pub(crate) note_span: Span, -} - -#[derive(Diagnostic)] #[diag(resolve_variable_is_not_bound_in_all_patterns, code = E0408)] pub(crate) struct VariableIsNotBoundInAllPatterns { #[primary_span] diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 447d5283e27..ff31af0025b 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1010,12 +1010,6 @@ impl ExternPreludeEntry<'_> { } } -/// Used for better errors for E0773 -enum BuiltinMacroState { - NotYetSeen(SyntaxExtensionKind), - AlreadySeen(Span), -} - struct DeriveData { resolutions: Vec<DeriveResolution>, helper_attrs: Vec<(usize, Ident)>, @@ -1134,7 +1128,7 @@ pub struct Resolver<'ra, 'tcx> { used_extern_options: FxHashSet<Symbol>, macro_names: FxHashSet<Ident>, - builtin_macros: FxHashMap<Symbol, BuiltinMacroState>, + builtin_macros: FxHashMap<Symbol, SyntaxExtensionKind>, registered_tools: &'tcx RegisteredTools, macro_use_prelude: FxIndexMap<Symbol, NameBinding<'ra>>, macro_map: FxHashMap<DefId, MacroData>, diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 7100d89ad61..c94846e95d4 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -40,9 +40,9 @@ use crate::errors::{ }; use crate::imports::Import; use crate::{ - BindingKey, BuiltinMacroState, DeriveData, Determinacy, Finalize, InvocationParent, MacroData, - ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, - ResolutionError, Resolver, ScopeSet, Segment, ToNameBinding, Used, + BindingKey, DeriveData, Determinacy, Finalize, InvocationParent, MacroData, ModuleKind, + ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, ResolutionError, + Resolver, ScopeSet, Segment, ToNameBinding, Used, }; type Res = def::Res<NodeId>; @@ -194,7 +194,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { } fn register_builtin_macro(&mut self, name: Symbol, ext: SyntaxExtensionKind) { - if self.builtin_macros.insert(name, BuiltinMacroState::NotYetSeen(ext)).is_some() { + if self.builtin_macros.insert(name, ext).is_some() { self.dcx().bug(format!("built-in macro `{name}` was already registered")); } } @@ -1127,20 +1127,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if let Some(builtin_name) = ext.builtin_name { // The macro was marked with `#[rustc_builtin_macro]`. - if let Some(builtin_macro) = self.builtin_macros.get_mut(&builtin_name) { + if let Some(builtin_ext_kind) = self.builtin_macros.get(&builtin_name) { // The macro is a built-in, replace its expander function // while still taking everything else from the source code. - // If we already loaded this builtin macro, give a better error message than 'no such builtin macro'. - match mem::replace(builtin_macro, BuiltinMacroState::AlreadySeen(span)) { - BuiltinMacroState::NotYetSeen(builtin_ext) => { - ext.kind = builtin_ext; - rule_spans = Vec::new(); - } - BuiltinMacroState::AlreadySeen(note_span) => { - self.dcx() - .emit_err(errors::AttemptToDefineBuiltinMacroTwice { span, note_span }); - } - } + ext.kind = builtin_ext_kind.clone(); + rule_spans = Vec::new(); } else { self.dcx().emit_err(errors::CannotFindBuiltinMacroWithName { span, ident }); } diff --git a/compiler/rustc_sanitizers/Cargo.toml b/compiler/rustc_sanitizers/Cargo.toml index 900cd4243b1..66488bc9625 100644 --- a/compiler/rustc_sanitizers/Cargo.toml +++ b/compiler/rustc_sanitizers/Cargo.toml @@ -8,7 +8,6 @@ bitflags = "2.5.0" tracing = "0.1" twox-hash = "1.6.3" rustc_abi = { path = "../rustc_abi" } -rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_hir = { path = "../rustc_hir" } rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_serialize/src/leb128.rs b/compiler/rustc_serialize/src/leb128.rs index 4a475805697..954c1f728f2 100644 --- a/compiler/rustc_serialize/src/leb128.rs +++ b/compiler/rustc_serialize/src/leb128.rs @@ -155,3 +155,6 @@ impl_read_signed_leb128!(read_i32_leb128, i32); impl_read_signed_leb128!(read_i64_leb128, i64); impl_read_signed_leb128!(read_i128_leb128, i128); impl_read_signed_leb128!(read_isize_leb128, isize); + +#[cfg(test)] +mod tests; diff --git a/compiler/rustc_serialize/tests/leb128.rs b/compiler/rustc_serialize/src/leb128/tests.rs index aef55d15e60..8434cd1e2e1 100644 --- a/compiler/rustc_serialize/tests/leb128.rs +++ b/compiler/rustc_serialize/src/leb128/tests.rs @@ -1,6 +1,6 @@ -use rustc_serialize::Decoder; -use rustc_serialize::leb128::*; -use rustc_serialize::opaque::{MAGIC_END_BYTES, MemDecoder}; +use super::*; +use crate::Decoder; +use crate::opaque::{MAGIC_END_BYTES, MemDecoder}; macro_rules! impl_test_unsigned_leb128 { ($test_name:ident, $write_fn_name:ident, $read_fn_name:ident, $int_ty:ident) => { diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 13c1a273eb8..34be35e36ac 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -16,6 +16,10 @@ #![feature(rustdoc_internals)] // tidy-alphabetical-end +// Allows macros to refer to this crate as `::rustc_serialize`. +#[cfg(test)] +extern crate self as rustc_serialize; + pub use self::serialize::{Decodable, Decoder, Encodable, Encoder}; mod serialize; diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index d4907b69b72..81f6266f8d1 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -451,3 +451,6 @@ impl<'a> Decodable<MemDecoder<'a>> for IntEncodedWithFixedSize { IntEncodedWithFixedSize(u64::from_le_bytes(bytes)) } } + +#[cfg(test)] +mod tests; diff --git a/compiler/rustc_serialize/tests/opaque.rs b/compiler/rustc_serialize/src/opaque/tests.rs index 5aeedbdcd4e..11401d24595 100644 --- a/compiler/rustc_serialize/tests/opaque.rs +++ b/compiler/rustc_serialize/src/opaque/tests.rs @@ -1,11 +1,10 @@ -#![allow(rustc::internal)] - use std::fmt::Debug; use std::fs; use rustc_macros::{Decodable_NoContext, Encodable_NoContext}; -use rustc_serialize::opaque::{FileEncoder, MemDecoder}; -use rustc_serialize::{Decodable, Encodable}; + +use crate::opaque::{FileEncoder, MemDecoder}; +use crate::{Decodable, Encodable}; #[derive(PartialEq, Clone, Debug, Encodable_NoContext, Decodable_NoContext)] struct Struct { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 34755249b60..701d06e4fd4 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -44,7 +44,7 @@ pub mod sigpipe; pub const PRINT_KINDS: &[(&str, PrintKind)] = &[ // tidy-alphabetical-start - ("all-target-specs-json", PrintKind::AllTargetSpecs), + ("all-target-specs-json", PrintKind::AllTargetSpecsJson), ("calling-conventions", PrintKind::CallingConventions), ("cfg", PrintKind::Cfg), ("check-cfg", PrintKind::CheckCfg), @@ -63,7 +63,7 @@ pub const PRINT_KINDS: &[(&str, PrintKind)] = &[ ("target-features", PrintKind::TargetFeatures), ("target-libdir", PrintKind::TargetLibdir), ("target-list", PrintKind::TargetList), - ("target-spec-json", PrintKind::TargetSpec), + ("target-spec-json", PrintKind::TargetSpecJson), ("tls-models", PrintKind::TlsModels), // tidy-alphabetical-end ]; @@ -873,27 +873,29 @@ pub struct PrintRequest { #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum PrintKind { + // tidy-alphabetical-start + AllTargetSpecsJson, + CallingConventions, + Cfg, + CheckCfg, + CodeModels, + CrateName, + DeploymentTarget, FileNames, HostTuple, + LinkArgs, + NativeStaticLibs, + RelocationModels, + SplitDebuginfo, + StackProtectorStrategies, Sysroot, - TargetLibdir, - CrateName, - Cfg, - CheckCfg, - CallingConventions, - TargetList, TargetCPUs, TargetFeatures, - RelocationModels, - CodeModels, + TargetLibdir, + TargetList, + TargetSpecJson, TlsModels, - TargetSpec, - AllTargetSpecs, - NativeStaticLibs, - StackProtectorStrategies, - LinkArgs, - SplitDebuginfo, - DeploymentTarget, + // tidy-alphabetical-end } #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Default)] @@ -2030,49 +2032,13 @@ fn collect_print_requests( prints.extend(matches.opt_strs("print").into_iter().map(|req| { let (req, out) = split_out_file_name(&req); - let kind = match PRINT_KINDS.iter().find(|&&(name, _)| name == req) { - Some((_, PrintKind::TargetSpec)) => { - if unstable_opts.unstable_options { - PrintKind::TargetSpec - } else { - early_dcx.early_fatal( - "the `-Z unstable-options` flag must also be passed to \ - enable the target-spec-json print option", - ); - } - } - Some((_, PrintKind::AllTargetSpecs)) => { - if unstable_opts.unstable_options { - PrintKind::AllTargetSpecs - } else { - early_dcx.early_fatal( - "the `-Z unstable-options` flag must also be passed to \ - enable the all-target-specs-json print option", - ); - } - } - Some((_, PrintKind::CheckCfg)) => { - if unstable_opts.unstable_options { - PrintKind::CheckCfg - } else { - early_dcx.early_fatal( - "the `-Z unstable-options` flag must also be passed to \ - enable the check-cfg print option", - ); - } - } - Some(&(_, print_kind)) => print_kind, - None => { - let prints = - PRINT_KINDS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>(); - let prints = prints.join(", "); - - let mut diag = - early_dcx.early_struct_fatal(format!("unknown print request: `{req}`")); - #[allow(rustc::diagnostic_outside_of_impl)] - diag.help(format!("valid print requests are: {prints}")); - diag.emit() - } + let kind = if let Some((print_name, print_kind)) = + PRINT_KINDS.iter().find(|&&(name, _)| name == req) + { + check_print_request_stability(early_dcx, unstable_opts, (print_name, *print_kind)); + *print_kind + } else { + emit_unknown_print_request_help(early_dcx, req) }; let out = out.unwrap_or(OutFileName::Stdout); @@ -2091,6 +2057,34 @@ fn collect_print_requests( prints } +fn check_print_request_stability( + early_dcx: &EarlyDiagCtxt, + unstable_opts: &UnstableOptions, + (print_name, print_kind): (&str, PrintKind), +) { + match print_kind { + PrintKind::AllTargetSpecsJson | PrintKind::CheckCfg | PrintKind::TargetSpecJson + if !unstable_opts.unstable_options => + { + early_dcx.early_fatal(format!( + "the `-Z unstable-options` flag must also be passed to enable the `{print_name}` \ + print option" + )); + } + _ => {} + } +} + +fn emit_unknown_print_request_help(early_dcx: &EarlyDiagCtxt, req: &str) -> ! { + let prints = PRINT_KINDS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>(); + let prints = prints.join(", "); + + let mut diag = early_dcx.early_struct_fatal(format!("unknown print request: `{req}`")); + #[allow(rustc::diagnostic_outside_of_impl)] + diag.help(format!("valid print requests are: {prints}")); + diag.emit() +} + pub fn parse_target_triple(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> TargetTuple { match matches.opt_str("target") { Some(target) if target.ends_with(".json") => { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 804b46a9bec..b3be4b611f0 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -389,7 +389,7 @@ top_level_options!( /// /// This directory is what the virtual `/rustc/$hash` is translated back to, /// if Rust was built with path remapping to `/rustc/$hash` enabled - /// (the `rust.remap-debuginfo` option in `config.toml`). + /// (the `rust.remap-debuginfo` option in `bootstrap.toml`). real_rust_source_base_dir: Option<PathBuf> [TRACKED_NO_CRATE_HASH], edition: Edition [TRACKED], @@ -2525,7 +2525,7 @@ written to standard error output)"), "for every macro invocation, print its name and arguments (default: no)"), track_diagnostics: bool = (false, parse_bool, [UNTRACKED], "tracks where in rustc a diagnostic was emitted"), - // Diagnostics are considered side-effects of a query (see `QuerySideEffects`) and are saved + // Diagnostics are considered side-effects of a query (see `QuerySideEffect`) and are saved // alongside query results and changes to translation options can affect diagnostics - so // translation options should be tracked. translate_additional_ftl: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED], diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml index a11df9a9c9b..b2149a03a8e 100644 --- a/compiler/rustc_smir/Cargo.toml +++ b/compiler/rustc_smir/Cargo.toml @@ -6,7 +6,6 @@ edition = "2024" [dependencies] # tidy-alphabetical-start rustc_abi = { path = "../rustc_abi" } -rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_hir = { path = "../rustc_hir" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml index 90ddf4c8a04..12fe6b719f9 100644 --- a/compiler/rustc_symbol_mangling/Cargo.toml +++ b/compiler/rustc_symbol_mangling/Cargo.toml @@ -9,7 +9,6 @@ punycode = "0.4.0" rustc-demangle = "0.1.21" rustc_abi = { path = "../rustc_abi" } -rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hashes = { path = "../rustc_hashes" } diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index c4558b5ce8b..c9b15151a2c 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -112,6 +112,8 @@ mod v0; pub mod errors; pub mod test; +pub use v0::mangle_internal_symbol; + /// This function computes the symbol name for the given `instance` and the /// given instantiating crate. That is, if you know that instance X is /// instantiated in crate Y, this is the symbol name this instance would have. @@ -183,6 +185,39 @@ fn compute_symbol_name<'tcx>( CodegenFnAttrs::EMPTY }; + if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) { + // Items marked as #[rustc_std_internal_symbol] need to have a fixed + // symbol name because it is used to import items from another crate + // without a direct dependency. As such it is not possible to look up + // the mangled name for the `Instance` from the crate metadata of the + // defining crate. + // Weak lang items automatically get #[rustc_std_internal_symbol] + // applied by the code computing the CodegenFnAttrs. + // We are mangling all #[rustc_std_internal_symbol] items that don't + // also have #[no_mangle] as a combination of the rustc version and the + // unmangled linkage name. This is to ensure that if we link against a + // staticlib compiled by a different rustc version, we don't get symbol + // conflicts or even UB due to a different implementation/ABI. Rust + // staticlibs currently export all symbols, including those that are + // hidden in cdylibs. + // We are using the v0 symbol mangling scheme here as we need to be + // consistent across all crates and in some contexts the legacy symbol + // mangling scheme can't be used. For example both the GCC backend and + // Rust-for-Linux don't support some of the characters used by the + // legacy symbol mangling scheme. + let name = if tcx.is_foreign_item(def_id) { + if let Some(name) = attrs.link_name { name } else { tcx.item_name(def_id) } + } else { + if let Some(name) = attrs.export_name { name } else { tcx.item_name(def_id) } + }; + + if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { + return name.to_string(); + } else { + return v0::mangle_internal_symbol(tcx, name.as_str()); + } + } + // Foreign items by default use no mangling for their symbol name. There's a // few exceptions to this rule though: // @@ -198,6 +233,8 @@ fn compute_symbol_name<'tcx>( // is present we mangle everything on wasm because the demangled form will // show up in the `wasm-import-name` custom attribute in LLVM IR. // + // * `#[rustc_std_internal_symbol]` mangles the symbol name in a special way + // both for exports and imports through foreign items. This is handled above. // [1]: https://bugs.llvm.org/show_bug.cgi?id=44316 if tcx.is_foreign_item(def_id) && (!tcx.sess.target.is_like_wasm diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index bc3923e4b4d..d824a23279b 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -1,4 +1,5 @@ use std::fmt::Write; +use std::hash::Hasher; use std::iter; use std::ops::Range; @@ -6,6 +7,8 @@ use rustc_abi::{ExternAbi, Integer}; use rustc_data_structures::base_n::ToBaseN; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::intern::Interned; +use rustc_data_structures::stable_hasher::StableHasher; +use rustc_hashes::Hash64; use rustc_hir as hir; use rustc_hir::def::CtorKind; use rustc_hir::def_id::{CrateNum, DefId}; @@ -70,6 +73,54 @@ pub(super) fn mangle<'tcx>( std::mem::take(&mut cx.out) } +pub fn mangle_internal_symbol<'tcx>(tcx: TyCtxt<'tcx>, item_name: &str) -> String { + if item_name == "rust_eh_personality" { + // rust_eh_personality must not be renamed as LLVM hard-codes the name + return "rust_eh_personality".to_owned(); + } else if item_name == "__rust_no_alloc_shim_is_unstable" { + // Temporary back compat hack to give people the chance to migrate to + // include #[rustc_std_internal_symbol]. + return "__rust_no_alloc_shim_is_unstable".to_owned(); + } + + let prefix = "_R"; + let mut cx: SymbolMangler<'_> = SymbolMangler { + tcx, + start_offset: prefix.len(), + paths: FxHashMap::default(), + types: FxHashMap::default(), + consts: FxHashMap::default(), + binders: vec![], + out: String::from(prefix), + }; + + cx.path_append_ns( + |cx| { + cx.push("C"); + cx.push_disambiguator({ + let mut hasher = StableHasher::new(); + // Incorporate the rustc version to ensure #[rustc_std_internal_symbol] functions + // get a different symbol name depending on the rustc version. + // + // RUSTC_FORCE_RUSTC_VERSION is ignored here as otherwise different we would get an + // abi incompatibility with the standard library. + hasher.write(tcx.sess.cfg_version.as_bytes()); + + let hash: Hash64 = hasher.finish(); + hash.as_u64() + }); + cx.push_ident("__rustc"); + Ok(()) + }, + 'v', + 0, + item_name, + ) + .unwrap(); + + std::mem::take(&mut cx.out) +} + pub(super) fn mangle_typeid_for_trait_ref<'tcx>( tcx: TyCtxt<'tcx>, trait_ref: ty::ExistentialTraitRef<'tcx>, diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_cygwin.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_cygwin.rs index 8da4fe6b8b1..eac4caf41c8 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_cygwin.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_cygwin.rs @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { description: Some("64-bit x86 Cygwin".into()), tier: Some(3), host_tools: Some(false), - std: None, + std: Some(true), }, } } diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index a32b42a6fe3..a96caf227f7 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -923,6 +923,28 @@ impl Target { _ => unreachable!(), } } + "loongarch64" => { + // LoongArch handles ABI in a very sane way, being fully explicit via `llvm_abiname` + // about what the intended ABI is. + match &*self.llvm_abiname { + "ilp32d" | "lp64d" => { + // Requires d (which implies f), incompatible with nothing. + FeatureConstraints { required: &["d"], incompatible: &[] } + } + "ilp32f" | "lp64f" => { + // Requires f, incompatible with nothing. + FeatureConstraints { required: &["f"], incompatible: &[] } + } + "ilp32s" | "lp64s" => { + // The soft-float ABI does not require any features and is also not + // incompatible with any features. Rust targets explicitly specify the + // LLVM ABI names, which allows for enabling hard-float support even on + // soft-float targets, and ensures that the ABI behavior is as expected. + NOTHING + } + _ => unreachable!(), + } + } _ => NOTHING, } } 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 6510dbbbe9d..40f8af1f691 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -2026,7 +2026,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } LetVisitor { span }.visit_body(body).break_value() } - hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _, _), .. }) => { + hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(_, ty, _, _), .. }) => { Some(&ty.peel_refs().kind) } _ => None, diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs index 5a303c3cd03..139b2997136 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs @@ -77,7 +77,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { match arg.kind { hir::TyKind::BareFn(_) => { self.current_index.shift_in(1); - intravisit::walk_ty(self, arg); + let _ = intravisit::walk_ty(self, arg); self.current_index.shift_out(1); return ControlFlow::Continue(()); } @@ -85,7 +85,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { hir::TyKind::TraitObject(bounds, ..) => { for bound in bounds { self.current_index.shift_in(1); - self.visit_poly_trait_ref(bound); + let _ = self.visit_poly_trait_ref(bound); self.current_index.shift_out(1); } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index d673e5672a0..59c93db9c8f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -338,7 +338,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .. }, hir::PathSegment { - ident: assoc_item_name, + ident: assoc_item_ident, res: Res::Def(_, item_id), .. }, @@ -368,17 +368,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let Some(local_def_id) = data.trait_ref.def_id.as_local() && let hir::Node::Item(hir::Item { - ident: trait_name, - kind: hir::ItemKind::Trait(_, _, _, _, trait_item_refs), + kind: hir::ItemKind::Trait(_, _, trait_ident, _, _, trait_item_refs), .. }) = self.tcx.hir_node_by_def_id(local_def_id) && let Some(method_ref) = trait_item_refs .iter() - .find(|item_ref| item_ref.ident == *assoc_item_name) + .find(|item_ref| item_ref.ident == *assoc_item_ident) { err.span_label( method_ref.span, - format!("`{trait_name}::{assoc_item_name}` defined here"), + format!("`{trait_ident}::{assoc_item_ident}` defined here"), ); } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 4d87a93be0c..98df09b6f7b 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -419,7 +419,12 @@ pub fn report_dyn_incompatibility<'tcx>( ) -> Diag<'tcx> { let trait_str = tcx.def_path_str(trait_def_id); let trait_span = tcx.hir_get_if_local(trait_def_id).and_then(|node| match node { - hir::Node::Item(item) => Some(item.ident.span), + hir::Node::Item(item) => match item.kind { + hir::ItemKind::Trait(_, _, ident, ..) | hir::ItemKind::TraitAlias(ident, _, _) => { + Some(ident.span) + } + _ => unreachable!(), + }, _ => None, }); 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 9383b82ff3c..393d175ea4c 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -267,8 +267,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let node = self.tcx.hir_node_by_def_id(body_id); match node { hir::Node::Item(hir::Item { - ident, - kind: hir::ItemKind::Trait(_, _, generics, bounds, _), + kind: hir::ItemKind::Trait(_, _, ident, generics, bounds, _), .. }) if self_ty == self.tcx.types.self_param => { assert!(param_ty); @@ -282,7 +281,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { None, projection, trait_pred, - Some((ident, bounds)), + Some((&ident, bounds)), ); return; } @@ -331,7 +330,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } hir::Node::Item(hir::Item { kind: - hir::ItemKind::Trait(_, _, generics, ..) + hir::ItemKind::Trait(_, _, _, generics, ..) | hir::ItemKind::Impl(hir::Impl { generics, .. }), .. }) if projection.is_some() => { @@ -352,15 +351,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { hir::Node::Item(hir::Item { kind: - hir::ItemKind::Struct(_, generics) - | hir::ItemKind::Enum(_, generics) - | hir::ItemKind::Union(_, generics) - | hir::ItemKind::Trait(_, _, generics, ..) + hir::ItemKind::Struct(_, _, generics) + | hir::ItemKind::Enum(_, _, generics) + | hir::ItemKind::Union(_, _, generics) + | hir::ItemKind::Trait(_, _, _, generics, ..) | hir::ItemKind::Impl(hir::Impl { generics, .. }) | hir::ItemKind::Fn { generics, .. } - | hir::ItemKind::TyAlias(_, generics) - | hir::ItemKind::Const(_, generics, _) - | hir::ItemKind::TraitAlias(generics, _), + | hir::ItemKind::TyAlias(_, _, generics) + | hir::ItemKind::Const(_, _, generics, _) + | hir::ItemKind::TraitAlias(_, generics, _), .. }) | hir::Node::TraitItem(hir::TraitItem { generics, .. }) @@ -390,13 +389,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let Some((name, term)) = associated_ty { // FIXME: this case overlaps with code in TyCtxt::note_and_explain_type_err. // That should be extracted into a helper function. - if constraint.ends_with('>') { - constraint = format!( - "{}, {} = {}>", - &constraint[..constraint.len() - 1], - name, - term - ); + if let Some(stripped) = constraint.strip_suffix('>') { + constraint = format!("{stripped}, {name} = {term}>"); } else { constraint.push_str(&format!("<{name} = {term}>")); } @@ -417,15 +411,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { hir::Node::Item(hir::Item { kind: - hir::ItemKind::Struct(_, generics) - | hir::ItemKind::Enum(_, generics) - | hir::ItemKind::Union(_, generics) - | hir::ItemKind::Trait(_, _, generics, ..) + hir::ItemKind::Struct(_, _, generics) + | hir::ItemKind::Enum(_, _, generics) + | hir::ItemKind::Union(_, _, generics) + | hir::ItemKind::Trait(_, _, _, generics, ..) | hir::ItemKind::Impl(hir::Impl { generics, .. }) | hir::ItemKind::Fn { generics, .. } - | hir::ItemKind::TyAlias(_, generics) - | hir::ItemKind::Const(_, generics, _) - | hir::ItemKind::TraitAlias(generics, _), + | hir::ItemKind::TyAlias(_, _, generics) + | hir::ItemKind::Const(_, _, generics, _) + | hir::ItemKind::TraitAlias(_, generics, _), .. }) if !param_ty => { // Missing generic type parameter bound. @@ -847,7 +841,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { name.to_string() } Some(hir::Node::Item(hir::Item { - ident, kind: hir::ItemKind::Fn { .. }, .. + kind: hir::ItemKind::Fn { ident, .. }, .. })) => { err.span_label(ident.span, "consider calling this function"); ident.to_string() @@ -1593,20 +1587,20 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let Some(typeck_results) = &self.typeck_results && let ty = typeck_results.expr_ty_adjusted(base) && let ty::FnDef(def_id, _args) = ty.kind() - && let Some(hir::Node::Item(hir::Item { ident, span, vis_span, .. })) = - self.tcx.hir_get_if_local(*def_id) + && let Some(hir::Node::Item(item)) = self.tcx.hir_get_if_local(*def_id) { + let (ident, _, _, _) = item.expect_fn(); let msg = format!("alternatively, consider making `fn {ident}` asynchronous"); - if vis_span.is_empty() { + if item.vis_span.is_empty() { err.span_suggestion_verbose( - span.shrink_to_lo(), + item.span.shrink_to_lo(), msg, "async ", Applicability::MaybeIncorrect, ); } else { err.span_suggestion_verbose( - vis_span.shrink_to_hi(), + item.vis_span.shrink_to_hi(), msg, " async", Applicability::MaybeIncorrect, @@ -3308,8 +3302,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut is_auto_trait = false; match tcx.hir_get_if_local(data.impl_or_alias_def_id) { Some(Node::Item(hir::Item { - kind: hir::ItemKind::Trait(is_auto, ..), - ident, + kind: hir::ItemKind::Trait(is_auto, _, ident, ..), .. })) => { // FIXME: we should do something else so that it works even on crate foreign diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index fe859eb53cd..7159397c4b1 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -516,7 +516,7 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> { match self.tcx.parent_hir_node(self.tcx.local_def_id_to_hir_id(anon_reg.scope)) { hir::Node::Item(hir::Item { - kind: hir::ItemKind::Trait(_, _, generics, ..), + kind: hir::ItemKind::Trait(_, _, _, generics, ..), .. }) | hir::Node::Item(hir::Item { diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 5cf0600ade8..84ac229b743 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -15,7 +15,7 @@ use tracing::instrument; use crate::infer::at::ToTrace; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -use crate::traits::{self, Obligation, ObligationCause, ObligationCtxt, SelectionContext}; +use crate::traits::{self, Obligation, ObligationCause, ObligationCtxt}; #[extension(pub trait InferCtxtExt<'tcx>)] impl<'tcx> InferCtxt<'tcx> { @@ -122,9 +122,6 @@ impl<'tcx> InferCtxt<'tcx> { /// - If this returns `Some([errors..])`, then the trait has an impl for /// the self type, but some nested obligations do not hold. /// - If this returns `None`, no implementation that applies could be found. - /// - /// FIXME(-Znext-solver): Due to the recursive nature of the new solver, - /// this will probably only ever return `Some([])` or `None`. fn type_implements_trait_shallow( &self, trait_def_id: DefId, @@ -132,20 +129,29 @@ impl<'tcx> InferCtxt<'tcx> { param_env: ty::ParamEnv<'tcx>, ) -> Option<Vec<traits::FulfillmentError<'tcx>>> { self.probe(|_snapshot| { - let mut selcx = SelectionContext::new(self); - match selcx.select(&Obligation::new( + let ocx = ObligationCtxt::new_with_diagnostics(self); + ocx.register_obligation(Obligation::new( self.tcx, ObligationCause::dummy(), param_env, ty::TraitRef::new(self.tcx, trait_def_id, [ty]), - )) { - Ok(Some(selection)) => { - let ocx = ObligationCtxt::new_with_diagnostics(self); - ocx.register_obligations(selection.nested_obligations()); - Some(ocx.select_all_or_error()) + )); + let errors = ocx.select_where_possible(); + // Find the original predicate in the list of predicates that could definitely not be fulfilled. + // If it is in that list, then we know this doesn't even shallowly implement the trait. + // If it is not in that list, it was fulfilled, but there may be nested obligations, which we don't care about here. + for error in &errors { + let Some(trait_clause) = error.obligation.predicate.as_trait_clause() else { + continue; + }; + let Some(bound_ty) = trait_clause.self_ty().no_bound_vars() else { continue }; + if trait_clause.def_id() == trait_def_id + && ocx.eq(&ObligationCause::dummy(), param_env, bound_ty, ty).is_ok() + { + return None; } - Ok(None) | Err(_) => None, } + Some(errors) }) } } diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 3fceada2510..78a45243983 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -9,7 +9,6 @@ use std::ops::ControlFlow; use rustc_errors::FatalError; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{ self, EarlyBinder, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, @@ -807,31 +806,8 @@ fn contains_illegal_impl_trait_in_trait<'tcx>( let ty = tcx.liberate_late_bound_regions(fn_def_id, ty); if tcx.asyncness(fn_def_id).is_async() { - // FIXME(async_fn_in_dyn_trait): Think of a better way to unify these code paths - // to issue an appropriate feature suggestion when users try to use AFIDT. - // Obviously we must only do this once AFIDT is finished enough to actually be usable. - if tcx.features().async_fn_in_dyn_trait() { - let ty::Alias(ty::Projection, proj) = *ty.kind() else { - bug!("expected async fn in trait to return an RPITIT"); - }; - assert!(tcx.is_impl_trait_in_trait(proj.def_id)); - - // FIXME(async_fn_in_dyn_trait): We should check that this bound is legal too, - // and stop relying on `async fn` in the definition. - for bound in tcx.item_bounds(proj.def_id).instantiate(tcx, proj.args) { - if let Some(violation) = bound - .visit_with(&mut IllegalRpititVisitor { tcx, allowed: Some(proj) }) - .break_value() - { - return Some(violation); - } - } - - None - } else { - // Rendering the error as a separate `async-specific` message is better. - Some(MethodViolationCode::AsyncFn) - } + // Rendering the error as a separate `async-specific` message is better. + Some(MethodViolationCode::AsyncFn) } else { ty.visit_with(&mut IllegalRpititVisitor { tcx, allowed: None }).break_value() } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index be5d6286e26..6057b66c483 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -7,8 +7,8 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_hir::lang_items::LangItem; +use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::resolve::OpportunisticRegionResolver; -use rustc_infer::infer::{DefineOpaqueTypes, RegionVariableOrigin}; use rustc_infer::traits::{ObligationCauseCode, PredicateObligations}; use rustc_middle::traits::select::OverflowError; use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData}; @@ -18,8 +18,6 @@ use rustc_middle::ty::{ }; use rustc_middle::{bug, span_bug}; use rustc_span::sym; -use rustc_type_ir::elaborate; -use thin_vec::thin_vec; use tracing::{debug, instrument}; use super::{ @@ -63,9 +61,6 @@ enum ProjectionCandidate<'tcx> { /// Bounds specified on an object type Object(ty::PolyProjectionPredicate<'tcx>), - /// Built-in bound for a dyn async fn in trait - ObjectRpitit, - /// From an "impl" (or a "pseudo-impl" returned by select) Select(Selection<'tcx>), } @@ -743,7 +738,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>( ) { debug!("assemble_candidates_from_trait_def(..)"); let mut ambiguous = false; - selcx.for_each_item_bound( + let _ = selcx.for_each_item_bound( obligation.predicate.self_ty(), |selcx, clause, _| { let Some(clause) = clause.as_projection_clause() else { @@ -832,16 +827,6 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>( env_predicates, false, ); - - // `dyn Trait` automagically project their AFITs to `dyn* Future`. - if tcx.is_impl_trait_in_trait(obligation.predicate.def_id) - && let Some(out_trait_def_id) = data.principal_def_id() - && let rpitit_trait_def_id = tcx.parent(obligation.predicate.def_id) - && elaborate::supertrait_def_ids(tcx, out_trait_def_id) - .any(|trait_def_id| trait_def_id == rpitit_trait_def_id) - { - candidate_set.push_candidate(ProjectionCandidate::ObjectRpitit); - } } #[instrument( @@ -1273,8 +1258,6 @@ fn confirm_candidate<'cx, 'tcx>( ProjectionCandidate::Select(impl_source) => { confirm_select_candidate(selcx, obligation, impl_source) } - - ProjectionCandidate::ObjectRpitit => confirm_object_rpitit_candidate(selcx, obligation), }; // When checking for cycle during evaluation, we compare predicates with @@ -2070,45 +2053,6 @@ fn confirm_impl_candidate<'cx, 'tcx>( } } -fn confirm_object_rpitit_candidate<'cx, 'tcx>( - selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTermObligation<'tcx>, -) -> Progress<'tcx> { - let tcx = selcx.tcx(); - let mut obligations = thin_vec![]; - - // Compute an intersection lifetime for all the input components of this GAT. - let intersection = - selcx.infcx.next_region_var(RegionVariableOrigin::MiscVariable(obligation.cause.span)); - for component in obligation.predicate.args { - match component.unpack() { - ty::GenericArgKind::Lifetime(lt) => { - obligations.push(obligation.with(tcx, ty::OutlivesPredicate(lt, intersection))); - } - ty::GenericArgKind::Type(ty) => { - obligations.push(obligation.with(tcx, ty::OutlivesPredicate(ty, intersection))); - } - ty::GenericArgKind::Const(_ct) => { - // Consts have no outlives... - } - } - } - - Progress { - term: Ty::new_dynamic( - tcx, - tcx.item_bounds_to_existential_predicates( - obligation.predicate.def_id, - obligation.predicate.args, - ), - intersection, - ty::DynStar, - ) - .into(), - obligations, - } -} - // Get obligations corresponding to the predicates from the where-clause of the // associated type itself. fn assoc_ty_own_obligations<'cx, 'tcx>( diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index a8d8003ead6..fc352499146 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -176,7 +176,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // normalization, so try to deduplicate when possible to avoid // unnecessary ambiguity. let mut distinct_normalized_bounds = FxHashSet::default(); - self.for_each_item_bound::<!>( + let _ = self.for_each_item_bound::<!>( placeholder_trait_predicate.self_ty(), |selcx, bound, idx| { let Some(bound) = bound.as_trait_clause() else { diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 4cd6781ab89..4404324d5cd 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -616,12 +616,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { for assoc_type in assoc_types { let defs: &ty::Generics = tcx.generics_of(assoc_type); - // When `async_fn_in_dyn_trait` is enabled, we don't need to check the - // RPITIT for compatibility, since it's not provided by the user. - if tcx.features().async_fn_in_dyn_trait() && tcx.is_impl_trait_in_trait(assoc_type) { - continue; - } - if !defs.own_params.is_empty() { tcx.dcx().span_delayed_bug( obligation.cause.span, diff --git a/compiler/rustc_transmute/src/layout/dfa.rs b/compiler/rustc_transmute/src/layout/dfa.rs index a29baade42f..af568171f91 100644 --- a/compiler/rustc_transmute/src/layout/dfa.rs +++ b/compiler/rustc_transmute/src/layout/dfa.rs @@ -55,6 +55,7 @@ where #[derive(Hash, Eq, PartialEq, PartialOrd, Ord, Copy, Clone)] pub(crate) struct State(u32); +#[cfg(test)] #[derive(Hash, Eq, PartialEq, Clone, Copy)] pub(crate) enum Transition<R> where @@ -70,6 +71,7 @@ impl fmt::Debug for State { } } +#[cfg(test)] impl<R> fmt::Debug for Transition<R> where R: Ref, @@ -166,6 +168,7 @@ impl State { } } +#[cfg(test)] impl<R> From<nfa::Transition<R>> for Transition<R> where R: Ref, diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index b14ce8a7f21..ce08b300cc8 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -7,7 +7,6 @@ edition = "2024" # tidy-alphabetical-start itertools = "0.12" rustc_abi = { path = "../rustc_abi" } -rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index a726ebae6fe..48d5a4a0fcb 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -55,31 +55,6 @@ fn fn_sig_for_fn_abi<'tcx>( sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); } - // Modify `fn() -> impl Future` to `fn() -> dyn* Future`. - if let ty::InstanceKind::ReifyShim(def_id, _) = instance.def - && let Some((rpitit_def_id, fn_args)) = - tcx.return_position_impl_trait_in_trait_shim_data(def_id) - { - let fn_args = fn_args.instantiate(tcx, args); - let rpitit_args = - fn_args.extend_to(tcx, rpitit_def_id, |param, _| match param.kind { - ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), - ty::GenericParamDefKind::Type { .. } - | ty::GenericParamDefKind::Const { .. } => { - unreachable!("rpitit should have no addition ty/ct") - } - }); - let dyn_star_ty = Ty::new_dynamic( - tcx, - tcx.item_bounds_to_existential_predicates(rpitit_def_id, rpitit_args), - tcx.lifetimes.re_erased, - ty::DynStar, - ); - let mut inputs_and_output = sig.inputs_and_output.to_vec(); - *inputs_and_output.last_mut().unwrap() = dyn_star_ty; - sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); - } - sig } ty::Closure(def_id, args) => { diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index c8b71074de7..e9055940310 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -112,7 +112,7 @@ where pub fn bind_with_vars(value: T, bound_vars: I::BoundVarKinds) -> Binder<I, T> { if cfg!(debug_assertions) { let mut validator = ValidateBoundVars::new(bound_vars); - value.visit_with(&mut validator); + let _ = value.visit_with(&mut validator); } Binder { value, bound_vars } } @@ -196,7 +196,7 @@ impl<I: Interner, T> Binder<I, T> { let value = f(value); if cfg!(debug_assertions) { let mut validator = ValidateBoundVars::new(bound_vars); - value.visit_with(&mut validator); + let _ = value.visit_with(&mut validator); } Binder { value, bound_vars } } @@ -209,7 +209,7 @@ impl<I: Interner, T> Binder<I, T> { let value = f(value)?; if cfg!(debug_assertions) { let mut validator = ValidateBoundVars::new(bound_vars); - value.visit_with(&mut validator); + let _ = value.visit_with(&mut validator); } Ok(Binder { value, bound_vars }) } diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 2f752f6eb39..1e03a191276 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -10,25 +10,28 @@ use core::ptr::{self, NonNull}; unsafe extern "Rust" { // These are the magic symbols to call the global allocator. rustc generates - // them to call `__rg_alloc` etc. if there is a `#[global_allocator]` attribute + // them to call the global allocator if there is a `#[global_allocator]` attribute // (the code expanding that attribute macro generates those functions), or to call // the default implementations in std (`__rdl_alloc` etc. in `library/std/src/alloc.rs`) // otherwise. - // The rustc fork of LLVM 14 and earlier also special-cases these function names to be able to optimize them - // like `malloc`, `realloc`, and `free`, respectively. #[rustc_allocator] #[rustc_nounwind] + #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)] fn __rust_alloc(size: usize, align: usize) -> *mut u8; #[rustc_deallocator] #[rustc_nounwind] + #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)] fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize); #[rustc_reallocator] #[rustc_nounwind] + #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)] fn __rust_realloc(ptr: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8; #[rustc_allocator_zeroed] #[rustc_nounwind] + #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)] fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8; + #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)] static __rust_no_alloc_shim_is_unstable: u8; } @@ -357,6 +360,7 @@ unsafe extern "Rust" { // This is the magic symbol to call the global alloc error handler. rustc generates // it to call `__rg_oom` if there is a `#[alloc_error_handler]`, or to call the // default implementations below (`__rdl_oom`) otherwise. + #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)] fn __rust_alloc_error_handler(size: usize, align: usize) -> !; } @@ -423,6 +427,7 @@ pub mod __alloc_error_handler { unsafe extern "Rust" { // This symbol is emitted by rustc next to __rust_alloc_error_handler. // Its value depends on the -Zoom={panic,abort} compiler option. + #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)] static __rust_alloc_error_handler_should_panic: u8; } diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index fc1cee28d03..619d9f258e3 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1327,11 +1327,14 @@ impl<T: ?Sized> Rc<T> { /// /// # Safety /// - /// The pointer must have been obtained through `Rc::into_raw`, the - /// associated `Rc` instance must be valid (i.e. the strong count must be at + /// The pointer must have been obtained through `Rc::into_raw` and must satisfy the + /// same layout requirements specified in [`Rc::from_raw_in`][from_raw_in]. + /// The associated `Rc` instance must be valid (i.e. the strong count must be at /// least 1) for the duration of this method, and `ptr` must point to a block of memory /// allocated by the global allocator. /// + /// [from_raw_in]: Rc::from_raw_in + /// /// # Examples /// /// ``` @@ -1360,12 +1363,15 @@ impl<T: ?Sized> Rc<T> { /// /// # Safety /// - /// The pointer must have been obtained through `Rc::into_raw`, the - /// associated `Rc` instance must be valid (i.e. the strong count must be at + /// The pointer must have been obtained through `Rc::into_raw`and must satisfy the + /// same layout requirements specified in [`Rc::from_raw_in`][from_raw_in]. + /// The associated `Rc` instance must be valid (i.e. the strong count must be at /// least 1) when invoking this method, and `ptr` must point to a block of memory /// allocated by the global allocator. This method can be used to release the final `Rc` and /// backing storage, but **should not** be called after the final `Rc` has been released. /// + /// [from_raw_in]: Rc::from_raw_in + /// /// # Examples /// /// ``` @@ -1623,10 +1629,13 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> { /// /// # Safety /// - /// The pointer must have been obtained through `Rc::into_raw`, the - /// associated `Rc` instance must be valid (i.e. the strong count must be at + /// The pointer must have been obtained through `Rc::into_raw` and must satisfy the + /// same layout requirements specified in [`Rc::from_raw_in`][from_raw_in]. + /// The associated `Rc` instance must be valid (i.e. the strong count must be at /// least 1) for the duration of this method, and `ptr` must point to a block of memory - /// allocated by `alloc` + /// allocated by `alloc`. + /// + /// [from_raw_in]: Rc::from_raw_in /// /// # Examples /// @@ -1665,11 +1674,14 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> { /// /// # Safety /// - /// The pointer must have been obtained through `Rc::into_raw`, the - /// associated `Rc` instance must be valid (i.e. the strong count must be at + /// The pointer must have been obtained through `Rc::into_raw`and must satisfy the + /// same layout requirements specified in [`Rc::from_raw_in`][from_raw_in]. + /// The associated `Rc` instance must be valid (i.e. the strong count must be at /// least 1) when invoking this method, and `ptr` must point to a block of memory - /// allocated by `alloc`. This method can be used to release the final `Rc` and backing storage, - /// but **should not** be called after the final `Rc` has been released. + /// allocated by `alloc`. This method can be used to release the final `Rc` and + /// backing storage, but **should not** be called after the final `Rc` has been released. + /// + /// [from_raw_in]: Rc::from_raw_in /// /// # Examples /// diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 4999319f618..c62f8e5b70f 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -84,9 +84,29 @@ macro_rules! acquire { /// /// Shared references in Rust disallow mutation by default, and `Arc` is no /// exception: you cannot generally obtain a mutable reference to something -/// inside an `Arc`. If you need to mutate through an `Arc`, use -/// [`Mutex`][mutex], [`RwLock`][rwlock], or one of the [`Atomic`][atomic] -/// types. +/// inside an `Arc`. If you do need to mutate through an `Arc`, you have several options: +/// +/// 1. Use interior mutability with synchronization primitives like [`Mutex`][mutex], +/// [`RwLock`][rwlock], or one of the [`Atomic`][atomic] types. +/// +/// 2. Use clone-on-write semantics with [`Arc::make_mut`] which provides efficient mutation +/// without requiring interior mutability. This approach clones the data only when +/// needed (when there are multiple references) and can be more efficient when mutations +/// are infrequent. +/// +/// 3. Use [`Arc::get_mut`] when you know your `Arc` is not shared (has a reference count of 1), +/// which provides direct mutable access to the inner value without any cloning. +/// +/// ``` +/// use std::sync::Arc; +/// +/// let mut data = Arc::new(vec![1, 2, 3]); +/// +/// // This will clone the vector only if there are other references to it +/// Arc::make_mut(&mut data).push(4); +/// +/// assert_eq!(*data, vec![1, 2, 3, 4]); +/// ``` /// /// **Note**: This type is only available on platforms that support atomic /// loads and stores of pointers, which includes all platforms that support @@ -1453,11 +1473,14 @@ impl<T: ?Sized> Arc<T> { /// /// # Safety /// - /// The pointer must have been obtained through `Arc::into_raw`, and the - /// associated `Arc` instance must be valid (i.e. the strong count must be at + /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the + /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. + /// The associated `Arc` instance must be valid (i.e. the strong count must be at /// least 1) for the duration of this method, and `ptr` must point to a block of memory /// allocated by the global allocator. /// + /// [from_raw_in]: Arc::from_raw_in + /// /// # Examples /// /// ``` @@ -1488,13 +1511,16 @@ impl<T: ?Sized> Arc<T> { /// /// # Safety /// - /// The pointer must have been obtained through `Arc::into_raw`, and the - /// associated `Arc` instance must be valid (i.e. the strong count must be at + /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the + /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. + /// The associated `Arc` instance must be valid (i.e. the strong count must be at /// least 1) when invoking this method, and `ptr` must point to a block of memory /// allocated by the global allocator. This method can be used to release the final /// `Arc` and backing storage, but **should not** be called after the final `Arc` has been /// released. /// + /// [from_raw_in]: Arc::from_raw_in + /// /// # Examples /// /// ``` @@ -1806,11 +1832,14 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> { /// /// # Safety /// - /// The pointer must have been obtained through `Arc::into_raw`, and the - /// associated `Arc` instance must be valid (i.e. the strong count must be at - /// least 1) for the duration of this method,, and `ptr` must point to a block of memory + /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the + /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. + /// The associated `Arc` instance must be valid (i.e. the strong count must be at + /// least 1) for the duration of this method, and `ptr` must point to a block of memory /// allocated by `alloc`. /// + /// [from_raw_in]: Arc::from_raw_in + /// /// # Examples /// /// ``` @@ -1850,13 +1879,16 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> { /// /// # Safety /// - /// The pointer must have been obtained through `Arc::into_raw`, the - /// associated `Arc` instance must be valid (i.e. the strong count must be at + /// The pointer must have been obtained through `Arc::into_raw` and must satisfy the + /// same layout requirements specified in [`Arc::from_raw_in`][from_raw_in]. + /// The associated `Arc` instance must be valid (i.e. the strong count must be at /// least 1) when invoking this method, and `ptr` must point to a block of memory /// allocated by `alloc`. This method can be used to release the final /// `Arc` and backing storage, but **should not** be called after the final `Arc` has been /// released. /// + /// [from_raw_in]: Arc::from_raw_in + /// /// # Examples /// /// ``` diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index da9a77154f9..3782f9e9519 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1252,6 +1252,19 @@ impl<T, A: Allocator> Vec<T, A> { /// vec.push(42); /// assert!(vec.capacity() >= 10); /// ``` + /// + /// A vector with zero-sized elements will always have a capacity of usize::MAX: + /// + /// ``` + /// #[derive(Clone)] + /// struct ZeroSized; + /// + /// fn main() { + /// assert_eq!(std::mem::size_of::<ZeroSized>(), 0); + /// let v = vec![ZeroSized; 0]; + /// assert_eq!(v.capacity(), usize::MAX); + /// } + /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")] diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 9ed2c8e9f3a..10f2a11d558 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -109,7 +109,7 @@ use crate::{fmt, hash, intrinsics}; // unsafe traits and unsafe methods (i.e., `type_id` would still be safe to call, // but we would likely want to indicate as such in documentation). #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "Any")] +#[rustc_diagnostic_item = "Any"] pub trait Any: 'static { /// Gets the `TypeId` of `self`. /// diff --git a/library/core/src/array/ascii.rs b/library/core/src/array/ascii.rs index e2faef855bc..792a57e3fa2 100644 --- a/library/core/src/array/ascii.rs +++ b/library/core/src/array/ascii.rs @@ -1,6 +1,5 @@ use crate::ascii; -#[cfg(not(test))] impl<const N: usize> [u8; N] { /// Converts this array of bytes into an array of ASCII characters, /// or returns `None` if any of the characters is non-ASCII. diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs index 3c589ca5dfa..d525ab425e6 100644 --- a/library/core/src/bool.rs +++ b/library/core/src/bool.rs @@ -56,7 +56,7 @@ impl bool { /// ``` #[doc(alias = "then_with")] #[stable(feature = "lazy_bool_to_option", since = "1.50.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "bool_then")] + #[rustc_diagnostic_item = "bool_then"] #[inline] pub fn then<T, F: FnOnce() -> T>(self, f: F) -> Option<T> { if self { Some(f()) } else { None } diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index cbf00106c51..1a320b316a4 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -304,7 +304,7 @@ pub use once::OnceCell; /// ``` /// /// See the [module-level documentation](self) for more. -#[cfg_attr(not(test), rustc_diagnostic_item = "Cell")] +#[rustc_diagnostic_item = "Cell"] #[stable(feature = "rust1", since = "1.0.0")] #[repr(transparent)] #[rustc_pub_transparent] @@ -725,7 +725,7 @@ impl<T, const N: usize> Cell<[T; N]> { /// A mutable memory location with dynamically checked borrow rules /// /// See the [module-level documentation](self) for more. -#[cfg_attr(not(test), rustc_diagnostic_item = "RefCell")] +#[rustc_diagnostic_item = "RefCell"] #[stable(feature = "rust1", since = "1.0.0")] pub struct RefCell<T: ?Sized> { borrow: Cell<BorrowFlag>, diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index bb71af339b8..fa584953bed 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -1178,7 +1178,7 @@ impl char { #[must_use] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_char_is_ascii", since = "1.32.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "char_is_ascii")] + #[rustc_diagnostic_item = "char_is_ascii"] #[inline] pub const fn is_ascii(&self) -> bool { *self as u32 <= 0x7F diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index c777dd995a6..e0ac0bfc528 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -262,34 +262,150 @@ pub struct AssertParamIsCopy<T: Copy + ?Sized> { _field: crate::marker::PhantomData<T>, } -/// A generalization of [`Clone`] to dynamically-sized types stored in arbitrary containers. +/// A generalization of [`Clone`] to [dynamically-sized types][DST] stored in arbitrary containers. /// -/// This trait is implemented for all types implementing [`Clone`], and also [slices](slice) of all -/// such types. You may also implement this trait to enable cloning trait objects and custom DSTs -/// (structures containing dynamically-sized fields). +/// This trait is implemented for all types implementing [`Clone`], [slices](slice) of all +/// such types, and other dynamically-sized types in the standard library. +/// You may also implement this trait to enable cloning custom DSTs +/// (structures containing dynamically-sized fields), or use it as a supertrait to enable +/// cloning a [trait object]. +/// +/// This trait is normally used via operations on container types which support DSTs, +/// so you should not typically need to call `.clone_to_uninit()` explicitly except when +/// implementing such a container or otherwise performing explicit management of an allocation, +/// or when implementing `CloneToUninit` itself. /// /// # Safety /// -/// Implementations must ensure that when `.clone_to_uninit(dst)` returns normally rather than -/// panicking, it always leaves `*dst` initialized as a valid value of type `Self`. +/// Implementations must ensure that when `.clone_to_uninit(dest)` returns normally rather than +/// panicking, it always leaves `*dest` initialized as a valid value of type `Self`. +/// +/// # Examples +/// +// FIXME(#126799): when `Box::clone` allows use of `CloneToUninit`, rewrite these examples with it +// since `Rc` is a distraction. +/// +/// If you are defining a trait, you can add `CloneToUninit` as a supertrait to enable cloning of +/// `dyn` values of your trait: +/// +/// ``` +/// #![feature(clone_to_uninit)] +/// use std::rc::Rc; +/// +/// trait Foo: std::fmt::Debug + std::clone::CloneToUninit { +/// fn modify(&mut self); +/// fn value(&self) -> i32; +/// } +/// +/// impl Foo for i32 { +/// fn modify(&mut self) { +/// *self *= 10; +/// } +/// fn value(&self) -> i32 { +/// *self +/// } +/// } +/// +/// let first: Rc<dyn Foo> = Rc::new(1234); +/// +/// let mut second = first.clone(); +/// Rc::make_mut(&mut second).modify(); // make_mut() will call clone_to_uninit() +/// +/// assert_eq!(first.value(), 1234); +/// assert_eq!(second.value(), 12340); +/// ``` +/// +/// The following is an example of implementing `CloneToUninit` for a custom DST. +/// (It is essentially a limited form of what `derive(CloneToUninit)` would do, +/// if such a derive macro existed.) /// -/// # See also +/// ``` +/// #![feature(clone_to_uninit)] +/// use std::clone::CloneToUninit; +/// use std::mem::offset_of; +/// use std::rc::Rc; +/// +/// #[derive(PartialEq)] +/// struct MyDst<T: ?Sized> { +/// label: String, +/// contents: T, +/// } /// -/// * [`Clone::clone_from`] is a safe function which may be used instead when `Self` is a [`Sized`] +/// unsafe impl<T: ?Sized + CloneToUninit> CloneToUninit for MyDst<T> { +/// unsafe fn clone_to_uninit(&self, dest: *mut u8) { +/// // The offset of `self.contents` is dynamic because it depends on the alignment of T +/// // which can be dynamic (if `T = dyn SomeTrait`). Therefore, we have to obtain it +/// // dynamically by examining `self`, rather than using `offset_of!`. +/// // +/// // SAFETY: `self` by definition points somewhere before `&self.contents` in the same +/// // allocation. +/// let offset_of_contents = unsafe { +/// (&raw const self.contents).byte_offset_from_unsigned(self) +/// }; +/// +/// // Clone the *sized* fields of `self` (just one, in this example). +/// // (By cloning this first and storing it temporarily in a local variable, we avoid +/// // leaking it in case of any panic, using the ordinary automatic cleanup of local +/// // variables. Such a leak would be sound, but undesirable.) +/// let label = self.label.clone(); +/// +/// // SAFETY: The caller must provide a `dest` such that these field offsets are valid +/// // to write to. +/// unsafe { +/// // Clone the unsized field directly from `self` to `dest`. +/// self.contents.clone_to_uninit(dest.add(offset_of_contents)); +/// +/// // Now write all the sized fields. +/// // +/// // Note that we only do this once all of the clone() and clone_to_uninit() calls +/// // have completed, and therefore we know that there are no more possible panics; +/// // this ensures no memory leaks in case of panic. +/// dest.add(offset_of!(Self, label)).cast::<String>().write(label); +/// } +/// // All fields of the struct have been initialized; therefore, the struct is initialized, +/// // and we have satisfied our `unsafe impl CloneToUninit` obligations. +/// } +/// } +/// +/// fn main() { +/// // Construct MyDst<[u8; 4]>, then coerce to MyDst<[u8]>. +/// let first: Rc<MyDst<[u8]>> = Rc::new(MyDst { +/// label: String::from("hello"), +/// contents: [1, 2, 3, 4], +/// }); +/// +/// let mut second = first.clone(); +/// // make_mut() will call clone_to_uninit(). +/// for elem in Rc::make_mut(&mut second).contents.iter_mut() { +/// *elem *= 10; +/// } +/// +/// assert_eq!(first.contents, [1, 2, 3, 4]); +/// assert_eq!(second.contents, [10, 20, 30, 40]); +/// assert_eq!(second.label, "hello"); +/// } +/// ``` +/// +/// # See Also +/// +/// * [`Clone::clone_from`] is a safe function which may be used instead when [`Self: Sized`](Sized) /// and the destination is already initialized; it may be able to reuse allocations owned by -/// the destination. +/// the destination, whereas `clone_to_uninit` cannot, since its destination is assumed to be +/// uninitialized. /// * [`ToOwned`], which allocates a new destination container. /// /// [`ToOwned`]: ../../std/borrow/trait.ToOwned.html +/// [DST]: https://doc.rust-lang.org/reference/dynamically-sized-types.html +/// [trait object]: https://doc.rust-lang.org/reference/types/trait-object.html #[unstable(feature = "clone_to_uninit", issue = "126799")] pub unsafe trait CloneToUninit { - /// Performs copy-assignment from `self` to `dst`. + /// Performs copy-assignment from `self` to `dest`. /// - /// This is analogous to `std::ptr::write(dst.cast(), self.clone())`, - /// except that `self` may be a dynamically-sized type ([`!Sized`](Sized)). + /// This is analogous to `std::ptr::write(dest.cast(), self.clone())`, + /// except that `Self` may be a dynamically-sized type ([`!Sized`](Sized)). /// - /// Before this function is called, `dst` may point to uninitialized memory. - /// After this function is called, `dst` will point to initialized memory; it will be + /// Before this function is called, `dest` may point to uninitialized memory. + /// After this function is called, `dest` will point to initialized memory; it will be /// sound to create a `&Self` reference from the pointer with the [pointer metadata] /// from `self`. /// @@ -297,8 +413,8 @@ pub unsafe trait CloneToUninit { /// /// Behavior is undefined if any of the following conditions are violated: /// - /// * `dst` must be [valid] for writes for `size_of_val(self)` bytes. - /// * `dst` must be properly aligned to `align_of_val(self)`. + /// * `dest` must be [valid] for writes for `size_of_val(self)` bytes. + /// * `dest` must be properly aligned to `align_of_val(self)`. /// /// [valid]: crate::ptr#safety /// [pointer metadata]: crate::ptr::metadata() @@ -307,27 +423,26 @@ pub unsafe trait CloneToUninit { /// /// This function may panic. (For example, it might panic if memory allocation for a clone /// of a value owned by `self` fails.) - /// If the call panics, then `*dst` should be treated as uninitialized memory; it must not be + /// If the call panics, then `*dest` should be treated as uninitialized memory; it must not be /// read or dropped, because even if it was previously valid, it may have been partially /// overwritten. /// - /// The caller may also need to take care to deallocate the allocation pointed to by `dst`, - /// if applicable, to avoid a memory leak, and may need to take other precautions to ensure - /// soundness in the presence of unwinding. + /// The caller may wish to to take care to deallocate the allocation pointed to by `dest`, + /// if applicable, to avoid a memory leak (but this is not a requirement). /// /// Implementors should avoid leaking values by, upon unwinding, dropping all component values /// that might have already been created. (For example, if a `[Foo]` of length 3 is being /// cloned, and the second of the three calls to `Foo::clone()` unwinds, then the first `Foo` /// cloned should be dropped.) - unsafe fn clone_to_uninit(&self, dst: *mut u8); + unsafe fn clone_to_uninit(&self, dest: *mut u8); } #[unstable(feature = "clone_to_uninit", issue = "126799")] unsafe impl<T: Clone> CloneToUninit for T { #[inline] - unsafe fn clone_to_uninit(&self, dst: *mut u8) { + unsafe fn clone_to_uninit(&self, dest: *mut u8) { // SAFETY: we're calling a specialization with the same contract - unsafe { <T as self::uninit::CopySpec>::clone_one(self, dst.cast::<T>()) } + unsafe { <T as self::uninit::CopySpec>::clone_one(self, dest.cast::<T>()) } } } @@ -335,10 +450,10 @@ unsafe impl<T: Clone> CloneToUninit for T { unsafe impl<T: Clone> CloneToUninit for [T] { #[inline] #[cfg_attr(debug_assertions, track_caller)] - unsafe fn clone_to_uninit(&self, dst: *mut u8) { - let dst: *mut [T] = dst.with_metadata_of(self); + unsafe fn clone_to_uninit(&self, dest: *mut u8) { + let dest: *mut [T] = dest.with_metadata_of(self); // SAFETY: we're calling a specialization with the same contract - unsafe { <T as self::uninit::CopySpec>::clone_slice(self, dst) } + unsafe { <T as self::uninit::CopySpec>::clone_slice(self, dest) } } } @@ -346,21 +461,21 @@ unsafe impl<T: Clone> CloneToUninit for [T] { unsafe impl CloneToUninit for str { #[inline] #[cfg_attr(debug_assertions, track_caller)] - unsafe fn clone_to_uninit(&self, dst: *mut u8) { + unsafe fn clone_to_uninit(&self, dest: *mut u8) { // SAFETY: str is just a [u8] with UTF-8 invariant - unsafe { self.as_bytes().clone_to_uninit(dst) } + unsafe { self.as_bytes().clone_to_uninit(dest) } } } #[unstable(feature = "clone_to_uninit", issue = "126799")] unsafe impl CloneToUninit for crate::ffi::CStr { #[cfg_attr(debug_assertions, track_caller)] - unsafe fn clone_to_uninit(&self, dst: *mut u8) { + unsafe fn clone_to_uninit(&self, dest: *mut u8) { // SAFETY: For now, CStr is just a #[repr(trasnsparent)] [c_char] with some invariants. // And we can cast [c_char] to [u8] on all supported platforms (see: to_bytes_with_nul). // The pointer metadata properly preserves the length (so NUL is also copied). // See: `cstr_metadata_is_length_with_nul` in tests. - unsafe { self.to_bytes_with_nul().clone_to_uninit(dst) } + unsafe { self.to_bytes_with_nul().clone_to_uninit(dest) } } } diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index b29251b4b43..25bd17d5802 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1481,7 +1481,7 @@ pub macro PartialOrd($item:item) { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "cmp_min")] +#[rustc_diagnostic_item = "cmp_min"] pub fn min<T: Ord>(v1: T, v2: T) -> T { v1.min(v2) } @@ -1573,7 +1573,7 @@ pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "cmp_max")] +#[rustc_diagnostic_item = "cmp_max"] pub fn max<T: Ord>(v1: T, v2: T) -> T { v1.max(v2) } diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 43fd54f881d..e1b10e1074d 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -214,7 +214,7 @@ pub const fn identity<T>(x: T) -> T { /// is_hello(s); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "AsRef")] +#[rustc_diagnostic_item = "AsRef"] pub trait AsRef<T: ?Sized> { /// Converts this type into a shared reference of the (usually inferred) input type. #[stable(feature = "rust1", since = "1.0.0")] @@ -365,7 +365,7 @@ pub trait AsRef<T: ?Sized> { /// Note, however, that APIs don't need to be generic. In many cases taking a `&mut [u8]` or /// `&mut Vec<u8>`, for example, is the better choice (callers need to pass the correct type then). #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "AsMut")] +#[rustc_diagnostic_item = "AsMut"] pub trait AsMut<T: ?Sized> { /// Converts this type into a mutable reference of the (usually inferred) input type. #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/convert/num.rs b/library/core/src/convert/num.rs index 0246d0627ca..d5cb10a5d1c 100644 --- a/library/core/src/convert/num.rs +++ b/library/core/src/convert/num.rs @@ -147,22 +147,42 @@ impl_from!(i16 => isize, #[stable(feature = "lossless_iusize_conv", since = "1.2 // https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-951.pdf // Note: integers can only be represented with full precision in a float if -// they fit in the significand, which is 24 bits in f32 and 53 bits in f64. +// they fit in the significand, which is: +// * 11 bits in f16 +// * 24 bits in f32 +// * 53 bits in f64 +// * 113 bits in f128 // Lossy float conversions are not implemented at this time. +// FIXME(f16_f128): The `f16`/`f128` impls `#[stable]` attributes should be changed to reference +// `f16`/`f128` when they are stabilised (trait impls have to have a `#[stable]` attribute, but none +// of the `f16`/`f128` impls can be used on stable as the `f16` and `f128` types are unstable). // signed integer -> float +impl_from!(i8 => f16, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(i8 => f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(i8 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); +impl_from!(i8 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(i16 => f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(i16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); +impl_from!(i16 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(i32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); +impl_from!(i32 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); +// FIXME(f16_f128): This impl would allow using `f128` on stable before it is stabilised. +// impl_from!(i64 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); // unsigned integer -> float +impl_from!(u8 => f16, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(u8 => f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(u8 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); +impl_from!(u8 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); +impl_from!(u16 => f16, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(u16 => f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(u16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); +impl_from!(u16 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(u32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); +impl_from!(u32 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); +// FIXME(f16_f128): This impl would allow using `f128` on stable before it is stabilised. +// impl_from!(u64 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); // float -> float // FIXME(f16_f128): adding additional `From<{float}>` impls to `f32` breaks inference. See @@ -174,7 +194,12 @@ impl_from!(f32 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0 impl_from!(f64 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); macro_rules! impl_float_from_bool { - ($float:ty) => { + ( + $float:ty $(; + doctest_prefix: $(#[doc = $doctest_prefix:literal])* + doctest_suffix: $(#[doc = $doctest_suffix:literal])* + )? + ) => { #[stable(feature = "float_from_bool", since = "1.68.0")] impl From<bool> for $float { #[doc = concat!("Converts a [`bool`] to [`", stringify!($float),"`] losslessly.")] @@ -182,12 +207,14 @@ macro_rules! impl_float_from_bool { /// /// # Examples /// ``` + $($(#[doc = $doctest_prefix])*)? #[doc = concat!("let x: ", stringify!($float)," = false.into();")] /// assert_eq!(x, 0.0); /// assert!(x.is_sign_positive()); /// #[doc = concat!("let y: ", stringify!($float)," = true.into();")] /// assert_eq!(y, 1.0); + $($(#[doc = $doctest_suffix])*)? /// ``` #[inline] fn from(small: bool) -> Self { @@ -198,8 +225,27 @@ macro_rules! impl_float_from_bool { } // boolean -> float +impl_float_from_bool!( + f16; + doctest_prefix: + // rustdoc doesn't remove the conventional space after the `///` + ///#![feature(f16)] + ///# #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { + /// + doctest_suffix: + ///# } +); impl_float_from_bool!(f32); impl_float_from_bool!(f64); +impl_float_from_bool!( + f128; + doctest_prefix: + ///#![feature(f128)] + ///# #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { + /// + doctest_suffix: + ///# } +); // no possible bounds violation macro_rules! impl_try_from_unbounded { diff --git a/library/core/src/default.rs b/library/core/src/default.rs index 4c30290ff26..044997a81a9 100644 --- a/library/core/src/default.rs +++ b/library/core/src/default.rs @@ -101,7 +101,7 @@ use crate::ascii::Char as AsciiChar; /// bar: f32, /// } /// ``` -#[cfg_attr(not(test), rustc_diagnostic_item = "Default")] +#[rustc_diagnostic_item = "Default"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_trivial_field_reads] pub trait Default: Sized { diff --git a/library/core/src/error.rs b/library/core/src/error.rs index 94847685ec9..bfa392003b9 100644 --- a/library/core/src/error.rs +++ b/library/core/src/error.rs @@ -47,7 +47,7 @@ use crate::fmt::{self, Debug, Display, Formatter}; /// impl Error for ReadConfigError {} /// ``` #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "Error")] +#[rustc_diagnostic_item = "Error"] #[rustc_has_incoherent_inherent_impls] #[allow(multiple_supertrait_upcastable)] pub trait Error: Debug + Display { diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index e0dc632df70..b13c7ee5aa2 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -18,7 +18,7 @@ mod num; mod rt; #[stable(feature = "fmt_flags_align", since = "1.28.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "Alignment")] +#[rustc_diagnostic_item = "Alignment"] /// Possible alignments returned by `Formatter::align` #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Alignment { @@ -2771,7 +2771,14 @@ impl Display for char { #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized> Pointer for *const T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { - pointer_fmt_inner(self.expose_provenance(), f) + if <<T as core::ptr::Pointee>::Metadata as core::unit::IsUnit>::is_unit() { + pointer_fmt_inner(self.expose_provenance(), f) + } else { + f.debug_struct("Pointer") + .field_with("addr", |f| pointer_fmt_inner(self.expose_provenance(), f)) + .field("metadata", &core::ptr::metadata(*self)) + .finish() + } } } diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 48b265fabc7..cf03c07b6a5 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1774,10 +1774,14 @@ pub fn ptr_mask<T>(ptr: *const T, mask: usize) -> *const T; /// a size of `count` * `size_of::<T>()` and an alignment of /// `min_align_of::<T>()` /// -/// The volatile parameter is set to `true`, so it will not be optimized out -/// unless size is equal to zero. -/// /// This intrinsic does not have a stable counterpart. +/// # Safety +/// +/// The safety requirements are consistent with [`copy_nonoverlapping`] +/// while the read and write behaviors are volatile, +/// which means it will not be optimized out unless `_count` or `size_of::<T>()` is equal to zero. +/// +/// [`copy_nonoverlapping`]: ptr::copy_nonoverlapping #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize); @@ -1796,10 +1800,13 @@ pub unsafe fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: usize); /// size of `count * size_of::<T>()` and an alignment of /// `min_align_of::<T>()`. /// -/// The volatile parameter is set to `true`, so it will not be optimized out -/// unless size is equal to zero. -/// /// This intrinsic does not have a stable counterpart. +/// # Safety +/// +/// The safety requirements are consistent with [`write_bytes`] while the write behavior is volatile, +/// which means it will not be optimized out unless `_count` or `size_of::<T>()` is equal to zero. +/// +/// [`write_bytes`]: ptr::write_bytes #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn volatile_set_memory<T>(dst: *mut T, val: u8, count: usize); @@ -3341,8 +3348,18 @@ pub const fn is_val_statically_known<T: Copy>(_arg: T) -> bool { /// The stabilized form of this intrinsic is [`crate::mem::swap`]. /// /// # Safety +/// Behavior is undefined if any of the following conditions are violated: +/// +/// * Both `x` and `y` must be [valid] for both reads and writes. /// -/// `x` and `y` are readable and writable as `T`, and non-overlapping. +/// * Both `x` and `y` must be properly aligned. +/// +/// * The region of memory beginning at `x` must *not* overlap with the region of memory +/// beginning at `y`. +/// +/// * The memory pointed by `x` and `y` must both contain values of type `T`. +/// +/// [valid]: crate::ptr#safety #[rustc_nounwind] #[inline] #[rustc_intrinsic] @@ -3624,7 +3641,8 @@ pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + ?Sized, M>(ptr: *const /// For regions of memory which might overlap, use [`copy`] instead. /// /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but -/// with the argument order swapped. +/// with the source and destination arguments swapped, +/// and `count` counting the number of `T`s instead of bytes. /// /// The copy is "untyped" in the sense that data may be uninitialized or otherwise violate the /// requirements of `T`. The initialization state is preserved exactly. @@ -3744,8 +3762,10 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us /// If the source and destination will *never* overlap, /// [`copy_nonoverlapping`] can be used instead. /// -/// `copy` is semantically equivalent to C's [`memmove`], but with the argument -/// order swapped. Copying takes place as if the bytes were copied from `src` +/// `copy` is semantically equivalent to C's [`memmove`], but +/// with the source and destination arguments swapped, +/// and `count` counting the number of `T`s instead of bytes. +/// Copying takes place as if the bytes were copied from `src` /// to a temporary array and then copied from the array to `dst`. /// /// The copy is "untyped" in the sense that data may be uninitialized or otherwise violate the diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index ac15e3767fc..f9c388e8564 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -14,7 +14,7 @@ use crate::ops::Try; #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "Enumerate")] +#[rustc_diagnostic_item = "Enumerate"] pub struct Enumerate<I> { iter: I, count: usize, diff --git a/library/core/src/iter/sources/repeat.rs b/library/core/src/iter/sources/repeat.rs index 243f938bce2..c4f5a483e5c 100644 --- a/library/core/src/iter/sources/repeat.rs +++ b/library/core/src/iter/sources/repeat.rs @@ -56,7 +56,7 @@ use crate::num::NonZero; /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "iter_repeat")] +#[rustc_diagnostic_item = "iter_repeat"] pub fn repeat<T: Clone>(elt: T) -> Repeat<T> { Repeat { element: elt } } diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index 3b126785728..7dabaece955 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -37,7 +37,7 @@ use crate::ops::{ControlFlow, Try}; /// assert_eq!(None, iter.next_back()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "DoubleEndedIterator")] +#[rustc_diagnostic_item = "DoubleEndedIterator"] pub trait DoubleEndedIterator: Iterator { /// Removes and returns an element from the end of the iterator. /// diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 10ae43ac3fc..3bbb52fdbcb 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -862,7 +862,7 @@ pub trait Iterator { /// Note that `iter.filter(f).next()` is equivalent to `iter.find(f)`. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "iter_filter")] + #[rustc_diagnostic_item = "iter_filter"] fn filter<P>(self, predicate: P) -> Filter<Self, P> where Self: Sized, @@ -954,7 +954,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "enumerate_method")] + #[rustc_diagnostic_item = "enumerate_method"] fn enumerate(self) -> Enumerate<Self> where Self: Sized, @@ -1704,11 +1704,7 @@ pub trait Iterator { /// self.state = self.state + 1; /// /// // if it's even, Some(i32), else None - /// if val % 2 == 0 { - /// Some(val) - /// } else { - /// None - /// } + /// (val % 2 == 0).then_some(val) /// } /// } /// @@ -1972,11 +1968,20 @@ pub trait Iterator { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] - #[cfg_attr(not(test), rustc_diagnostic_item = "iterator_collect_fn")] + #[rustc_diagnostic_item = "iterator_collect_fn"] fn collect<B: FromIterator<Self::Item>>(self) -> B where Self: Sized, { + // This is too aggressive to turn on for everything all the time, but PR#137908 + // accidentally noticed that some rustc iterators had malformed `size_hint`s, + // so this will help catch such things in debug-assertions-std runners, + // even if users won't actually ever see it. + if cfg!(debug_assertions) { + let hint = self.size_hint(); + assert!(hint.1.is_none_or(|high| high >= hint.0), "Malformed size_hint {hint:?}"); + } + FromIterator::from_iter(self) } @@ -3367,7 +3372,7 @@ pub trait Iterator { /// assert_eq!(v_map, vec![1, 2, 3]); /// ``` #[stable(feature = "iter_copied", since = "1.36.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "iter_copied")] + #[rustc_diagnostic_item = "iter_copied"] fn copied<'a, T: 'a>(self) -> Copied<Self> where Self: Sized + Iterator<Item = &'a T>, @@ -3415,7 +3420,7 @@ pub trait Iterator { /// assert_eq!(&[vec![23]], &faster[..]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "iter_cloned")] + #[rustc_diagnostic_item = "iter_cloned"] fn cloned<'a, T: 'a>(self) -> Cloned<Self> where Self: Sized + Iterator<Item = &'a T>, diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 6e058069756..e1ca69edcbb 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -43,18 +43,6 @@ //! which do not trigger a panic can be assured that this function is never //! called. The `lang` attribute is called `eh_personality`. -// Since core defines many fundamental lang items, all tests live in a -// separate crate, coretests (library/coretests), to avoid bizarre issues. -// -// Here we explicitly #[cfg]-out this whole crate when testing. If we don't do -// this, both the generated test artifact and the linked libtest (which -// transitively includes core) will both define the same set of lang items, -// and this will cause the E0152 "found duplicate lang item" error. See -// discussion in #50466 for details. -// -// This cfg won't affect doc tests. -#![cfg(not(test))] -// #![stable(feature = "core", since = "1.6.0")] #![doc( html_playground_url = "https://play.rust-lang.org/", @@ -64,7 +52,6 @@ )] #![doc(rust_logo)] #![doc(cfg_hide( - not(test), no_fp_fmt_parse, target_pointer_width = "16", target_pointer_width = "32", @@ -228,13 +215,9 @@ extern crate self as core; #[allow(unused)] use prelude::rust_2024::*; -#[cfg(not(test))] // See #65860 #[macro_use] mod macros; -// We don't export this through #[macro_export] for now, to avoid breakage. -// See https://github.com/rust-lang/rust/issues/82913 -#[cfg(not(test))] #[unstable(feature = "assert_matches", issue = "82775")] /// Unstable module containing the unstable `assert_matches` macro. pub mod assert_matches { diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index a527a2ea5aa..fa0d882181a 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -37,7 +37,7 @@ macro_rules! panic { /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "assert_eq_macro")] +#[rustc_diagnostic_item = "assert_eq_macro"] #[allow_internal_unstable(panic_internals)] macro_rules! assert_eq { ($left:expr, $right:expr $(,)?) => { @@ -93,7 +93,7 @@ macro_rules! assert_eq { /// ``` #[macro_export] #[stable(feature = "assert_ne", since = "1.13.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "assert_ne_macro")] +#[rustc_diagnostic_item = "assert_ne_macro"] #[allow_internal_unstable(panic_internals)] macro_rules! assert_ne { ($left:expr, $right:expr $(,)?) => { @@ -331,7 +331,7 @@ macro_rules! debug_assert { /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "debug_assert_eq_macro")] +#[rustc_diagnostic_item = "debug_assert_eq_macro"] macro_rules! debug_assert_eq { ($($arg:tt)*) => { if $crate::cfg!(debug_assertions) { @@ -361,7 +361,7 @@ macro_rules! debug_assert_eq { /// ``` #[macro_export] #[stable(feature = "assert_ne", since = "1.13.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "debug_assert_ne_macro")] +#[rustc_diagnostic_item = "debug_assert_ne_macro"] macro_rules! debug_assert_ne { ($($arg:tt)*) => { if $crate::cfg!(debug_assertions) { @@ -442,7 +442,7 @@ pub macro debug_assert_matches($($arg:tt)*) { /// ``` #[macro_export] #[stable(feature = "matches_macro", since = "1.42.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "matches_macro")] +#[rustc_diagnostic_item = "matches_macro"] macro_rules! matches { ($expression:expr, $pattern:pat $(if $guard:expr)? $(,)?) => { match $expression { @@ -617,7 +617,7 @@ macro_rules! r#try { /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "write_macro")] +#[rustc_diagnostic_item = "write_macro"] macro_rules! write { ($dst:expr, $($arg:tt)*) => { $dst.write_fmt($crate::format_args!($($arg)*)) @@ -651,7 +651,7 @@ macro_rules! write { /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "writeln_macro")] +#[rustc_diagnostic_item = "writeln_macro"] #[allow_internal_unstable(format_args_nl)] macro_rules! writeln { ($dst:expr $(,)?) => { @@ -718,7 +718,7 @@ macro_rules! writeln { #[rustc_builtin_macro(unreachable)] #[allow_internal_unstable(edition_panic)] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "unreachable_macro")] +#[rustc_diagnostic_item = "unreachable_macro"] macro_rules! unreachable { // Expands to either `$crate::panic::unreachable_2015` or `$crate::panic::unreachable_2021` // depending on the edition of the caller. @@ -803,7 +803,7 @@ macro_rules! unreachable { /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "unimplemented_macro")] +#[rustc_diagnostic_item = "unimplemented_macro"] #[allow_internal_unstable(panic_internals)] macro_rules! unimplemented { () => { @@ -883,7 +883,7 @@ macro_rules! unimplemented { /// ``` #[macro_export] #[stable(feature = "todo_macro", since = "1.40.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "todo_macro")] +#[rustc_diagnostic_item = "todo_macro"] #[allow_internal_unstable(panic_internals)] macro_rules! todo { () => { @@ -995,7 +995,7 @@ pub(crate) mod builtin { /// and cannot be stored for later use. /// This is a known limitation, see [#92698](https://github.com/rust-lang/rust/issues/92698). #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "format_args_macro")] + #[rustc_diagnostic_item = "format_args_macro"] #[allow_internal_unsafe] #[allow_internal_unstable(fmt_internals)] #[rustc_builtin_macro] @@ -1342,7 +1342,7 @@ pub(crate) mod builtin { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_builtin_macro] #[macro_export] - #[cfg_attr(not(test), rustc_diagnostic_item = "include_str_macro")] + #[rustc_diagnostic_item = "include_str_macro"] macro_rules! include_str { ($file:expr $(,)?) => {{ /* compiler built-in */ }}; } @@ -1382,7 +1382,7 @@ pub(crate) mod builtin { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_builtin_macro] #[macro_export] - #[cfg_attr(not(test), rustc_diagnostic_item = "include_bytes_macro")] + #[rustc_diagnostic_item = "include_bytes_macro"] macro_rules! include_bytes { ($file:expr $(,)?) => {{ /* compiler built-in */ }}; } diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index a4ab4674f4a..68011310d2c 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -82,7 +82,7 @@ macro marker_impls { /// [arc]: ../../std/sync/struct.Arc.html /// [ub]: ../../reference/behavior-considered-undefined.html #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "Send")] +#[rustc_diagnostic_item = "Send"] #[diagnostic::on_unimplemented( message = "`{Self}` cannot be sent between threads safely", label = "`{Self}` cannot be sent between threads safely" @@ -545,7 +545,7 @@ pub trait BikeshedGuaranteedNoDrop {} /// [transmute]: crate::mem::transmute /// [nomicon-send-and-sync]: ../../nomicon/send-and-sync.html #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "Sync")] +#[rustc_diagnostic_item = "Sync"] #[lang = "sync"] #[rustc_on_unimplemented( on( @@ -1305,7 +1305,7 @@ pub trait FnPtr: Copy + Clone { /// ``` #[rustc_builtin_macro(CoercePointee, attributes(pointee))] #[allow_internal_unstable(dispatch_from_dyn, coerce_unsized, unsize, coerce_pointee_validated)] -#[cfg_attr(not(test), rustc_diagnostic_item = "CoercePointee")] +#[rustc_diagnostic_item = "CoercePointee"] #[unstable(feature = "derive_coerce_pointee", issue = "123430")] pub macro CoercePointee($item:item) { /* compiler built-in */ diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index ce84f105e5c..d0be82adb6b 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -1065,161 +1065,46 @@ impl<T> MaybeUninit<T> { this.write_clone_of_slice(src) } - /// Fills a slice with elements by cloning `value`, returning a mutable reference to the now - /// initialized contents of the slice. - /// Any previously initialized elements will not be dropped. - /// - /// This is similar to [`slice::fill`]. - /// - /// # Panics - /// - /// This function will panic if any call to `Clone` panics. - /// - /// If such a panic occurs, any elements previously initialized during this operation will be - /// dropped. - /// - /// # Examples - /// - /// ``` - /// #![feature(maybe_uninit_fill)] - /// use std::mem::MaybeUninit; - /// - /// let mut buf = [const { MaybeUninit::uninit() }; 10]; - /// let initialized = MaybeUninit::fill(&mut buf, 1); - /// assert_eq!(initialized, &mut [1; 10]); - /// ``` - #[doc(alias = "memset")] + /// Deprecated version of [`slice::write_filled`]. #[unstable(feature = "maybe_uninit_fill", issue = "117428")] - pub fn fill(this: &mut [MaybeUninit<T>], value: T) -> &mut [T] + #[deprecated( + note = "replaced by inherent write_filled method; will eventually be removed", + since = "1.83.0" + )] + pub fn fill<'a>(this: &'a mut [MaybeUninit<T>], value: T) -> &'a mut [T] where T: Clone, { - SpecFill::spec_fill(this, value); - // SAFETY: Valid elements have just been filled into `this` so it is initialized - unsafe { this.assume_init_mut() } + this.write_filled(value) } - /// Fills a slice with elements returned by calling a closure repeatedly. - /// - /// This method uses a closure to create new values. If you'd rather `Clone` a given value, use - /// [`MaybeUninit::fill`]. If you want to use the `Default` trait to generate values, you can - /// pass [`Default::default`] as the argument. - /// - /// # Panics - /// - /// This function will panic if any call to the provided closure panics. - /// - /// If such a panic occurs, any elements previously initialized during this operation will be - /// dropped. - /// - /// # Examples - /// - /// ``` - /// #![feature(maybe_uninit_fill)] - /// use std::mem::MaybeUninit; - /// - /// let mut buf = [const { MaybeUninit::<i32>::uninit() }; 10]; - /// let initialized = MaybeUninit::fill_with(&mut buf, Default::default); - /// assert_eq!(initialized, &mut [0; 10]); - /// ``` + /// Deprecated version of [`slice::write_with`]. #[unstable(feature = "maybe_uninit_fill", issue = "117428")] - pub fn fill_with<F>(this: &mut [MaybeUninit<T>], mut f: F) -> &mut [T] + #[deprecated( + note = "replaced by inherent write_with method; will eventually be removed", + since = "1.83.0" + )] + pub fn fill_with<'a, F>(this: &'a mut [MaybeUninit<T>], mut f: F) -> &'a mut [T] where F: FnMut() -> T, { - let mut guard = Guard { slice: this, initialized: 0 }; - - for element in guard.slice.iter_mut() { - element.write(f()); - guard.initialized += 1; - } - - super::forget(guard); - - // SAFETY: Valid elements have just been written into `this` so it is initialized - unsafe { this.assume_init_mut() } + this.write_with(|_| f()) } - /// Fills a slice with elements yielded by an iterator until either all elements have been - /// initialized or the iterator is empty. - /// - /// Returns two slices. The first slice contains the initialized portion of the original slice. - /// The second slice is the still-uninitialized remainder of the original slice. - /// - /// # Panics - /// - /// This function panics if the iterator's `next` function panics. - /// - /// If such a panic occurs, any elements previously initialized during this operation will be - /// dropped. - /// - /// # Examples - /// - /// Completely filling the slice: - /// - /// ``` - /// #![feature(maybe_uninit_fill)] - /// use std::mem::MaybeUninit; - /// - /// let mut buf = [const { MaybeUninit::uninit() }; 5]; - /// - /// let iter = [1, 2, 3].into_iter().cycle(); - /// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter); - /// - /// assert_eq!(initialized, &mut [1, 2, 3, 1, 2]); - /// assert_eq!(remainder.len(), 0); - /// ``` - /// - /// Partially filling the slice: - /// - /// ``` - /// #![feature(maybe_uninit_fill)] - /// use std::mem::MaybeUninit; - /// - /// let mut buf = [const { MaybeUninit::uninit() }; 5]; - /// let iter = [1, 2]; - /// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter); - /// - /// assert_eq!(initialized, &mut [1, 2]); - /// assert_eq!(remainder.len(), 3); - /// ``` - /// - /// Checking an iterator after filling a slice: - /// - /// ``` - /// #![feature(maybe_uninit_fill)] - /// use std::mem::MaybeUninit; - /// - /// let mut buf = [const { MaybeUninit::uninit() }; 3]; - /// let mut iter = [1, 2, 3, 4, 5].into_iter(); - /// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter.by_ref()); - /// - /// assert_eq!(initialized, &mut [1, 2, 3]); - /// assert_eq!(remainder.len(), 0); - /// assert_eq!(iter.as_slice(), &[4, 5]); - /// ``` + /// Deprecated version of [`slice::write_iter`]. #[unstable(feature = "maybe_uninit_fill", issue = "117428")] - pub fn fill_from<I>(this: &mut [MaybeUninit<T>], it: I) -> (&mut [T], &mut [MaybeUninit<T>]) + #[deprecated( + note = "replaced by inherent write_iter method; will eventually be removed", + since = "1.83.0" + )] + pub fn fill_from<'a, I>( + this: &'a mut [MaybeUninit<T>], + it: I, + ) -> (&'a mut [T], &'a mut [MaybeUninit<T>]) where I: IntoIterator<Item = T>, { - let iter = it.into_iter(); - let mut guard = Guard { slice: this, initialized: 0 }; - - for (element, val) in guard.slice.iter_mut().zip(iter) { - element.write(val); - guard.initialized += 1; - } - - let initialized_len = guard.initialized; - super::forget(guard); - - // SAFETY: guard.initialized <= this.len() - let (initted, remainder) = unsafe { this.split_at_mut_unchecked(initialized_len) }; - - // SAFETY: Valid elements have just been written into `init`, so that portion - // of `this` is initialized. - (unsafe { initted.assume_init_mut() }, remainder) + this.write_iter(it) } /// Deprecated version of [`slice::as_bytes`]. @@ -1380,6 +1265,163 @@ impl<T> [MaybeUninit<T>] { unsafe { self.assume_init_mut() } } + /// Fills a slice with elements by cloning `value`, returning a mutable reference to the now + /// initialized contents of the slice. + /// Any previously initialized elements will not be dropped. + /// + /// This is similar to [`slice::fill`]. + /// + /// # Panics + /// + /// This function will panic if any call to `Clone` panics. + /// + /// If such a panic occurs, any elements previously initialized during this operation will be + /// dropped. + /// + /// # Examples + /// + /// ``` + /// #![feature(maybe_uninit_fill)] + /// use std::mem::MaybeUninit; + /// + /// let mut buf = [const { MaybeUninit::uninit() }; 10]; + /// let initialized = buf.write_filled(1); + /// assert_eq!(initialized, &mut [1; 10]); + /// ``` + #[doc(alias = "memset")] + #[unstable(feature = "maybe_uninit_fill", issue = "117428")] + pub fn write_filled(&mut self, value: T) -> &mut [T] + where + T: Clone, + { + SpecFill::spec_fill(self, value); + // SAFETY: Valid elements have just been filled into `self` so it is initialized + unsafe { self.assume_init_mut() } + } + + /// Fills a slice with elements returned by calling a closure for each index. + /// + /// This method uses a closure to create new values. If you'd rather `Clone` a given value, use + /// [`MaybeUninit::fill`]. If you want to use the `Default` trait to generate values, you can + /// pass [`|_| Default::default()`][Default::default] as the argument. + /// + /// # Panics + /// + /// This function will panic if any call to the provided closure panics. + /// + /// If such a panic occurs, any elements previously initialized during this operation will be + /// dropped. + /// + /// # Examples + /// + /// ``` + /// #![feature(maybe_uninit_fill)] + /// use std::mem::MaybeUninit; + /// + /// let mut buf = [const { MaybeUninit::<usize>::uninit() }; 5]; + /// let initialized = buf.write_with(|idx| idx + 1); + /// assert_eq!(initialized, &mut [1, 2, 3, 4, 5]); + /// ``` + #[unstable(feature = "maybe_uninit_fill", issue = "117428")] + pub fn write_with<F>(&mut self, mut f: F) -> &mut [T] + where + F: FnMut(usize) -> T, + { + let mut guard = Guard { slice: self, initialized: 0 }; + + for (idx, element) in guard.slice.iter_mut().enumerate() { + element.write(f(idx)); + guard.initialized += 1; + } + + super::forget(guard); + + // SAFETY: Valid elements have just been written into `this` so it is initialized + unsafe { self.assume_init_mut() } + } + + /// Fills a slice with elements yielded by an iterator until either all elements have been + /// initialized or the iterator is empty. + /// + /// Returns two slices. The first slice contains the initialized portion of the original slice. + /// The second slice is the still-uninitialized remainder of the original slice. + /// + /// # Panics + /// + /// This function panics if the iterator's `next` function panics. + /// + /// If such a panic occurs, any elements previously initialized during this operation will be + /// dropped. + /// + /// # Examples + /// + /// Completely filling the slice: + /// + /// ``` + /// #![feature(maybe_uninit_fill)] + /// use std::mem::MaybeUninit; + /// + /// let mut buf = [const { MaybeUninit::uninit() }; 5]; + /// + /// let iter = [1, 2, 3].into_iter().cycle(); + /// let (initialized, remainder) = buf.write_iter(iter); + /// + /// assert_eq!(initialized, &mut [1, 2, 3, 1, 2]); + /// assert_eq!(remainder.len(), 0); + /// ``` + /// + /// Partially filling the slice: + /// + /// ``` + /// #![feature(maybe_uninit_fill)] + /// use std::mem::MaybeUninit; + /// + /// let mut buf = [const { MaybeUninit::uninit() }; 5]; + /// let iter = [1, 2]; + /// let (initialized, remainder) = buf.write_iter(iter); + /// + /// assert_eq!(initialized, &mut [1, 2]); + /// assert_eq!(remainder.len(), 3); + /// ``` + /// + /// Checking an iterator after filling a slice: + /// + /// ``` + /// #![feature(maybe_uninit_fill)] + /// use std::mem::MaybeUninit; + /// + /// let mut buf = [const { MaybeUninit::uninit() }; 3]; + /// let mut iter = [1, 2, 3, 4, 5].into_iter(); + /// let (initialized, remainder) = buf.write_iter(iter.by_ref()); + /// + /// assert_eq!(initialized, &mut [1, 2, 3]); + /// assert_eq!(remainder.len(), 0); + /// assert_eq!(iter.as_slice(), &[4, 5]); + /// ``` + #[unstable(feature = "maybe_uninit_fill", issue = "117428")] + pub fn write_iter<I>(&mut self, it: I) -> (&mut [T], &mut [MaybeUninit<T>]) + where + I: IntoIterator<Item = T>, + { + let iter = it.into_iter(); + let mut guard = Guard { slice: self, initialized: 0 }; + + for (element, val) in guard.slice.iter_mut().zip(iter) { + element.write(val); + guard.initialized += 1; + } + + let initialized_len = guard.initialized; + super::forget(guard); + + // SAFETY: guard.initialized <= self.len() + let (initted, remainder) = unsafe { self.split_at_mut_unchecked(initialized_len) }; + + // SAFETY: Valid elements have just been written into `init`, so that portion + // of `this` is initialized. + (unsafe { initted.assume_init_mut() }, remainder) + } + /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes. /// /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 1494d7aca15..27387754633 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -140,7 +140,7 @@ pub use crate::intrinsics::transmute; #[inline] #[rustc_const_stable(feature = "const_forget", since = "1.46.0")] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "mem_forget")] +#[rustc_diagnostic_item = "mem_forget"] pub const fn forget<T>(t: T) { let _ = ManuallyDrop::new(t); } @@ -300,7 +300,7 @@ pub fn forget_unsized<T: ?Sized>(t: T) { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_promotable] #[rustc_const_stable(feature = "const_mem_size_of", since = "1.24.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of")] +#[rustc_diagnostic_item = "mem_size_of"] pub const fn size_of<T>() -> usize { intrinsics::size_of::<T>() } @@ -328,7 +328,7 @@ pub const fn size_of<T>() -> usize { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_size_of_val", since = "1.85.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of_val")] +#[rustc_diagnostic_item = "mem_size_of_val"] pub const fn size_of_val<T: ?Sized>(val: &T) -> usize { // SAFETY: `val` is a reference, so it's a valid raw pointer unsafe { intrinsics::size_of_val(val) } @@ -846,7 +846,7 @@ pub fn take<T: Default>(dest: &mut T) -> T { #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "if you don't need the old value, you can just assign the new value directly"] #[rustc_const_stable(feature = "const_replace", since = "1.83.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "mem_replace")] +#[rustc_diagnostic_item = "mem_replace"] pub const fn replace<T>(dest: &mut T, src: T) -> T { // It may be tempting to use `swap` to avoid `unsafe` here. Don't! // The compiler optimizes the implementation below to two `memcpy`s @@ -931,7 +931,7 @@ pub const fn replace<T>(dest: &mut T, src: T) -> T { /// [`RefCell`]: crate::cell::RefCell #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "mem_drop")] +#[rustc_diagnostic_item = "mem_drop"] pub fn drop<T>(_x: T) {} /// Bitwise-copies a value. @@ -1154,7 +1154,7 @@ impl<T> fmt::Debug for Discriminant<T> { /// ``` #[stable(feature = "discriminant_value", since = "1.21.0")] #[rustc_const_stable(feature = "const_discriminant", since = "1.75.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "mem_discriminant")] +#[rustc_diagnostic_item = "mem_discriminant"] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const fn discriminant<T>(v: &T) -> Discriminant<T> { Discriminant(intrinsics::discriminant_value(v)) @@ -1254,42 +1254,56 @@ impl<T> SizedTypeProperties for T {} /// Expands to the offset in bytes of a field from the beginning of the given type. /// -/// Structs, enums, unions and tuples are supported. +/// The type may be a `struct`, `enum`, `union`, or tuple. /// -/// Nested field accesses may be used, but not array indexes. +/// The field may be a nested field (`field1.field2`), but not an array index. +/// The field must be visible to the call site. /// -/// If the nightly-only feature `offset_of_enum` is enabled, -/// variants may be traversed as if they were fields. -/// Variants themselves do not have an offset. +/// The offset is returned as a [`usize`]. /// -/// Visibility is respected - all types and fields must be visible to the call site: +/// # Offsets of, and in, dynamically sized types /// -/// ``` -/// mod nested { -/// #[repr(C)] -/// pub struct Struct { -/// private: u8, -/// } -/// } +/// The field’s type must be [`Sized`], but it may be located in a [dynamically sized] container. +/// If the field type is dynamically sized, then you cannot use `offset_of!` (since the field's +/// alignment, and therefore its offset, may also be dynamic) and must take the offset from an +/// actual pointer to the container instead. /// -/// // assert_eq!(mem::offset_of!(nested::Struct, private), 0); -/// // ^^^ error[E0616]: field `private` of struct `Struct` is private -/// ``` -/// -/// Only [`Sized`] fields are supported, but the container may be unsized: /// ``` /// # use core::mem; +/// # use core::fmt::Debug; /// #[repr(C)] -/// pub struct Struct { +/// pub struct Struct<T: ?Sized> { /// a: u8, -/// b: [u8], +/// b: T, /// } /// -/// assert_eq!(mem::offset_of!(Struct, a), 0); // OK -/// // assert_eq!(mem::offset_of!(Struct, b), 1); -/// // ^^^ error[E0277]: doesn't have a size known at compile-time +/// #[derive(Debug)] +/// #[repr(C, align(4))] +/// struct Align4(u32); +/// +/// assert_eq!(mem::offset_of!(Struct<dyn Debug>, a), 0); // OK — Sized field +/// assert_eq!(mem::offset_of!(Struct<Align4>, b), 4); // OK — not DST +/// +/// // assert_eq!(mem::offset_of!(Struct<dyn Debug>, b), 1); +/// // ^^^ error[E0277]: ... cannot be known at compilation time +/// +/// // To obtain the offset of a !Sized field, examine a concrete value +/// // instead of using offset_of!. +/// let value: Struct<Align4> = Struct { a: 1, b: Align4(2) }; +/// let ref_unsized: &Struct<dyn Debug> = &value; +/// let offset_of_b = unsafe { +/// (&raw const ref_unsized.b).byte_offset_from_unsigned(ref_unsized) +/// }; +/// assert_eq!(offset_of_b, 4); /// ``` /// +/// If you need to obtain the offset of a field of a `!Sized` type, then, since the offset may +/// depend on the particular value being stored (in particular, `dyn Trait` values have a +/// dynamically-determined alignment), you must retrieve the offset from a specific reference +/// or pointer, and so you cannot use `offset_of!` to work without one. +/// +/// # Layout is subject to change +/// /// Note that type layout is, in general, [subject to change and /// platform-specific](https://doc.rust-lang.org/reference/type-layout.html). If /// layout stability is required, consider using an [explicit `repr` attribute]. @@ -1325,11 +1339,16 @@ impl<T> SizedTypeProperties for T {} /// /// [explicit `repr` attribute]: https://doc.rust-lang.org/reference/type-layout.html#representations /// +/// # Unstable features +/// +/// The following unstable features expand the functionality of `offset_of!`: +/// +/// * [`offset_of_enum`] — allows `enum` variants to be traversed as if they were fields. +/// * [`offset_of_slice`] — allows getting the offset of a field of type `[T]`. +/// /// # Examples /// /// ``` -/// #![feature(offset_of_enum)] -/// /// use std::mem; /// #[repr(C)] /// struct FieldStruct { @@ -1351,18 +1370,11 @@ impl<T> SizedTypeProperties for T {} /// struct NestedB(u8); /// /// assert_eq!(mem::offset_of!(NestedA, b.0), 0); -/// -/// #[repr(u8)] -/// enum Enum { -/// A(u8, u16), -/// B { one: u8, two: u16 }, -/// } -/// -/// assert_eq!(mem::offset_of!(Enum, A.0), 1); -/// assert_eq!(mem::offset_of!(Enum, B.two), 2); -/// -/// assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0); /// ``` +/// +/// [dynamically sized]: https://doc.rust-lang.org/reference/dynamically-sized-types.html +/// [`offset_of_enum`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/offset-of-enum.html +/// [`offset_of_slice`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/offset-of-slice.html #[stable(feature = "offset_of", since = "1.77.0")] #[allow_internal_unstable(builtin_syntax)] pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) { diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index 8e4417ec461..7aa5ed60d04 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs @@ -25,7 +25,7 @@ use crate::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not}; /// assert_eq!(localhost_v4.is_ipv6(), false); /// assert_eq!(localhost_v4.is_ipv4(), true); /// ``` -#[cfg_attr(not(test), rustc_diagnostic_item = "IpAddr")] +#[rustc_diagnostic_item = "IpAddr"] #[stable(feature = "ip_addr", since = "1.7.0")] #[derive(Copy, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] pub enum IpAddr { diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 5e45974b3d4..b17190971c3 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -12,11 +12,9 @@ #![unstable(feature = "f128", issue = "116909")] use crate::convert::FloatToInt; -#[cfg(not(test))] -use crate::intrinsics; -use crate::mem; use crate::num::FpCategory; use crate::panic::const_assert; +use crate::{intrinsics, mem}; /// Basic mathematical constants. #[unstable(feature = "f128", issue = "116909")] @@ -138,7 +136,6 @@ pub mod consts { pub const LN_10: f128 = 2.30258509299404568401799145468436420760110148862877297603333_f128; } -#[cfg(not(test))] impl f128 { // FIXME(f16_f128): almost all methods in this `impl` are missing examples and a const // implementation. Add these once we can run code on all platforms and have f16/f128 in CTFE. diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index e3176cd1688..d20677f43b4 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -12,11 +12,9 @@ #![unstable(feature = "f16", issue = "116909")] use crate::convert::FloatToInt; -#[cfg(not(test))] -use crate::intrinsics; -use crate::mem; use crate::num::FpCategory; use crate::panic::const_assert; +use crate::{intrinsics, mem}; /// Basic mathematical constants. #[unstable(feature = "f16", issue = "116909")] @@ -133,7 +131,6 @@ pub mod consts { pub const LN_10: f16 = 2.30258509299404568401799145468436421_f16; } -#[cfg(not(test))] impl f16 { // FIXME(f16_f128): almost all methods in this `impl` are missing examples and a const // implementation. Add these once we can run code on all platforms and have f16/f128 in CTFE. diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index de1557ccc90..79d864e1b19 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -12,11 +12,9 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::convert::FloatToInt; -#[cfg(not(test))] -use crate::intrinsics; -use crate::mem; use crate::num::FpCategory; use crate::panic::const_assert; +use crate::{intrinsics, mem}; /// The radix or base of the internal representation of `f32`. /// Use [`f32::RADIX`] instead. @@ -386,7 +384,6 @@ pub mod consts { pub const LN_10: f32 = 2.30258509299404568401799145468436421_f32; } -#[cfg(not(test))] impl f32 { /// The radix or base of the internal representation of `f32`. #[stable(feature = "assoc_int_consts", since = "1.43.0")] @@ -416,7 +413,7 @@ impl f32 { /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon /// [`MANTISSA_DIGITS`]: f32::MANTISSA_DIGITS #[stable(feature = "assoc_int_consts", since = "1.43.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "f32_epsilon")] + #[rustc_diagnostic_item = "f32_epsilon"] pub const EPSILON: f32 = 1.19209290e-07_f32; /// Smallest finite `f32` value. diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 65b5f3b9af0..ca28b40bb3a 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -12,11 +12,9 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::convert::FloatToInt; -#[cfg(not(test))] -use crate::intrinsics; -use crate::mem; use crate::num::FpCategory; use crate::panic::const_assert; +use crate::{intrinsics, mem}; /// The radix or base of the internal representation of `f64`. /// Use [`f64::RADIX`] instead. @@ -386,7 +384,6 @@ pub mod consts { pub const LN_10: f64 = 2.30258509299404568401799145468436421_f64; } -#[cfg(not(test))] impl f64 { /// The radix or base of the internal representation of `f64`. #[stable(feature = "assoc_int_consts", since = "1.43.0")] @@ -415,7 +412,7 @@ impl f64 { /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon /// [`MANTISSA_DIGITS`]: f64::MANTISSA_DIGITS #[stable(feature = "assoc_int_consts", since = "1.43.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "f64_epsilon")] + #[rustc_diagnostic_item = "f64_epsilon"] pub const EPSILON: f64 = 2.2204460492503131e-16_f64; /// Smallest finite `f64` value. diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index 8993e14fcd3..ef7e6f9c2f4 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -79,7 +79,8 @@ use crate::{convert, ops}; /// [`Break`]: ControlFlow::Break /// [`Continue`]: ControlFlow::Continue #[stable(feature = "control_flow_enum_type", since = "1.55.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "ControlFlow")] +#[rustc_diagnostic_item = "ControlFlow"] +#[must_use] // ControlFlow should not implement PartialOrd or Ord, per RFC 3058: // https://rust-lang.github.io/rfcs/3058-try-trait-v2.html#traits-for-controlflow #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] diff --git a/library/core/src/option.rs b/library/core/src/option.rs index f668c6f0672..7ec0ac71271 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -924,7 +924,7 @@ impl<T> Option<T> { #[inline] #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "option_expect")] + #[rustc_diagnostic_item = "option_expect"] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn expect(self, msg: &str) -> T { @@ -969,7 +969,7 @@ impl<T> Option<T> { #[inline(always)] #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "option_unwrap")] + #[rustc_diagnostic_item = "option_unwrap"] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn unwrap(self) -> T { diff --git a/library/core/src/panic/unwind_safe.rs b/library/core/src/panic/unwind_safe.rs index 37859212c0e..a60f0799c0e 100644 --- a/library/core/src/panic/unwind_safe.rs +++ b/library/core/src/panic/unwind_safe.rs @@ -82,7 +82,7 @@ use crate::task::{Context, Poll}; /// [`AssertUnwindSafe`] wrapper struct can be used to force this trait to be /// implemented for any closed over variables passed to `catch_unwind`. #[stable(feature = "catch_unwind", since = "1.9.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "unwind_safe_trait")] +#[rustc_diagnostic_item = "unwind_safe_trait"] #[diagnostic::on_unimplemented( message = "the type `{Self}` may not be safely transferred across an unwind boundary", label = "`{Self}` may not be safely transferred across an unwind boundary" @@ -98,7 +98,7 @@ pub auto trait UnwindSafe {} /// This is a "helper marker trait" used to provide impl blocks for the /// [`UnwindSafe`] trait, for more information see that documentation. #[stable(feature = "catch_unwind", since = "1.9.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "ref_unwind_safe_trait")] +#[rustc_diagnostic_item = "ref_unwind_safe_trait"] #[diagnostic::on_unimplemented( message = "the type `{Self}` may contain interior mutability and a reference may not be safely \ transferrable across a catch_unwind boundary", diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index 48707506389..9c5da306e27 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -61,6 +61,8 @@ pub trait Pointee { // NOTE: Keep trait bounds in `static_assert_expected_bounds_for_metadata` // in `library/core/src/ptr/metadata.rs` // in sync with those here: + // NOTE: The metadata of `dyn Trait + 'a` is `DynMetadata<dyn Trait + 'a>` + // so a `'static` bound must not be added. type Metadata: fmt::Debug + Copy + Send + Sync + Ord + Hash + Unpin + Freeze; } diff --git a/library/core/src/result.rs b/library/core/src/result.rs index ee98a47523f..48ab9267f21 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -654,7 +654,7 @@ impl<T, E> Result<T, E> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "result_ok_method")] + #[rustc_diagnostic_item = "result_ok_method"] pub fn ok(self) -> Option<T> { match self { Ok(x) => Some(x), diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 51b25fa40e3..91befdb8c78 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -7,7 +7,6 @@ use crate::fmt::{self, Write}; use crate::intrinsics::const_eval_select; use crate::{ascii, iter, ops}; -#[cfg(not(test))] impl [u8] { /// Checks if all bytes in this slice are within the ASCII range. #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs index 804bdfcbb4f..da85f42926e 100644 --- a/library/core/src/slice/cmp.rs +++ b/library/core/src/slice/cmp.rs @@ -282,4 +282,4 @@ macro_rules! impl_slice_contains { }; } -impl_slice_contains!(u16, u32, u64, i16, i32, i64, f32, f64, usize, isize); +impl_slice_contains!(u16, u32, u64, i16, i32, i64, f32, f64, usize, isize, char); diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 3570d8d0876..5bb7243c449 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -97,7 +97,6 @@ enum Direction { Back, } -#[cfg(not(test))] impl<T> [T] { /// Returns the number of elements in the slice. /// @@ -1045,7 +1044,7 @@ impl<T> [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - #[cfg_attr(not(test), rustc_diagnostic_item = "slice_iter")] + #[rustc_diagnostic_item = "slice_iter"] pub fn iter(&self) -> Iter<'_, T> { Iter::new(self) } @@ -4446,8 +4445,10 @@ impl<T> [T] { /// ``` #[inline] #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")] - pub fn split_off_first<'a>(self: &mut &'a Self) -> Option<&'a T> { - let (first, rem) = self.split_first()?; + #[rustc_const_unstable(feature = "const_split_off_first_last", issue = "138539")] + pub const fn split_off_first<'a>(self: &mut &'a Self) -> Option<&'a T> { + // FIXME(const-hack): Use `?` when available in const instead of `let-else`. + let Some((first, rem)) = self.split_first() else { return None }; *self = rem; Some(first) } @@ -4469,8 +4470,11 @@ impl<T> [T] { /// ``` #[inline] #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")] - pub fn split_off_first_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> { - let (first, rem) = mem::take(self).split_first_mut()?; + #[rustc_const_unstable(feature = "const_split_off_first_last", issue = "138539")] + pub const fn split_off_first_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> { + // FIXME(const-hack): Use `mem::take` and `?` when available in const. + // Original: `mem::take(self).split_first_mut()?` + let Some((first, rem)) = mem::replace(self, &mut []).split_first_mut() else { return None }; *self = rem; Some(first) } @@ -4491,8 +4495,10 @@ impl<T> [T] { /// ``` #[inline] #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")] - pub fn split_off_last<'a>(self: &mut &'a Self) -> Option<&'a T> { - let (last, rem) = self.split_last()?; + #[rustc_const_unstable(feature = "const_split_off_first_last", issue = "138539")] + pub const fn split_off_last<'a>(self: &mut &'a Self) -> Option<&'a T> { + // FIXME(const-hack): Use `?` when available in const instead of `let-else`. + let Some((last, rem)) = self.split_last() else { return None }; *self = rem; Some(last) } @@ -4514,8 +4520,11 @@ impl<T> [T] { /// ``` #[inline] #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")] - pub fn split_off_last_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> { - let (last, rem) = mem::take(self).split_last_mut()?; + #[rustc_const_unstable(feature = "const_split_off_first_last", issue = "138539")] + pub const fn split_off_last_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> { + // FIXME(const-hack): Use `mem::take` and `?` when available in const. + // Original: `mem::take(self).split_last_mut()?` + let Some((last, rem)) = mem::replace(self, &mut []).split_last_mut() else { return None }; *self = rem; Some(last) } @@ -4844,7 +4853,6 @@ impl<T, const N: usize> [[T; N]] { } } -#[cfg(not(test))] impl [f32] { /// Sorts the slice of floats. /// @@ -4873,7 +4881,6 @@ impl [f32] { } } -#[cfg(not(test))] impl [f64] { /// Sorts the slice of floats. /// diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 83ad10db2da..5cc08f8a71a 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -114,7 +114,6 @@ fn slice_error_fail_rt(s: &str, begin: usize, end: usize) -> ! { ); } -#[cfg(not(test))] impl str { /// Returns the length of `self`. /// @@ -134,7 +133,7 @@ impl str { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_str_len", since = "1.39.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "str_len")] + #[rustc_diagnostic_item = "str_len"] #[must_use] #[inline] pub const fn len(&self) -> usize { @@ -1029,7 +1028,7 @@ impl str { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - #[cfg_attr(not(test), rustc_diagnostic_item = "str_chars")] + #[rustc_diagnostic_item = "str_chars"] pub fn chars(&self) -> Chars<'_> { Chars { iter: self.as_bytes().iter() } } @@ -1160,7 +1159,7 @@ impl str { #[must_use = "this returns the split string as an iterator, \ without modifying the original"] #[stable(feature = "split_whitespace", since = "1.1.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "str_split_whitespace")] + #[rustc_diagnostic_item = "str_split_whitespace"] #[inline] pub fn split_whitespace(&self) -> SplitWhitespace<'_> { SplitWhitespace { inner: self.split(IsWhitespace).filter(IsNotEmpty) } @@ -1355,7 +1354,7 @@ impl str { /// assert!(bananas.starts_with(&['a', 'b', 'c', 'd'])); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "str_starts_with")] + #[rustc_diagnostic_item = "str_starts_with"] pub fn starts_with<P: Pattern>(&self, pat: P) -> bool { pat.is_prefix_of(self) } @@ -1380,7 +1379,7 @@ impl str { /// assert!(!bananas.ends_with("nana")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "str_ends_with")] + #[rustc_diagnostic_item = "str_ends_with"] pub fn ends_with<P: Pattern>(&self, pat: P) -> bool where for<'a> P::Searcher<'a>: ReverseSearcher<'a>, @@ -2114,7 +2113,7 @@ impl str { #[must_use = "this returns the trimmed string as a slice, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "str_trim")] + #[rustc_diagnostic_item = "str_trim"] pub fn trim(&self) -> &str { self.trim_matches(|c: char| c.is_whitespace()) } @@ -2153,7 +2152,7 @@ impl str { #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] #[stable(feature = "trim_direction", since = "1.30.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "str_trim_start")] + #[rustc_diagnostic_item = "str_trim_start"] pub fn trim_start(&self) -> &str { self.trim_start_matches(|c: char| c.is_whitespace()) } @@ -2192,7 +2191,7 @@ impl str { #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] #[stable(feature = "trim_direction", since = "1.30.0")] - #[cfg_attr(not(test), rustc_diagnostic_item = "str_trim_end")] + #[rustc_diagnostic_item = "str_trim_end"] pub fn trim_end(&self) -> &str { self.trim_end_matches(|c: char| c.is_whitespace()) } diff --git a/library/core/src/str/pattern.rs b/library/core/src/str/pattern.rs index 2d941adfd85..bcbbb11c83b 100644 --- a/library/core/src/str/pattern.rs +++ b/library/core/src/str/pattern.rs @@ -644,21 +644,21 @@ where impl<const N: usize> MultiCharEq for [char; N] { #[inline] fn matches(&mut self, c: char) -> bool { - self.iter().any(|&m| m == c) + self.contains(&c) } } impl<const N: usize> MultiCharEq for &[char; N] { #[inline] fn matches(&mut self, c: char) -> bool { - self.iter().any(|&m| m == c) + self.contains(&c) } } impl MultiCharEq for &[char] { #[inline] fn matches(&mut self, c: char) -> bool { - self.iter().any(|&m| m == c) + self.contains(&c) } } diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 54a65c8459e..88bee622031 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -295,7 +295,7 @@ unsafe impl Sync for AtomicBool {} /// loads and stores of pointers. Its size depends on the target pointer's size. #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "AtomicPtr")] +#[rustc_diagnostic_item = "AtomicPtr"] #[cfg_attr(target_pointer_width = "16", repr(C, align(2)))] #[cfg_attr(target_pointer_width = "32", repr(C, align(4)))] #[cfg_attr(target_pointer_width = "64", repr(C, align(8)))] @@ -3446,7 +3446,7 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicI8"), + rustc_diagnostic_item = "AtomicI8", "i8", "", atomic_min, atomic_max, @@ -3465,7 +3465,7 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicU8"), + rustc_diagnostic_item = "AtomicU8", "u8", "", atomic_umin, atomic_umax, @@ -3484,7 +3484,7 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicI16"), + rustc_diagnostic_item = "AtomicI16", "i16", "", atomic_min, atomic_max, @@ -3503,7 +3503,7 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicU16"), + rustc_diagnostic_item = "AtomicU16", "u16", "", atomic_umin, atomic_umax, @@ -3522,7 +3522,7 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicI32"), + rustc_diagnostic_item = "AtomicI32", "i32", "", atomic_min, atomic_max, @@ -3541,7 +3541,7 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicU32"), + rustc_diagnostic_item = "AtomicU32", "u32", "", atomic_umin, atomic_umax, @@ -3560,7 +3560,7 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicI64"), + rustc_diagnostic_item = "AtomicI64", "i64", "", atomic_min, atomic_max, @@ -3579,7 +3579,7 @@ atomic_int! { stable(feature = "integer_atomics_stable", since = "1.34.0"), rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicU64"), + rustc_diagnostic_item = "AtomicU64", "u64", "", atomic_umin, atomic_umax, @@ -3598,7 +3598,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "99069"), rustc_const_unstable(feature = "integer_atomics", issue = "99069"), rustc_const_unstable(feature = "integer_atomics", issue = "99069"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicI128"), + rustc_diagnostic_item = "AtomicI128", "i128", "#![feature(integer_atomics)]\n\n", atomic_min, atomic_max, @@ -3617,7 +3617,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "99069"), rustc_const_unstable(feature = "integer_atomics", issue = "99069"), rustc_const_unstable(feature = "integer_atomics", issue = "99069"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicU128"), + rustc_diagnostic_item = "AtomicU128", "u128", "#![feature(integer_atomics)]\n\n", atomic_umin, atomic_umax, @@ -3640,7 +3640,7 @@ macro_rules! atomic_int_ptr_sized { stable(feature = "atomic_nand", since = "1.27.0"), rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicIsize"), + rustc_diagnostic_item = "AtomicIsize", "isize", "", atomic_min, atomic_max, @@ -3659,7 +3659,7 @@ macro_rules! atomic_int_ptr_sized { stable(feature = "atomic_nand", since = "1.27.0"), rustc_const_stable(feature = "const_ptr_sized_atomics", since = "1.24.0"), rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0"), - cfg_attr(not(test), rustc_diagnostic_item = "AtomicUsize"), + rustc_diagnostic_item = "AtomicUsize", "usize", "", atomic_umin, atomic_umax, diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 3f57b04753a..9b8fefe42af 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -402,7 +402,7 @@ impl<'a> ContextBuilder<'a> { /// [`Wake`]: ../../alloc/task/trait.Wake.html #[repr(transparent)] #[stable(feature = "futures_api", since = "1.36.0")] -#[cfg_attr(not(test), rustc_diagnostic_item = "Waker")] +#[rustc_diagnostic_item = "Waker"] pub struct Waker { waker: RawWaker, } diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 37b5c1076fa..18c03b4a6f8 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -77,7 +77,7 @@ const DAYS_PER_WEEK: u64 = 7; /// crate to do so. #[stable(feature = "duration", since = "1.3.0")] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] -#[cfg_attr(not(test), rustc_diagnostic_item = "Duration")] +#[rustc_diagnostic_item = "Duration"] pub struct Duration { secs: u64, nanos: Nanoseconds, // Always 0 <= nanos < NANOS_PER_SEC diff --git a/library/core/src/unit.rs b/library/core/src/unit.rs index d656005f3d4..d54816c444b 100644 --- a/library/core/src/unit.rs +++ b/library/core/src/unit.rs @@ -17,3 +17,19 @@ impl FromIterator<()> for () { iter.into_iter().for_each(|()| {}) } } + +pub(crate) trait IsUnit { + fn is_unit() -> bool; +} + +impl<T: ?Sized> IsUnit for T { + default fn is_unit() -> bool { + false + } +} + +impl IsUnit for () { + fn is_unit() -> bool { + true + } +} diff --git a/library/coretests/tests/fmt/mod.rs b/library/coretests/tests/fmt/mod.rs index 025c69c4f62..3f082a90770 100644 --- a/library/coretests/tests/fmt/mod.rs +++ b/library/coretests/tests/fmt/mod.rs @@ -15,8 +15,31 @@ fn test_format_flags() { fn test_pointer_formats_data_pointer() { let b: &[u8] = b""; let s: &str = ""; - assert_eq!(format!("{s:p}"), format!("{:p}", s.as_ptr())); - assert_eq!(format!("{b:p}"), format!("{:p}", b.as_ptr())); + assert_eq!(format!("{s:p}"), format!("{:p}", s as *const _)); + assert_eq!(format!("{b:p}"), format!("{:p}", b as *const _)); +} + +#[test] +fn test_fmt_debug_of_raw_pointers() { + use core::fmt::Debug; + use core::ptr; + + fn check_fmt<T: Debug>(t: T, start: &str, contains: &str) { + let formatted = format!("{:?}", t); + assert!(formatted.starts_with(start), "{formatted:?} doesn't start with {start:?}"); + assert!(formatted.contains(contains), "{formatted:?} doesn't contain {contains:?}"); + } + + assert_eq!(format!("{:?}", ptr::without_provenance_mut::<i32>(0x100)), "0x100"); + assert_eq!(format!("{:?}", ptr::without_provenance::<i32>(0x100)), "0x100"); + + let slice = ptr::slice_from_raw_parts(ptr::without_provenance::<i32>(0x100), 3); + assert_eq!(format!("{:?}", slice as *mut [i32]), "Pointer { addr: 0x100, metadata: 3 }"); + assert_eq!(format!("{:?}", slice as *const [i32]), "Pointer { addr: 0x100, metadata: 3 }"); + + let vtable = &mut 500 as &mut dyn Debug; + check_fmt(vtable as *mut dyn Debug, "Pointer { addr: ", ", metadata: DynMetadata("); + check_fmt(vtable as *const dyn Debug, "Pointer { addr: ", ", metadata: DynMetadata("); } #[test] diff --git a/library/coretests/tests/mem.rs b/library/coretests/tests/mem.rs index 9cb94ca3b0f..9c15be4a8c4 100644 --- a/library/coretests/tests/mem.rs +++ b/library/coretests/tests/mem.rs @@ -1,5 +1,5 @@ use core::mem::*; -use core::ptr; +use core::{array, ptr}; #[cfg(panic = "unwind")] use std::rc::Rc; @@ -327,11 +327,11 @@ fn uninit_write_clone_of_slice_no_drop() { } #[test] -fn uninit_fill() { +fn uninit_write_filled() { let mut dst = [MaybeUninit::new(255); 64]; let expect = [0; 64]; - assert_eq!(MaybeUninit::fill(&mut dst, 0), &expect); + assert_eq!(dst.write_filled(0), &expect); } #[cfg(panic = "unwind")] @@ -352,7 +352,7 @@ impl Clone for CloneUntilPanic { #[test] #[cfg(panic = "unwind")] -fn uninit_fill_clone_panic_drop() { +fn uninit_write_filled_panic_drop() { use std::panic; let rc = Rc::new(()); @@ -361,7 +361,7 @@ fn uninit_fill_clone_panic_drop() { let src = CloneUntilPanic { limit: 3, rc: rc.clone() }; let err = panic::catch_unwind(panic::AssertUnwindSafe(|| { - MaybeUninit::fill(&mut dst, src); + dst.write_filled(src); })); match err { @@ -378,23 +378,23 @@ fn uninit_fill_clone_panic_drop() { #[test] #[cfg(panic = "unwind")] -fn uninit_fill_clone_no_drop_clones() { +fn uninit_write_filled_no_drop_clones() { let mut dst = [MaybeUninit::uninit(), MaybeUninit::uninit(), MaybeUninit::uninit()]; - MaybeUninit::fill(&mut dst, Bomb); + dst.write_filled(Bomb); } #[test] -fn uninit_fill_with() { - let mut dst = [MaybeUninit::new(255); 64]; - let expect = [0; 64]; +fn uninit_write_with() { + let mut dst = [MaybeUninit::new(255usize); 64]; + let expect = array::from_fn::<usize, 64, _>(|idx| idx); - assert_eq!(MaybeUninit::fill_with(&mut dst, || 0), &expect); + assert_eq!(dst.write_with(|idx| idx), &expect); } #[test] #[cfg(panic = "unwind")] -fn uninit_fill_with_mid_panic() { +fn uninit_write_with_mid_panic() { use std::panic; let rc = Rc::new(()); @@ -403,7 +403,7 @@ fn uninit_fill_with_mid_panic() { let src = CloneUntilPanic { limit: 3, rc: rc.clone() }; let err = panic::catch_unwind(panic::AssertUnwindSafe(|| { - MaybeUninit::fill_with(&mut dst, || src.clone()); + dst.write_with(|_| src.clone()); })); drop(src); @@ -423,58 +423,58 @@ fn uninit_fill_with_mid_panic() { #[test] #[cfg(panic = "unwind")] -fn uninit_fill_with_no_drop() { +fn uninit_write_with_no_drop() { let mut dst = [MaybeUninit::uninit()]; let src = Bomb; - MaybeUninit::fill_with(&mut dst, || src.clone()); + dst.write_with(|_| src.clone()); forget(src); } #[test] -fn uninit_fill_from() { +fn uninit_write_iter() { let mut dst = [MaybeUninit::new(255); 64]; let src = [0; 64]; - let (initted, remainder) = MaybeUninit::fill_from(&mut dst, src.into_iter()); + let (initted, remainder) = dst.write_iter(src.into_iter()); assert_eq!(initted, &src); assert_eq!(remainder.len(), 0); } #[test] -fn uninit_fill_from_partial() { +fn uninit_write_iter_partial() { let mut dst = [MaybeUninit::new(255); 64]; let src = [0; 48]; - let (initted, remainder) = MaybeUninit::fill_from(&mut dst, src.into_iter()); + let (initted, remainder) = dst.write_iter(src.into_iter()); assert_eq!(initted, &src); assert_eq!(remainder.len(), 16); } #[test] -fn uninit_over_fill() { +fn uninit_write_iter_overfill() { let mut dst = [MaybeUninit::new(255); 64]; let src = [0; 72]; - let (initted, remainder) = MaybeUninit::fill_from(&mut dst, src.into_iter()); + let (initted, remainder) = dst.write_iter(src.into_iter()); assert_eq!(initted, &src[0..64]); assert_eq!(remainder.len(), 0); } #[test] -fn uninit_empty_fill() { +fn uninit_write_iter_empty() { let mut dst = [MaybeUninit::new(255); 64]; let src = [0; 0]; - let (initted, remainder) = MaybeUninit::fill_from(&mut dst, src.into_iter()); + let (initted, remainder) = dst.write_iter(src.into_iter()); assert_eq!(initted, &src[0..0]); assert_eq!(remainder.len(), 64); } #[test] #[cfg(panic = "unwind")] -fn uninit_fill_from_mid_panic() { +fn uninit_write_iter_mid_panic() { use std::panic; struct IterUntilPanic { @@ -504,7 +504,7 @@ fn uninit_fill_from_mid_panic() { let src = IterUntilPanic { limit: 3, rc: rc.clone() }; let err = panic::catch_unwind(panic::AssertUnwindSafe(|| { - MaybeUninit::fill_from(&mut dst, src); + dst.write_iter(src); })); match err { @@ -522,11 +522,11 @@ fn uninit_fill_from_mid_panic() { #[test] #[cfg(panic = "unwind")] -fn uninit_fill_from_no_drop() { +fn uninit_write_iter_no_drop() { let mut dst = [MaybeUninit::uninit()]; let src = [Bomb]; - MaybeUninit::fill_from(&mut dst, src.iter()); + dst.write_iter(src.iter()); forget(src); } diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs index a284633ea2f..e5c1d6bdb3b 100644 --- a/library/panic_unwind/src/lib.rs +++ b/library/panic_unwind/src/lib.rs @@ -79,9 +79,11 @@ cfg_if::cfg_if! { unsafe extern "C" { /// Handler in std called when a panic object is dropped outside of /// `catch_unwind`. + #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)] fn __rust_drop_panic() -> !; /// Handler in std called when a foreign exception is caught. + #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)] fn __rust_foreign_exception() -> !; } diff --git a/library/portable-simd/beginners-guide.md b/library/portable-simd/beginners-guide.md index 17ade06ae80..dc08d847ced 100644 --- a/library/portable-simd/beginners-guide.md +++ b/library/portable-simd/beginners-guide.md @@ -80,12 +80,12 @@ Most of the portable SIMD API is designed to allow the user to gloss over the de Fortunately, most SIMD types have a fairly predictable size. `i32x4` is bit-equivalent to `[i32; 4]` and so can be bitcast to it, e.g. using [`mem::transmute`], though the API usually offers a safe cast you can use instead. -However, this is not the same as alignment. Computer architectures generally prefer aligned accesses, especially when moving data between memory and vector registers, and while some support specialized operations that can bend the rules to help with this, unaligned access is still typically slow, or even undefined behavior. In addition, different architectures can require different alignments when interacting with their native SIMD types. For this reason, any `#[repr(simd)]` type has a non-portable alignment. If it is necessary to directly interact with the alignment of these types, it should be via [`mem::align_of`]. +However, this is not the same as alignment. Computer architectures generally prefer aligned accesses, especially when moving data between memory and vector registers, and while some support specialized operations that can bend the rules to help with this, unaligned access is still typically slow, or even undefined behavior. In addition, different architectures can require different alignments when interacting with their native SIMD types. For this reason, any `#[repr(simd)]` type has a non-portable alignment. If it is necessary to directly interact with the alignment of these types, it should be via [`align_of`]. When working with slices, data correctly aligned for SIMD can be acquired using the [`as_simd`] and [`as_simd_mut`] methods of the slice primitive. [`mem::transmute`]: https://doc.rust-lang.org/core/mem/fn.transmute.html -[`mem::align_of`]: https://doc.rust-lang.org/core/mem/fn.align_of.html +[`align_of`]: https://doc.rust-lang.org/core/mem/fn.align_of.html [`as_simd`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_simd [`as_simd_mut`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_simd_mut diff --git a/library/portable-simd/crates/core_simd/Cargo.toml b/library/portable-simd/crates/core_simd/Cargo.toml index a7a6d43b11d..537ce459c07 100644 --- a/library/portable-simd/crates/core_simd/Cargo.toml +++ b/library/portable-simd/crates/core_simd/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "core_simd" version = "0.1.0" -edition = "2021" +edition = "2024" homepage = "https://github.com/rust-lang/portable-simd" repository = "https://github.com/rust-lang/portable-simd" keywords = ["core", "simd", "intrinsics"] diff --git a/library/portable-simd/crates/core_simd/src/lib.rs b/library/portable-simd/crates/core_simd/src/lib.rs index 7f57847c9c2..717b882b64b 100644 --- a/library/portable-simd/crates/core_simd/src/lib.rs +++ b/library/portable-simd/crates/core_simd/src/lib.rs @@ -35,7 +35,11 @@ feature(stdarch_x86_avx512) )] #![warn(missing_docs, clippy::missing_inline_in_public_items)] // basically all items, really -#![deny(unsafe_op_in_unsafe_fn, clippy::undocumented_unsafe_blocks)] +#![deny( + unsafe_op_in_unsafe_fn, + unreachable_pub, + clippy::undocumented_unsafe_blocks +)] #![doc(test(attr(deny(warnings))))] #![allow(internal_features)] #![unstable(feature = "portable_simd", issue = "86656")] diff --git a/library/portable-simd/crates/core_simd/src/masks/bitmask.rs b/library/portable-simd/crates/core_simd/src/masks/bitmask.rs index db4312d5bf8..8221d8f17e9 100644 --- a/library/portable-simd/crates/core_simd/src/masks/bitmask.rs +++ b/library/portable-simd/crates/core_simd/src/masks/bitmask.rs @@ -5,7 +5,7 @@ use core::marker::PhantomData; /// A mask where each lane is represented by a single bit. #[repr(transparent)] -pub struct Mask<T, const N: usize>( +pub(crate) struct Mask<T, const N: usize>( <LaneCount<N> as SupportedLaneCount>::BitMask, PhantomData<T>, ) @@ -78,7 +78,7 @@ where { #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub fn splat(value: bool) -> Self { + pub(crate) fn splat(value: bool) -> Self { let mut mask = <LaneCount<N> as SupportedLaneCount>::BitMask::default(); if value { mask.as_mut().fill(u8::MAX) @@ -93,12 +93,12 @@ where #[inline] #[must_use = "method returns a new bool and does not mutate the original value"] - pub unsafe fn test_unchecked(&self, lane: usize) -> bool { + pub(crate) unsafe fn test_unchecked(&self, lane: usize) -> bool { (self.0.as_ref()[lane / 8] >> (lane % 8)) & 0x1 > 0 } #[inline] - pub unsafe fn set_unchecked(&mut self, lane: usize, value: bool) { + pub(crate) unsafe fn set_unchecked(&mut self, lane: usize, value: bool) { unsafe { self.0.as_mut()[lane / 8] ^= ((value ^ self.test_unchecked(lane)) as u8) << (lane % 8) } @@ -106,7 +106,7 @@ where #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - pub fn to_int(self) -> Simd<T, N> { + pub(crate) fn to_int(self) -> Simd<T, N> { unsafe { core::intrinsics::simd::simd_select_bitmask( self.0, @@ -118,19 +118,19 @@ where #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub unsafe fn from_int_unchecked(value: Simd<T, N>) -> Self { + pub(crate) unsafe fn from_int_unchecked(value: Simd<T, N>) -> Self { unsafe { Self(core::intrinsics::simd::simd_bitmask(value), PhantomData) } } #[inline] - pub fn to_bitmask_integer(self) -> u64 { + pub(crate) fn to_bitmask_integer(self) -> u64 { let mut bitmask = [0u8; 8]; bitmask[..self.0.as_ref().len()].copy_from_slice(self.0.as_ref()); u64::from_ne_bytes(bitmask) } #[inline] - pub fn from_bitmask_integer(bitmask: u64) -> Self { + pub(crate) fn from_bitmask_integer(bitmask: u64) -> Self { let mut bytes = <LaneCount<N> as SupportedLaneCount>::BitMask::default(); let len = bytes.as_mut().len(); bytes @@ -141,7 +141,7 @@ where #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub fn convert<U>(self) -> Mask<U, N> + pub(crate) fn convert<U>(self) -> Mask<U, N> where U: MaskElement, { @@ -151,13 +151,13 @@ where #[inline] #[must_use = "method returns a new bool and does not mutate the original value"] - pub fn any(self) -> bool { + pub(crate) fn any(self) -> bool { self != Self::splat(false) } #[inline] #[must_use = "method returns a new bool and does not mutate the original value"] - pub fn all(self) -> bool { + pub(crate) fn all(self) -> bool { self == Self::splat(true) } } diff --git a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs index 387b508c4b4..4e98db4070a 100644 --- a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs +++ b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs @@ -3,7 +3,7 @@ use crate::simd::{LaneCount, MaskElement, Simd, SupportedLaneCount}; #[repr(transparent)] -pub struct Mask<T, const N: usize>(Simd<T, N>) +pub(crate) struct Mask<T, const N: usize>(Simd<T, N>) where T: MaskElement, LaneCount<N>: SupportedLaneCount; @@ -80,7 +80,7 @@ macro_rules! impl_reverse_bits { #[inline(always)] fn reverse_bits(self, n: usize) -> Self { let rev = <$int>::reverse_bits(self); - let bitsize = core::mem::size_of::<$int>() * 8; + let bitsize = size_of::<$int>() * 8; if n < bitsize { // Shift things back to the right rev >> (bitsize - n) @@ -102,36 +102,36 @@ where { #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub fn splat(value: bool) -> Self { + pub(crate) fn splat(value: bool) -> Self { Self(Simd::splat(if value { T::TRUE } else { T::FALSE })) } #[inline] #[must_use = "method returns a new bool and does not mutate the original value"] - pub unsafe fn test_unchecked(&self, lane: usize) -> bool { + pub(crate) unsafe fn test_unchecked(&self, lane: usize) -> bool { T::eq(self.0[lane], T::TRUE) } #[inline] - pub unsafe fn set_unchecked(&mut self, lane: usize, value: bool) { + pub(crate) unsafe fn set_unchecked(&mut self, lane: usize, value: bool) { self.0[lane] = if value { T::TRUE } else { T::FALSE } } #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - pub fn to_int(self) -> Simd<T, N> { + pub(crate) fn to_int(self) -> Simd<T, N> { self.0 } #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub unsafe fn from_int_unchecked(value: Simd<T, N>) -> Self { + pub(crate) unsafe fn from_int_unchecked(value: Simd<T, N>) -> Self { Self(value) } #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub fn convert<U>(self) -> Mask<U, N> + pub(crate) fn convert<U>(self) -> Mask<U, N> where U: MaskElement, { @@ -220,14 +220,14 @@ where #[inline] #[must_use = "method returns a new bool and does not mutate the original value"] - pub fn any(self) -> bool { + pub(crate) fn any(self) -> bool { // Safety: use `self` as an integer vector unsafe { core::intrinsics::simd::simd_reduce_any(self.to_int()) } } #[inline] #[must_use = "method returns a new bool and does not mutate the original value"] - pub fn all(self) -> bool { + pub(crate) fn all(self) -> bool { // Safety: use `self` as an integer vector unsafe { core::intrinsics::simd::simd_reduce_all(self.to_int()) } } diff --git a/library/portable-simd/crates/core_simd/src/ops.rs b/library/portable-simd/crates/core_simd/src/ops.rs index 4ac64a253a3..f36e8d01a73 100644 --- a/library/portable-simd/crates/core_simd/src/ops.rs +++ b/library/portable-simd/crates/core_simd/src/ops.rs @@ -1,4 +1,4 @@ -use crate::simd::{cmp::SimdPartialEq, LaneCount, Simd, SimdElement, SupportedLaneCount}; +use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount, cmp::SimdPartialEq}; use core::ops::{Add, Mul}; use core::ops::{BitAnd, BitOr, BitXor}; use core::ops::{Div, Rem, Sub}; diff --git a/library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs b/library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs index 93989ce91b8..2312ba401fa 100644 --- a/library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs +++ b/library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs @@ -1,6 +1,6 @@ use crate::simd::{ - ptr::{SimdConstPtr, SimdMutPtr}, LaneCount, Mask, Simd, SimdElement, SupportedLaneCount, + ptr::{SimdConstPtr, SimdMutPtr}, }; /// Parallel `PartialEq`. diff --git a/library/portable-simd/crates/core_simd/src/simd/cmp/ord.rs b/library/portable-simd/crates/core_simd/src/simd/cmp/ord.rs index 899f00a8316..e813e761303 100644 --- a/library/portable-simd/crates/core_simd/src/simd/cmp/ord.rs +++ b/library/portable-simd/crates/core_simd/src/simd/cmp/ord.rs @@ -1,7 +1,7 @@ use crate::simd::{ + LaneCount, Mask, Simd, SupportedLaneCount, cmp::SimdPartialEq, ptr::{SimdConstPtr, SimdMutPtr}, - LaneCount, Mask, Simd, SupportedLaneCount, }; /// Parallel `PartialOrd`. diff --git a/library/portable-simd/crates/core_simd/src/simd/num/float.rs b/library/portable-simd/crates/core_simd/src/simd/num/float.rs index db705dfe202..b5972c47373 100644 --- a/library/portable-simd/crates/core_simd/src/simd/num/float.rs +++ b/library/portable-simd/crates/core_simd/src/simd/num/float.rs @@ -1,7 +1,7 @@ use super::sealed::Sealed; use crate::simd::{ - cmp::{SimdPartialEq, SimdPartialOrd}, LaneCount, Mask, Simd, SimdCast, SimdElement, SupportedLaneCount, + cmp::{SimdPartialEq, SimdPartialOrd}, }; /// Operations on SIMD vectors of floats. @@ -263,7 +263,8 @@ macro_rules! impl_trait { unsafe { core::intrinsics::simd::simd_as(self) } } - // https://github.com/llvm/llvm-project/issues/94694 + // workaround for https://github.com/llvm/llvm-project/issues/94694 (fixed in LLVM 20) + // tracked in: https://github.com/rust-lang/rust/issues/135982 #[cfg(target_arch = "aarch64")] #[inline] fn cast<T: SimdCast>(self) -> Self::Cast<T> @@ -302,14 +303,14 @@ macro_rules! impl_trait { #[inline] fn to_bits(self) -> Simd<$bits_ty, N> { - assert_eq!(core::mem::size_of::<Self>(), core::mem::size_of::<Self::Bits>()); + assert_eq!(size_of::<Self>(), size_of::<Self::Bits>()); // Safety: transmuting between vector types is safe unsafe { core::mem::transmute_copy(&self) } } #[inline] fn from_bits(bits: Simd<$bits_ty, N>) -> Self { - assert_eq!(core::mem::size_of::<Self>(), core::mem::size_of::<Self::Bits>()); + assert_eq!(size_of::<Self>(), size_of::<Self::Bits>()); // Safety: transmuting between vector types is safe unsafe { core::mem::transmute_copy(&bits) } } diff --git a/library/portable-simd/crates/core_simd/src/simd/num/int.rs b/library/portable-simd/crates/core_simd/src/simd/num/int.rs index 3a51235ff95..d25050c3e4b 100644 --- a/library/portable-simd/crates/core_simd/src/simd/num/int.rs +++ b/library/portable-simd/crates/core_simd/src/simd/num/int.rs @@ -1,7 +1,7 @@ use super::sealed::Sealed; use crate::simd::{ - cmp::SimdOrd, cmp::SimdPartialOrd, num::SimdUint, LaneCount, Mask, Simd, SimdCast, SimdElement, - SupportedLaneCount, + LaneCount, Mask, Simd, SimdCast, SimdElement, SupportedLaneCount, cmp::SimdOrd, + cmp::SimdPartialOrd, num::SimdUint, }; /// Operations on SIMD vectors of signed integers. diff --git a/library/portable-simd/crates/core_simd/src/simd/num/uint.rs b/library/portable-simd/crates/core_simd/src/simd/num/uint.rs index 1ab2d8c7b73..45d978068b6 100644 --- a/library/portable-simd/crates/core_simd/src/simd/num/uint.rs +++ b/library/portable-simd/crates/core_simd/src/simd/num/uint.rs @@ -1,5 +1,5 @@ use super::sealed::Sealed; -use crate::simd::{cmp::SimdOrd, LaneCount, Simd, SimdCast, SimdElement, SupportedLaneCount}; +use crate::simd::{LaneCount, Simd, SimdCast, SimdElement, SupportedLaneCount, cmp::SimdOrd}; /// Operations on SIMD vectors of unsigned integers. pub trait SimdUint: Copy + Sealed { diff --git a/library/portable-simd/crates/core_simd/src/simd/prelude.rs b/library/portable-simd/crates/core_simd/src/simd/prelude.rs index 4b7c744c013..e5d7a2aeb73 100644 --- a/library/portable-simd/crates/core_simd/src/simd/prelude.rs +++ b/library/portable-simd/crates/core_simd/src/simd/prelude.rs @@ -7,10 +7,11 @@ #[doc(no_inline)] pub use super::{ + Mask, Simd, cmp::{SimdOrd, SimdPartialEq, SimdPartialOrd}, num::{SimdFloat, SimdInt, SimdUint}, ptr::{SimdConstPtr, SimdMutPtr}, - simd_swizzle, Mask, Simd, + simd_swizzle, }; #[rustfmt::skip] diff --git a/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs b/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs index 47383809ffb..36452e7ae92 100644 --- a/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs +++ b/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs @@ -1,5 +1,5 @@ use super::sealed::Sealed; -use crate::simd::{cmp::SimdPartialEq, num::SimdUint, LaneCount, Mask, Simd, SupportedLaneCount}; +use crate::simd::{LaneCount, Mask, Simd, SupportedLaneCount, cmp::SimdPartialEq, num::SimdUint}; /// Operations on SIMD vectors of constant pointers. pub trait SimdConstPtr: Copy + Sealed { diff --git a/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs b/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs index 3f20eef21a3..c644f390c20 100644 --- a/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs +++ b/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs @@ -1,5 +1,5 @@ use super::sealed::Sealed; -use crate::simd::{cmp::SimdPartialEq, num::SimdUint, LaneCount, Mask, Simd, SupportedLaneCount}; +use crate::simd::{LaneCount, Mask, Simd, SupportedLaneCount, cmp::SimdPartialEq, num::SimdUint}; /// Operations on SIMD vectors of mutable pointers. pub trait SimdMutPtr: Copy + Sealed { diff --git a/library/portable-simd/crates/core_simd/src/swizzle.rs b/library/portable-simd/crates/core_simd/src/swizzle.rs index 42425ef37e5..dbdd6ef40eb 100644 --- a/library/portable-simd/crates/core_simd/src/swizzle.rs +++ b/library/portable-simd/crates/core_simd/src/swizzle.rs @@ -214,6 +214,17 @@ where /// Rotates the vector such that the first `OFFSET` elements of the slice move to the end /// while the last `self.len() - OFFSET` elements move to the front. After calling `rotate_elements_left`, /// the element previously at index `OFFSET` will become the first element in the slice. + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd::Simd; + /// let a = Simd::from_array([0, 1, 2, 3]); + /// let x = a.rotate_elements_left::<3>(); + /// assert_eq!(x.to_array(), [3, 0, 1, 2]); + /// + /// let y = a.rotate_elements_left::<7>(); + /// assert_eq!(y.to_array(), [3, 0, 1, 2]); + /// ``` #[inline] #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn rotate_elements_left<const OFFSET: usize>(self) -> Self { @@ -238,6 +249,17 @@ where /// Rotates the vector such that the first `self.len() - OFFSET` elements of the vector move to /// the end while the last `OFFSET` elements move to the front. After calling `rotate_elements_right`, /// the element previously at index `self.len() - OFFSET` will become the first element in the slice. + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd::Simd; + /// let a = Simd::from_array([0, 1, 2, 3]); + /// let x = a.rotate_elements_right::<3>(); + /// assert_eq!(x.to_array(), [1, 2, 3, 0]); + /// + /// let y = a.rotate_elements_right::<7>(); + /// assert_eq!(y.to_array(), [1, 2, 3, 0]); + /// ``` #[inline] #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn rotate_elements_right<const OFFSET: usize>(self) -> Self { @@ -261,6 +283,17 @@ where /// Shifts the vector elements to the left by `OFFSET`, filling in with /// `padding` from the right. + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd::Simd; + /// let a = Simd::from_array([0, 1, 2, 3]); + /// let x = a.shift_elements_left::<3>(255); + /// assert_eq!(x.to_array(), [3, 255, 255, 255]); + /// + /// let y = a.shift_elements_left::<7>(255); + /// assert_eq!(y.to_array(), [255, 255, 255, 255]); + /// ``` #[inline] #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn shift_elements_left<const OFFSET: usize>(self, padding: T) -> Self { @@ -283,6 +316,17 @@ where /// Shifts the vector elements to the right by `OFFSET`, filling in with /// `padding` from the left. + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd::Simd; + /// let a = Simd::from_array([0, 1, 2, 3]); + /// let x = a.shift_elements_right::<3>(255); + /// assert_eq!(x.to_array(), [255, 255, 255, 0]); + /// + /// let y = a.shift_elements_right::<7>(255); + /// assert_eq!(y.to_array(), [255, 255, 255, 255]); + /// ``` #[inline] #[must_use = "method returns a new vector and does not mutate the original inputs"] pub fn shift_elements_right<const OFFSET: usize>(self, padding: T) -> Self { diff --git a/library/portable-simd/crates/core_simd/src/to_bytes.rs b/library/portable-simd/crates/core_simd/src/to_bytes.rs index 4833ea9e113..fee2cc06c5b 100644 --- a/library/portable-simd/crates/core_simd/src/to_bytes.rs +++ b/library/portable-simd/crates/core_simd/src/to_bytes.rs @@ -1,6 +1,6 @@ use crate::simd::{ - num::{SimdFloat, SimdInt, SimdUint}, LaneCount, Simd, SimdElement, SupportedLaneCount, + num::{SimdFloat, SimdInt, SimdUint}, }; mod sealed { diff --git a/library/portable-simd/crates/core_simd/src/vector.rs b/library/portable-simd/crates/core_simd/src/vector.rs index 9c4dd36c24f..d76a6cd52bf 100644 --- a/library/portable-simd/crates/core_simd/src/vector.rs +++ b/library/portable-simd/crates/core_simd/src/vector.rs @@ -1,8 +1,8 @@ use crate::simd::{ + LaneCount, Mask, MaskElement, SupportedLaneCount, Swizzle, cmp::SimdPartialOrd, num::SimdUint, ptr::{SimdConstPtr, SimdMutPtr}, - LaneCount, Mask, MaskElement, SupportedLaneCount, Swizzle, }; /// A SIMD vector with the shape of `[T; N]` but the operations of `T`. @@ -83,7 +83,7 @@ use crate::simd::{ /// converting `[T]` to `[Simd<T, N>]`, and allows soundly operating on an aligned SIMD body, /// but it may cost more time when handling the scalar head and tail. /// If these are not enough, it is most ideal to design data structures to be already aligned -/// to `mem::align_of::<Simd<T, N>>()` before using `unsafe` Rust to read or write. +/// to `align_of::<Simd<T, N>>()` before using `unsafe` Rust to read or write. /// Other ways to compensate for these facts, like materializing `Simd` to or from an array first, /// are handled by safe methods like [`Simd::from_array`] and [`Simd::from_slice`]. /// diff --git a/library/portable-simd/crates/core_simd/tests/layout.rs b/library/portable-simd/crates/core_simd/tests/layout.rs index 24114c2d261..3b4666249b0 100644 --- a/library/portable-simd/crates/core_simd/tests/layout.rs +++ b/library/portable-simd/crates/core_simd/tests/layout.rs @@ -7,8 +7,8 @@ macro_rules! layout_tests { test_helpers::test_lanes! { fn no_padding<const LANES: usize>() { assert_eq!( - core::mem::size_of::<core_simd::simd::Simd::<$ty, LANES>>(), - core::mem::size_of::<[$ty; LANES]>(), + size_of::<core_simd::simd::Simd::<$ty, LANES>>(), + size_of::<[$ty; LANES]>(), ); } } diff --git a/library/portable-simd/crates/core_simd/tests/pointers.rs b/library/portable-simd/crates/core_simd/tests/pointers.rs index d7db4e82b3c..6e74c2d18b1 100644 --- a/library/portable-simd/crates/core_simd/tests/pointers.rs +++ b/library/portable-simd/crates/core_simd/tests/pointers.rs @@ -1,8 +1,8 @@ #![feature(portable_simd)] use core_simd::simd::{ - ptr::{SimdConstPtr, SimdMutPtr}, Simd, + ptr::{SimdConstPtr, SimdMutPtr}, }; macro_rules! common_tests { diff --git a/library/portable-simd/crates/core_simd/tests/round.rs b/library/portable-simd/crates/core_simd/tests/round.rs index 847766ec41e..4c1ac3c36f8 100644 --- a/library/portable-simd/crates/core_simd/tests/round.rs +++ b/library/portable-simd/crates/core_simd/tests/round.rs @@ -58,7 +58,7 @@ macro_rules! float_rounding_test { // all of the mantissa digits set to 1, pushed up to the MSB. const ALL_MANTISSA_BITS: IntScalar = ((1 << <Scalar>::MANTISSA_DIGITS) - 1); const MAX_REPRESENTABLE_VALUE: Scalar = - (ALL_MANTISSA_BITS << (core::mem::size_of::<Scalar>() * 8 - <Scalar>::MANTISSA_DIGITS as usize - 1)) as Scalar; + (ALL_MANTISSA_BITS << (size_of::<Scalar>() * 8 - <Scalar>::MANTISSA_DIGITS as usize - 1)) as Scalar; let mut runner = test_helpers::make_runner(); runner.run( diff --git a/library/portable-simd/crates/test_helpers/src/subnormals.rs b/library/portable-simd/crates/test_helpers/src/subnormals.rs index ec0f1fb24b9..b5f19ba47b8 100644 --- a/library/portable-simd/crates/test_helpers/src/subnormals.rs +++ b/library/portable-simd/crates/test_helpers/src/subnormals.rs @@ -12,7 +12,7 @@ macro_rules! impl_float { $( impl FlushSubnormals for $ty { fn flush(self) -> Self { - let is_f32 = core::mem::size_of::<Self>() == 4; + let is_f32 = size_of::<Self>() == 4; let ppc_flush = is_f32 && cfg!(all( any(target_arch = "powerpc", all(target_arch = "powerpc64", target_endian = "big")), target_feature = "altivec", diff --git a/library/std/build.rs b/library/std/build.rs index a0cfbc4685e..d76d07a89f4 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -62,6 +62,7 @@ fn main() { || target_os == "zkvm" || target_os == "rtems" || target_os == "nuttx" + || target_os == "cygwin" // See src/bootstrap/src/core/build_steps/synthetic_targets.rs || env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok() diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 99d105a2454..5d2a304b41c 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -348,6 +348,7 @@ fn default_alloc_error_hook(layout: Layout) { unsafe extern "Rust" { // This symbol is emitted by rustc next to __rust_alloc_error_handler. // Its value depends on the -Zoom={panic,abort} compiler option. + #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)] static __rust_alloc_error_handler_should_panic: u8; } diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 6961fa8ea94..05bd4345ea8 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -333,7 +333,7 @@ impl Error for VarError { /// /// Discussion of this unsafety on Unix may be found in: /// -/// - [Austin Group Bugzilla](https://austingroupbugs.net/view.php?id=188) +/// - [Austin Group Bugzilla (for POSIX)](https://austingroupbugs.net/view.php?id=188) /// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=15607#c2) /// /// To pass an environment variable to a child process, you can instead use [`Command::env`]. diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs index 697fb5974a3..40441dc057d 100644 --- a/library/std/src/io/buffered/bufreader.rs +++ b/library/std/src/io/buffered/bufreader.rs @@ -109,9 +109,13 @@ impl<R: Read + ?Sized> BufReader<R> { /// /// `n` must be less than or equal to `capacity`. /// - /// the returned slice may be less than `n` bytes long if + /// The returned slice may be less than `n` bytes long if /// end of file is reached. /// + /// After calling this method, you may call [`consume`](BufRead::consume) + /// with a value less than or equal to `n` to advance over some or all of + /// the returned bytes. + /// /// ## Examples /// /// ```rust diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 7f610bc88bf..a4f007cab74 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -310,7 +310,7 @@ pub use self::error::RawOsError; pub use self::error::SimpleMessage; #[unstable(feature = "io_const_error", issue = "133448")] pub use self::error::const_error; -#[unstable(feature = "anonymous_pipe", issue = "127154")] +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] pub use self::pipe::{PipeReader, PipeWriter, pipe}; #[stable(feature = "is_terminal", since = "1.70.0")] pub use self::stdio::IsTerminal; @@ -2251,24 +2251,18 @@ fn skip_until<R: BufRead + ?Sized>(r: &mut R, delim: u8) -> Result<usize> { #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "IoBufRead")] pub trait BufRead: Read { - /// Returns the contents of the internal buffer, filling it with more data - /// from the inner reader if it is empty. + /// Returns the contents of the internal buffer, filling it with more data, via `Read` methods, if empty. /// - /// This function is a lower-level call. It needs to be paired with the - /// [`consume`] method to function properly. When calling this - /// method, none of the contents will be "read" in the sense that later - /// calling `read` may return the same contents. As such, [`consume`] must - /// be called with the number of bytes that are consumed from this buffer to - /// ensure that the bytes are never returned twice. + /// This is a lower-level method and is meant to be used together with [`consume`], + /// which can be used to mark bytes that should not be returned by subsequent calls to `read`. /// /// [`consume`]: BufRead::consume /// - /// An empty buffer returned indicates that the stream has reached EOF. + /// Returns an empty buffer when the stream has reached EOF. /// /// # Errors /// - /// This function will return an I/O error if the underlying reader was - /// read, but returned an error. + /// This function will return an I/O error if a `Read` method was called, but returned an error. /// /// # Examples /// @@ -2286,7 +2280,7 @@ pub trait BufRead: Read { /// // work with buffer /// println!("{buffer:?}"); /// - /// // ensure the bytes we worked with aren't returned again later + /// // mark the bytes we worked with as read /// let length = buffer.len(); /// stdin.consume(length); /// # std::io::Result::Ok(()) @@ -2294,18 +2288,13 @@ pub trait BufRead: Read { #[stable(feature = "rust1", since = "1.0.0")] fn fill_buf(&mut self) -> Result<&[u8]>; - /// Tells this buffer that `amt` bytes have been consumed from the buffer, - /// so they should no longer be returned in calls to `read`. + /// Marks the given `amount` of additional bytes from the internal buffer as having been read. + /// Subsequent calls to `read` only return bytes that have not been marked as read. /// - /// This function is a lower-level call. It needs to be paired with the - /// [`fill_buf`] method to function properly. This function does - /// not perform any I/O, it simply informs this object that some amount of - /// its buffer, returned from [`fill_buf`], has been consumed and should - /// no longer be returned. As such, this function may do odd things if - /// [`fill_buf`] isn't called before calling it. + /// This is a lower-level method and is meant to be used together with [`fill_buf`], + /// which can be used to fill the internal buffer via `Read` methods. /// - /// The `amt` must be `<=` the number of bytes in the buffer returned by - /// [`fill_buf`]. + /// It is a logic error if `amount` exceeds the number of unread bytes in the internal buffer, which is returned by [`fill_buf`]. /// /// # Examples /// @@ -2314,9 +2303,9 @@ pub trait BufRead: Read { /// /// [`fill_buf`]: BufRead::fill_buf #[stable(feature = "rust1", since = "1.0.0")] - fn consume(&mut self, amt: usize); + fn consume(&mut self, amount: usize); - /// Checks if the underlying `Read` has any data left to be read. + /// Checks if there is any data left to be `read`. /// /// This function may fill the buffer to check for data, /// so this functions returns `Result<bool>`, not `bool`. @@ -2325,6 +2314,10 @@ pub trait BufRead: Read { /// returned slice is empty (which means that there is no data left, /// since EOF is reached). /// + /// # Errors + /// + /// This function will return an I/O error if a `Read` method was called, but returned an error. + /// /// Examples /// /// ``` diff --git a/library/std/src/io/pipe.rs b/library/std/src/io/pipe.rs index 266c7bc9638..cfed9b05cc0 100644 --- a/library/std/src/io/pipe.rs +++ b/library/std/src/io/pipe.rs @@ -1,5 +1,6 @@ use crate::io; use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner}; +use crate::sys_common::{FromInner, IntoInner}; /// Create an anonymous pipe. /// @@ -40,7 +41,6 @@ use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner}; /// # Examples /// /// ```no_run -/// #![feature(anonymous_pipe)] /// # #[cfg(miri)] fn main() {} /// # #[cfg(not(miri))] /// # fn main() -> std::io::Result<()> { @@ -67,29 +67,52 @@ use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner}; /// ``` /// [changes]: io#platform-specific-behavior /// [man page]: https://man7.org/linux/man-pages/man7/pipe.7.html -#[unstable(feature = "anonymous_pipe", issue = "127154")] +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] #[inline] pub fn pipe() -> io::Result<(PipeReader, PipeWriter)> { pipe_inner().map(|(reader, writer)| (PipeReader(reader), PipeWriter(writer))) } /// Read end of an anonymous pipe. -#[unstable(feature = "anonymous_pipe", issue = "127154")] +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] #[derive(Debug)] pub struct PipeReader(pub(crate) AnonPipe); /// Write end of an anonymous pipe. -#[unstable(feature = "anonymous_pipe", issue = "127154")] +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] #[derive(Debug)] pub struct PipeWriter(pub(crate) AnonPipe); +impl FromInner<AnonPipe> for PipeReader { + fn from_inner(inner: AnonPipe) -> Self { + Self(inner) + } +} + +impl IntoInner<AnonPipe> for PipeReader { + fn into_inner(self) -> AnonPipe { + self.0 + } +} + +impl FromInner<AnonPipe> for PipeWriter { + fn from_inner(inner: AnonPipe) -> Self { + Self(inner) + } +} + +impl IntoInner<AnonPipe> for PipeWriter { + fn into_inner(self) -> AnonPipe { + self.0 + } +} + impl PipeReader { /// Create a new [`PipeReader`] instance that shares the same underlying file description. /// /// # Examples /// /// ```no_run - /// #![feature(anonymous_pipe)] /// # #[cfg(miri)] fn main() {} /// # #[cfg(not(miri))] /// # fn main() -> std::io::Result<()> { @@ -137,7 +160,7 @@ impl PipeReader { /// # Ok(()) /// # } /// ``` - #[unstable(feature = "anonymous_pipe", issue = "127154")] + #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] pub fn try_clone(&self) -> io::Result<Self> { self.0.try_clone().map(Self) } @@ -149,7 +172,6 @@ impl PipeWriter { /// # Examples /// /// ```no_run - /// #![feature(anonymous_pipe)] /// # #[cfg(miri)] fn main() {} /// # #[cfg(not(miri))] /// # fn main() -> std::io::Result<()> { @@ -177,13 +199,13 @@ impl PipeWriter { /// # Ok(()) /// # } /// ``` - #[unstable(feature = "anonymous_pipe", issue = "127154")] + #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] pub fn try_clone(&self) -> io::Result<Self> { self.0.try_clone().map(Self) } } -#[unstable(feature = "anonymous_pipe", issue = "127154")] +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] impl io::Read for &PipeReader { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) @@ -203,7 +225,7 @@ impl io::Read for &PipeReader { } } -#[unstable(feature = "anonymous_pipe", issue = "127154")] +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] impl io::Read for PipeReader { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) @@ -223,7 +245,7 @@ impl io::Read for PipeReader { } } -#[unstable(feature = "anonymous_pipe", issue = "127154")] +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] impl io::Write for &PipeWriter { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) @@ -241,7 +263,7 @@ impl io::Write for &PipeWriter { } } -#[unstable(feature = "anonymous_pipe", issue = "127154")] +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] impl io::Write for PipeWriter { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs index cb3f864fd4e..0410df3ef1a 100644 --- a/library/std/src/io/util.rs +++ b/library/std/src/io/util.rs @@ -7,7 +7,6 @@ use crate::fmt; use crate::io::{ self, BorrowedCursor, BufRead, IoSlice, IoSliceMut, Read, Seek, SeekFrom, SizeHint, Write, }; -use crate::mem::MaybeUninit; /// `Empty` ignores any data written via [`Write`], and will always be empty /// (returning zero bytes) when read via [`Read`]. @@ -68,6 +67,38 @@ impl Read for Empty { fn read_buf(&mut self, _cursor: BorrowedCursor<'_>) -> io::Result<()> { Ok(()) } + + #[inline] + fn read_vectored(&mut self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { + Ok(0) + } + + #[inline] + fn is_read_vectored(&self) -> bool { + // Do not force `Chain<Empty, T>` or `Chain<T, Empty>` to use vectored + // reads, unless the other reader is vectored. + false + } + + #[inline] + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + if !buf.is_empty() { Err(io::Error::READ_EXACT_EOF) } else { Ok(()) } + } + + #[inline] + fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> { + if cursor.capacity() != 0 { Err(io::Error::READ_EXACT_EOF) } else { Ok(()) } + } + + #[inline] + fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> io::Result<usize> { + Ok(0) + } + + #[inline] + fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> { + Ok(0) + } } #[stable(feature = "rust1", since = "1.0.0")] impl BufRead for Empty { @@ -75,20 +106,44 @@ impl BufRead for Empty { fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) } + #[inline] fn consume(&mut self, _n: usize) {} + + #[inline] + fn has_data_left(&mut self) -> io::Result<bool> { + Ok(false) + } + + #[inline] + fn read_until(&mut self, _byte: u8, _buf: &mut Vec<u8>) -> io::Result<usize> { + Ok(0) + } + + #[inline] + fn skip_until(&mut self, _byte: u8) -> io::Result<usize> { + Ok(0) + } + + #[inline] + fn read_line(&mut self, _buf: &mut String) -> io::Result<usize> { + Ok(0) + } } #[stable(feature = "empty_seek", since = "1.51.0")] impl Seek for Empty { + #[inline] fn seek(&mut self, _pos: SeekFrom) -> io::Result<u64> { Ok(0) } + #[inline] fn stream_len(&mut self) -> io::Result<u64> { Ok(0) } + #[inline] fn stream_position(&mut self) -> io::Result<u64> { Ok(0) } @@ -120,6 +175,21 @@ impl Write for Empty { } #[inline] + fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> { + Ok(()) + } + + #[inline] + fn write_all_vectored(&mut self, _bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + Ok(()) + } + + #[inline] + fn write_fmt(&mut self, _args: fmt::Arguments<'_>) -> io::Result<()> { + Ok(()) + } + + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) } @@ -144,6 +214,21 @@ impl Write for &Empty { } #[inline] + fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> { + Ok(()) + } + + #[inline] + fn write_all_vectored(&mut self, _bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + Ok(()) + } + + #[inline] + fn write_fmt(&mut self, _args: fmt::Arguments<'_>) -> io::Result<()> { + Ok(()) + } + + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) } @@ -196,7 +281,7 @@ impl Read for Repeat { #[inline] fn read_buf(&mut self, mut buf: BorrowedCursor<'_>) -> io::Result<()> { // SAFETY: No uninit bytes are being written. - MaybeUninit::fill(unsafe { buf.as_mut() }, self.byte); + unsafe { buf.as_mut() }.write_filled(self.byte); // SAFETY: the entire unfilled portion of buf has been initialized. unsafe { buf.advance_unchecked(buf.capacity()) }; Ok(()) @@ -303,6 +388,21 @@ impl Write for Sink { } #[inline] + fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> { + Ok(()) + } + + #[inline] + fn write_all_vectored(&mut self, _bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + Ok(()) + } + + #[inline] + fn write_fmt(&mut self, _args: fmt::Arguments<'_>) -> io::Result<()> { + Ok(()) + } + + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) } @@ -327,6 +427,21 @@ impl Write for &Sink { } #[inline] + fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> { + Ok(()) + } + + #[inline] + fn write_all_vectored(&mut self, _bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + Ok(()) + } + + #[inline] + fn write_fmt(&mut self, _args: fmt::Arguments<'_>) -> io::Result<()> { + Ok(()) + } + + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) } diff --git a/library/std/src/io/util/tests.rs b/library/std/src/io/util/tests.rs index 0599a881af1..d0f106d7af4 100644 --- a/library/std/src/io/util/tests.rs +++ b/library/std/src/io/util/tests.rs @@ -1,14 +1,51 @@ +use crate::fmt; use crate::io::prelude::*; -use crate::io::{BorrowedBuf, Empty, Repeat, SeekFrom, Sink, empty, repeat, sink}; +use crate::io::{ + BorrowedBuf, Empty, ErrorKind, IoSlice, IoSliceMut, Repeat, SeekFrom, Sink, empty, repeat, sink, +}; use crate::mem::MaybeUninit; +struct ErrorDisplay; + +impl fmt::Display for ErrorDisplay { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + Err(fmt::Error) + } +} + +struct PanicDisplay; + +impl fmt::Display for PanicDisplay { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + panic!() + } +} + +#[track_caller] +fn test_sinking<W: Write>(mut w: W) { + assert_eq!(w.write(&[]).unwrap(), 0); + assert_eq!(w.write(&[0]).unwrap(), 1); + assert_eq!(w.write(&[0; 1024]).unwrap(), 1024); + w.write_all(&[]).unwrap(); + w.write_all(&[0]).unwrap(); + w.write_all(&[0; 1024]).unwrap(); + let mut bufs = + [IoSlice::new(&[]), IoSlice::new(&[0]), IoSlice::new(&[0; 1024]), IoSlice::new(&[])]; + assert!(w.is_write_vectored()); + assert_eq!(w.write_vectored(&[]).unwrap(), 0); + assert_eq!(w.write_vectored(&bufs).unwrap(), 1025); + w.write_all_vectored(&mut []).unwrap(); + w.write_all_vectored(&mut bufs).unwrap(); + assert!(w.flush().is_ok()); + assert_eq!(w.by_ref().write(&[0; 1024]).unwrap(), 1024); + // Ignores fmt arguments + w.write_fmt(format_args!("{}", ErrorDisplay)).unwrap(); + w.write_fmt(format_args!("{}", PanicDisplay)).unwrap(); +} + #[test] fn sink_sinks() { - let mut s = sink(); - assert_eq!(s.write(&[]).unwrap(), 0); - assert_eq!(s.write(&[0]).unwrap(), 1); - assert_eq!(s.write(&[0; 1024]).unwrap(), 1024); - assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024); + test_sinking(sink()); } #[test] @@ -19,6 +56,21 @@ fn empty_reads() { assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0); assert_eq!(Read::by_ref(&mut e).read(&mut [0; 1024]).unwrap(), 0); + e.read_exact(&mut []).unwrap(); + assert_eq!(e.read_exact(&mut [0]).unwrap_err().kind(), ErrorKind::UnexpectedEof); + assert_eq!(e.read_exact(&mut [0; 1024]).unwrap_err().kind(), ErrorKind::UnexpectedEof); + + assert!(!e.is_read_vectored()); + assert_eq!(e.read_vectored(&mut []).unwrap(), 0); + let (mut buf1, mut buf1024) = ([0], [0; 1024]); + let bufs = &mut [ + IoSliceMut::new(&mut []), + IoSliceMut::new(&mut buf1), + IoSliceMut::new(&mut buf1024), + IoSliceMut::new(&mut []), + ]; + assert_eq!(e.read_vectored(bufs).unwrap(), 0); + let buf: &mut [MaybeUninit<_>] = &mut []; let mut buf: BorrowedBuf<'_> = buf.into(); e.read_buf(buf.unfilled()).unwrap(); @@ -42,6 +94,47 @@ fn empty_reads() { Read::by_ref(&mut e).read_buf(buf.unfilled()).unwrap(); assert_eq!(buf.len(), 0); assert_eq!(buf.init_len(), 0); + + let buf: &mut [MaybeUninit<_>] = &mut []; + let mut buf: BorrowedBuf<'_> = buf.into(); + e.read_buf_exact(buf.unfilled()).unwrap(); + assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); + + let buf: &mut [_] = &mut [MaybeUninit::uninit()]; + let mut buf: BorrowedBuf<'_> = buf.into(); + assert_eq!(e.read_buf_exact(buf.unfilled()).unwrap_err().kind(), ErrorKind::UnexpectedEof); + assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); + + let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1024]; + let mut buf: BorrowedBuf<'_> = buf.into(); + assert_eq!(e.read_buf_exact(buf.unfilled()).unwrap_err().kind(), ErrorKind::UnexpectedEof); + assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); + + let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1024]; + let mut buf: BorrowedBuf<'_> = buf.into(); + assert_eq!( + Read::by_ref(&mut e).read_buf_exact(buf.unfilled()).unwrap_err().kind(), + ErrorKind::UnexpectedEof, + ); + assert_eq!(buf.len(), 0); + assert_eq!(buf.init_len(), 0); + + let mut buf = Vec::new(); + assert_eq!(e.read_to_end(&mut buf).unwrap(), 0); + assert_eq!(buf, vec![]); + let mut buf = vec![1, 2, 3]; + assert_eq!(e.read_to_end(&mut buf).unwrap(), 0); + assert_eq!(buf, vec![1, 2, 3]); + + let mut buf = String::new(); + assert_eq!(e.read_to_string(&mut buf).unwrap(), 0); + assert_eq!(buf, ""); + let mut buf = "hello".to_owned(); + assert_eq!(e.read_to_string(&mut buf).unwrap(), 0); + assert_eq!(buf, "hello"); } #[test] @@ -66,11 +159,7 @@ fn empty_seeks() { #[test] fn empty_sinks() { - let mut e = empty(); - assert_eq!(e.write(&[]).unwrap(), 0); - assert_eq!(e.write(&[0]).unwrap(), 1); - assert_eq!(e.write(&[0; 1024]).unwrap(), 1024); - assert_eq!(Write::by_ref(&mut e).write(&[0; 1024]).unwrap(), 1024); + test_sinking(empty()); } #[test] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 938b8c6e4f4..ad005833ad5 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -174,7 +174,9 @@ //! //! - after-main use of thread-locals, which also affects additional features: //! - [`thread::current()`] -//! - before-main stdio file descriptors are not guaranteed to be open on unix platforms +//! - under UNIX, before main, file descriptors 0, 1, and 2 may be unchanged +//! (they are guaranteed to be open during main, +//! and are opened to /dev/null O_RDWR if they weren't open on program start) //! //! //! [I/O]: io @@ -666,6 +668,8 @@ pub mod arch { pub use std_detect::is_loongarch_feature_detected; #[unstable(feature = "is_riscv_feature_detected", issue = "111192")] pub use std_detect::is_riscv_feature_detected; + #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] + pub use std_detect::is_s390x_feature_detected; #[stable(feature = "simd_x86", since = "1.27.0")] pub use std_detect::is_x86_feature_detected; #[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")] diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs index e0f9f0bb5ce..f008d42804c 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs @@ -41,7 +41,7 @@ macro_rules! panic { /// Use `print!` only for the primary output of your program. Use /// [`eprint!`] instead to print error and progress messages. /// -/// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) +/// See the formatting documentation in [`std::fmt`](crate::fmt) /// for details of the macro argument syntax. /// /// [flush]: crate::io::Write::flush @@ -106,7 +106,7 @@ macro_rules! print { /// Use `println!` only for the primary output of your program. Use /// [`eprintln!`] instead to print error and progress messages. /// -/// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) +/// See the formatting documentation in [`std::fmt`](crate::fmt) /// for details of the macro argument syntax. /// /// [`std::fmt`]: crate::fmt @@ -156,7 +156,7 @@ macro_rules! println { /// [`io::stderr`]: crate::io::stderr /// [`io::stdout`]: crate::io::stdout /// -/// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) +/// See the formatting documentation in [`std::fmt`](crate::fmt) /// for details of the macro argument syntax. /// /// # Panics @@ -190,7 +190,7 @@ macro_rules! eprint { /// Use `eprintln!` only for error and progress messages. Use `println!` /// instead for the primary output of your program. /// -/// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) +/// See the formatting documentation in [`std::fmt`](crate::fmt) /// for details of the macro argument syntax. /// /// [`io::stderr`]: crate::io::stderr diff --git a/library/std/src/os/cygwin/fs.rs b/library/std/src/os/cygwin/fs.rs new file mode 100644 index 00000000000..5533264fd51 --- /dev/null +++ b/library/std/src/os/cygwin/fs.rs @@ -0,0 +1,102 @@ +#![stable(feature = "metadata_ext", since = "1.1.0")] +use crate::fs::Metadata; +use crate::sys_common::AsInner; +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: crate::fs::Metadata +#[stable(feature = "metadata_ext", since = "1.1.0")] +pub trait MetadataExt { + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_dev(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ino(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mode(&self) -> u32; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_nlink(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_uid(&self) -> u32; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_gid(&self) -> u32; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_rdev(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_size(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_atime(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_atime_nsec(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mtime(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mtime_nsec(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ctime(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ctime_nsec(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_blksize(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_blocks(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_birthtime(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_birthtime_nsec(&self) -> i64; +} +#[stable(feature = "metadata_ext", since = "1.1.0")] +impl MetadataExt for Metadata { + fn st_dev(&self) -> u64 { + self.as_inner().as_inner().st_dev as u64 + } + fn st_ino(&self) -> u64 { + self.as_inner().as_inner().st_ino as u64 + } + fn st_mode(&self) -> u32 { + self.as_inner().as_inner().st_mode as u32 + } + fn st_nlink(&self) -> u64 { + self.as_inner().as_inner().st_nlink as u64 + } + fn st_uid(&self) -> u32 { + self.as_inner().as_inner().st_uid as u32 + } + fn st_gid(&self) -> u32 { + self.as_inner().as_inner().st_gid as u32 + } + fn st_rdev(&self) -> u64 { + self.as_inner().as_inner().st_rdev as u64 + } + fn st_size(&self) -> u64 { + self.as_inner().as_inner().st_size as u64 + } + fn st_atime(&self) -> i64 { + self.as_inner().as_inner().st_atime as i64 + } + fn st_atime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_atime_nsec as i64 + } + fn st_mtime(&self) -> i64 { + self.as_inner().as_inner().st_mtime as i64 + } + fn st_mtime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_mtime_nsec as i64 + } + fn st_ctime(&self) -> i64 { + self.as_inner().as_inner().st_ctime as i64 + } + fn st_ctime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_ctime_nsec as i64 + } + fn st_blksize(&self) -> u64 { + self.as_inner().as_inner().st_blksize as u64 + } + fn st_blocks(&self) -> u64 { + self.as_inner().as_inner().st_blocks as u64 + } + fn st_birthtime(&self) -> i64 { + self.as_inner().as_inner().st_birthtime as i64 + } + fn st_birthtime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_birthtime_nsec as i64 + } +} diff --git a/library/std/src/os/cygwin/mod.rs b/library/std/src/os/cygwin/mod.rs new file mode 100644 index 00000000000..7f6d6a645c8 --- /dev/null +++ b/library/std/src/os/cygwin/mod.rs @@ -0,0 +1,4 @@ +//! Cygwin-specific definitions +#![stable(feature = "raw_ext", since = "1.1.0")] +pub mod fs; +pub(crate) mod raw; diff --git a/library/std/src/os/cygwin/raw.rs b/library/std/src/os/cygwin/raw.rs new file mode 100644 index 00000000000..2bae1477fcf --- /dev/null +++ b/library/std/src/os/cygwin/raw.rs @@ -0,0 +1,4 @@ +//! Cygwin-specific raw type definitions. + +#[stable(feature = "raw_ext", since = "1.1.0")] +pub use libc::{blkcnt_t, blksize_t, dev_t, ino_t, mode_t, nlink_t, off_t, pthread_t, time_t}; diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 701cf823357..2dcbfc96618 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -15,8 +15,9 @@ use crate::mem::ManuallyDrop; target_os = "trusty" )))] use crate::sys::cvt; +use crate::sys_common::FromInner; #[cfg(not(target_os = "trusty"))] -use crate::sys_common::{AsInner, FromInner, IntoInner}; +use crate::sys_common::{AsInner, IntoInner}; use crate::{fmt, io}; type ValidRawFd = core::num::niche_types::NotAllOnes<RawFd>; @@ -504,3 +505,45 @@ impl<'a> AsFd for io::StderrLock<'a> { unsafe { BorrowedFd::borrow_raw(2) } } } + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl AsFd for io::PipeReader { + fn as_fd(&self) -> BorrowedFd<'_> { + self.0.as_fd() + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl From<io::PipeReader> for OwnedFd { + fn from(pipe: io::PipeReader) -> Self { + pipe.0.into_inner() + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl AsFd for io::PipeWriter { + fn as_fd(&self) -> BorrowedFd<'_> { + self.0.as_fd() + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl From<io::PipeWriter> for OwnedFd { + fn from(pipe: io::PipeWriter) -> Self { + pipe.0.into_inner() + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl From<OwnedFd> for io::PipeReader { + fn from(owned_fd: OwnedFd) -> Self { + Self(FromInner::from_inner(owned_fd)) + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl From<OwnedFd> for io::PipeWriter { + fn from(owned_fd: OwnedFd) -> Self { + Self(FromInner::from_inner(owned_fd)) + } +} diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs index 083ac6e3fe6..596b21a5204 100644 --- a/library/std/src/os/fd/raw.rs +++ b/library/std/src/os/fd/raw.rs @@ -18,6 +18,7 @@ use crate::os::unix::io::AsFd; use crate::os::unix::io::OwnedFd; #[cfg(target_os = "wasi")] use crate::os::wasi::io::OwnedFd; +use crate::sys_common::FromInner; #[cfg(not(target_os = "trusty"))] use crate::sys_common::{AsInner, IntoInner}; @@ -284,3 +285,45 @@ impl<T: AsRawFd> AsRawFd for Box<T> { (**self).as_raw_fd() } } + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl AsRawFd for io::PipeReader { + fn as_raw_fd(&self) -> RawFd { + self.0.as_raw_fd() + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl FromRawFd for io::PipeReader { + unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { + Self::from_inner(unsafe { FromRawFd::from_raw_fd(raw_fd) }) + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl IntoRawFd for io::PipeReader { + fn into_raw_fd(self) -> RawFd { + self.0.into_raw_fd() + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl AsRawFd for io::PipeWriter { + fn as_raw_fd(&self) -> RawFd { + self.0.as_raw_fd() + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl FromRawFd for io::PipeWriter { + unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { + Self::from_inner(unsafe { FromRawFd::from_raw_fd(raw_fd) }) + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl IntoRawFd for io::PipeWriter { + fn into_raw_fd(self) -> RawFd { + self.0.into_raw_fd() + } +} diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 58cbecd30e5..ab7734a7952 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -125,6 +125,8 @@ pub mod windows; pub mod aix; #[cfg(target_os = "android")] pub mod android; +#[cfg(target_os = "cygwin")] +pub mod cygwin; #[cfg(target_os = "dragonfly")] pub mod dragonfly; #[cfg(target_os = "emscripten")] diff --git a/library/std/src/os/unix/mod.rs b/library/std/src/os/unix/mod.rs index 2f9dffe8c65..5802b653965 100644 --- a/library/std/src/os/unix/mod.rs +++ b/library/std/src/os/unix/mod.rs @@ -41,6 +41,8 @@ mod platform { pub use crate::os::aix::*; #[cfg(target_os = "android")] pub use crate::os::android::*; + #[cfg(target_os = "cygwin")] + pub use crate::os::cygwin::*; #[cfg(target_vendor = "apple")] pub use crate::os::darwin::*; #[cfg(target_os = "dragonfly")] diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs index 82446ea107f..7735637c840 100644 --- a/library/std/src/os/unix/net/datagram.rs +++ b/library/std/src/os/unix/net/datagram.rs @@ -9,6 +9,7 @@ target_os = "illumos", target_os = "haiku", target_os = "nto", + target_os = "cygwin" ))] use libc::MSG_NOSIGNAL; @@ -37,6 +38,7 @@ use crate::{fmt, io}; target_os = "illumos", target_os = "haiku", target_os = "nto", + target_os = "cygwin" )))] const MSG_NOSIGNAL: core::ffi::c_int = 0x0; diff --git a/library/std/src/os/unix/net/mod.rs b/library/std/src/os/unix/net/mod.rs index 3e45e3533ed..6cd62303a53 100644 --- a/library/std/src/os/unix/net/mod.rs +++ b/library/std/src/os/unix/net/mod.rs @@ -21,6 +21,7 @@ mod tests; target_os = "openbsd", target_os = "nto", target_vendor = "apple", + target_os = "cygwin" ))] mod ucred; @@ -44,6 +45,7 @@ pub use self::stream::*; target_os = "openbsd", target_os = "nto", target_vendor = "apple", + target_os = "cygwin", ))] #[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")] pub use self::ucred::*; diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index cb210b41eae..1cab04a454d 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -10,6 +10,7 @@ use super::{SocketAncillary, recv_vectored_with_ancillary_from, send_vectored_wi target_os = "openbsd", target_os = "nto", target_vendor = "apple", + target_os = "cygwin" ))] use super::{UCred, peer_cred}; use crate::fmt; @@ -231,6 +232,7 @@ impl UnixStream { target_os = "openbsd", target_os = "nto", target_vendor = "apple", + target_os = "cygwin" ))] pub fn peer_cred(&self) -> io::Result<UCred> { peer_cred(self) diff --git a/library/std/src/os/unix/net/ucred.rs b/library/std/src/os/unix/net/ucred.rs index 2dd7d409e48..36fb9c46b4a 100644 --- a/library/std/src/os/unix/net/ucred.rs +++ b/library/std/src/os/unix/net/ucred.rs @@ -33,10 +33,10 @@ pub(super) use self::impl_apple::peer_cred; target_os = "nto" ))] pub(super) use self::impl_bsd::peer_cred; -#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))] pub(super) use self::impl_linux::peer_cred; -#[cfg(any(target_os = "linux", target_os = "android"))] +#[cfg(any(target_os = "linux", target_os = "android", target_os = "cygwin"))] mod impl_linux { use libc::{SO_PEERCRED, SOL_SOCKET, c_void, getsockopt, socklen_t, ucred}; diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs index 76f5f549dd2..7f21929b85f 100644 --- a/library/std/src/os/windows/io/handle.rs +++ b/library/std/src/os/windows/io/handle.rs @@ -660,3 +660,45 @@ impl<T> From<crate::thread::JoinHandle<T>> for OwnedHandle { join_handle.into_inner().into_handle().into_inner() } } + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl AsHandle for io::PipeReader { + fn as_handle(&self) -> BorrowedHandle<'_> { + self.0.as_handle() + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl From<io::PipeReader> for OwnedHandle { + fn from(pipe: io::PipeReader) -> Self { + pipe.into_inner().into_inner() + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl AsHandle for io::PipeWriter { + fn as_handle(&self) -> BorrowedHandle<'_> { + self.0.as_handle() + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl From<io::PipeWriter> for OwnedHandle { + fn from(pipe: io::PipeWriter) -> Self { + pipe.into_inner().into_inner() + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl From<OwnedHandle> for io::PipeReader { + fn from(owned_handle: OwnedHandle) -> Self { + Self::from_inner(FromInner::from_inner(owned_handle)) + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl From<OwnedHandle> for io::PipeWriter { + fn from(owned_handle: OwnedHandle) -> Self { + Self::from_inner(FromInner::from_inner(owned_handle)) + } +} diff --git a/library/std/src/os/windows/io/raw.rs b/library/std/src/os/windows/io/raw.rs index c0517fab950..bc3e55c8629 100644 --- a/library/std/src/os/windows/io/raw.rs +++ b/library/std/src/os/windows/io/raw.rs @@ -310,3 +310,45 @@ impl IntoRawSocket for net::UdpSocket { self.into_inner().into_socket().into_inner().into_raw_socket() } } + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl AsRawHandle for io::PipeReader { + fn as_raw_handle(&self) -> RawHandle { + self.0.as_raw_handle() + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl FromRawHandle for io::PipeReader { + unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self { + unsafe { Self::from_inner(FromRawHandle::from_raw_handle(raw_handle)) } + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl IntoRawHandle for io::PipeReader { + fn into_raw_handle(self) -> RawHandle { + self.0.into_raw_handle() + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl AsRawHandle for io::PipeWriter { + fn as_raw_handle(&self) -> RawHandle { + self.0.as_raw_handle() + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl FromRawHandle for io::PipeWriter { + unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self { + unsafe { Self::from_inner(FromRawHandle::from_raw_handle(raw_handle)) } + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl IntoRawHandle for io::PipeWriter { + fn into_raw_handle(self) -> RawHandle { + self.0.into_raw_handle() + } +} diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index b47b41d4bc5..b35549c92ad 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -55,12 +55,14 @@ pub static EMPTY_PANIC: fn(&'static str) -> ! = // hook up these functions, but it is not this day! #[allow(improper_ctypes)] unsafe extern "C" { + #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)] fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static); } unsafe extern "Rust" { /// `PanicPayload` lazily performs allocation only when needed (this avoids /// allocations when using the "abort" panic runtime). + #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)] fn __rust_start_panic(payload: &mut dyn PanicPayload) -> u32; } diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 37762c65f65..f81ce8e1a1a 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -1659,6 +1659,20 @@ impl From<io::Stderr> for Stdio { } } +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl From<io::PipeWriter> for Stdio { + fn from(pipe: io::PipeWriter) -> Self { + Stdio::from_inner(pipe.into_inner().into()) + } +} + +#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +impl From<io::PipeReader> for Stdio { + fn from(pipe: io::PipeReader) -> Self { + Stdio::from_inner(pipe.into_inner().into()) + } +} + /// Describes the result of a process after it has terminated. /// /// This `struct` is used to represent the exit status or other termination of a child process. @@ -2004,9 +2018,9 @@ impl ExitCode { /// /// Note that this has the same caveats as [`process::exit()`][exit], namely that this function /// terminates the process immediately, so no destructors on the current stack or any other - /// thread's stack will be run. If a clean shutdown is needed, it is recommended to simply - /// return this ExitCode from the `main` function, as demonstrated in the [type - /// documentation](#examples). + /// thread's stack will be run. Also see those docs for some important notes on interop with C + /// code. If a clean shutdown is needed, it is recommended to simply return this ExitCode from + /// the `main` function, as demonstrated in the [type documentation](#examples). /// /// # Differences from `process::exit()` /// @@ -2312,6 +2326,33 @@ impl Child { /// /// process::exit(0x0100); /// ``` +/// +/// ### Safe interop with C code +/// +/// On Unix, this function is currently implemented using the `exit` C function [`exit`][C-exit]. As +/// of C23, the C standard does not permit multiple threads to call `exit` concurrently. Rust +/// mitigates this with a lock, but if C code calls `exit`, that can still cause undefined behavior. +/// Note that returning from `main` is equivalent to calling `exit`. +/// +/// Therefore, it is undefined behavior to have two concurrent threads perform the following +/// without synchronization: +/// - One thread calls Rust's `exit` function or returns from Rust's `main` function +/// - Another thread calls the C function `exit` or `quick_exit`, or returns from C's `main` function +/// +/// Note that if a binary contains multiple copies of the Rust runtime (e.g., when combining +/// multiple `cdylib` or `staticlib`), they each have their own separate lock, so from the +/// perspective of code running in one of the Rust runtimes, the "outside" Rust code is basically C +/// code, and concurrent `exit` again causes undefined behavior. +/// +/// Individual C implementations might provide more guarantees than the standard and permit concurrent +/// calls to `exit`; consult the documentation of your C implementation for details. +/// +/// For some of the on-going discussion to make `exit` thread-safe in C, see: +/// - [Rust issue #126600](https://github.com/rust-lang/rust/issues/126600) +/// - [Austin Group Bugzilla (for POSIX)](https://austingroupbugs.net/view.php?id=1845) +/// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=31997) +/// +/// [C-exit]: https://en.cppreference.com/w/c/program/exit #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "process_exit")] pub fn exit(code: i32) -> ! { diff --git a/library/std/src/random.rs b/library/std/src/random.rs index 45f51dd37b0..e7d4ab81df0 100644 --- a/library/std/src/random.rs +++ b/library/std/src/random.rs @@ -37,7 +37,7 @@ use crate::sys::random as sys; /// Solaris | [`arc4random_buf`](https://docs.oracle.com/cd/E88353_01/html/E37843/arc4random-3c.html) /// Vita | `arc4random_buf` /// Hermit | `read_entropy` -/// Horizon | `getrandom` shim +/// Horizon, Cygwin | `getrandom` /// AIX, Hurd, L4Re, QNX | `/dev/urandom` /// Redox | `/scheme/rand` /// RTEMS | [`arc4random_buf`](https://docs.rtems.org/branches/master/bsp-howto/getentropy.html) diff --git a/library/std/src/sys/anonymous_pipe/unix.rs b/library/std/src/sys/anonymous_pipe/unix.rs index 9e398765634..dfe10f7fafe 100644 --- a/library/std/src/sys/anonymous_pipe/unix.rs +++ b/library/std/src/sys/anonymous_pipe/unix.rs @@ -1,9 +1,7 @@ -use crate::io::{self, PipeReader, PipeWriter}; -use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; -use crate::process::Stdio; +use crate::io; use crate::sys::fd::FileDesc; use crate::sys::pipe::anon_pipe; -use crate::sys_common::{FromInner, IntoInner}; +use crate::sys_common::IntoInner; pub type AnonPipe = FileDesc; @@ -11,91 +9,3 @@ pub type AnonPipe = FileDesc; pub fn pipe() -> io::Result<(AnonPipe, AnonPipe)> { anon_pipe().map(|(rx, wx)| (rx.into_inner(), wx.into_inner())) } - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl AsFd for PipeReader { - fn as_fd(&self) -> BorrowedFd<'_> { - self.0.as_fd() - } -} -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl AsRawFd for PipeReader { - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() - } -} -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl From<PipeReader> for OwnedFd { - fn from(pipe: PipeReader) -> Self { - FileDesc::into_inner(pipe.0) - } -} -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl FromRawFd for PipeReader { - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - unsafe { Self(FileDesc::from_raw_fd(raw_fd)) } - } -} -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl IntoRawFd for PipeReader { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw_fd() - } -} -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl From<PipeReader> for Stdio { - fn from(pipe: PipeReader) -> Self { - Self::from(OwnedFd::from(pipe)) - } -} - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl AsFd for PipeWriter { - fn as_fd(&self) -> BorrowedFd<'_> { - self.0.as_fd() - } -} -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl AsRawFd for PipeWriter { - fn as_raw_fd(&self) -> RawFd { - self.0.as_raw_fd() - } -} -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl From<PipeWriter> for OwnedFd { - fn from(pipe: PipeWriter) -> Self { - FileDesc::into_inner(pipe.0) - } -} -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl FromRawFd for PipeWriter { - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - unsafe { Self(FileDesc::from_raw_fd(raw_fd)) } - } -} -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl IntoRawFd for PipeWriter { - fn into_raw_fd(self) -> RawFd { - self.0.into_raw_fd() - } -} -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl From<PipeWriter> for Stdio { - fn from(pipe: PipeWriter) -> Self { - Self::from(OwnedFd::from(pipe)) - } -} - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl From<OwnedFd> for PipeReader { - fn from(owned_fd: OwnedFd) -> Self { - Self(FileDesc::from_inner(owned_fd)) - } -} - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl From<OwnedFd> for PipeWriter { - fn from(owned_fd: OwnedFd) -> Self { - Self(FileDesc::from_inner(owned_fd)) - } -} diff --git a/library/std/src/sys/anonymous_pipe/unsupported.rs b/library/std/src/sys/anonymous_pipe/unsupported.rs index 4e79ac9c21a..a0805ba9540 100644 --- a/library/std/src/sys/anonymous_pipe/unsupported.rs +++ b/library/std/src/sys/anonymous_pipe/unsupported.rs @@ -1,22 +1,7 @@ -use crate::io::{self, PipeReader, PipeWriter}; -use crate::process::Stdio; +use crate::io; pub use crate::sys::pipe::AnonPipe; #[inline] pub fn pipe() -> io::Result<(AnonPipe, AnonPipe)> { Err(io::Error::UNSUPPORTED_PLATFORM) } - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl From<PipeReader> for Stdio { - fn from(pipe: PipeReader) -> Self { - pipe.0.diverge() - } -} - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl From<PipeWriter> for Stdio { - fn from(pipe: PipeWriter) -> Self { - pipe.0.diverge() - } -} diff --git a/library/std/src/sys/anonymous_pipe/windows.rs b/library/std/src/sys/anonymous_pipe/windows.rs index eb7fa8ec1c9..bdda7ffc5d2 100644 --- a/library/std/src/sys/anonymous_pipe/windows.rs +++ b/library/std/src/sys/anonymous_pipe/windows.rs @@ -1,12 +1,7 @@ -use crate::io::{self, PipeReader, PipeWriter}; -use crate::os::windows::io::{ - AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle, OwnedHandle, RawHandle, -}; -use crate::process::Stdio; -use crate::ptr; +use crate::os::windows::io::FromRawHandle; use crate::sys::c; use crate::sys::handle::Handle; -use crate::sys_common::{FromInner, IntoInner}; +use crate::{io, ptr}; pub type AnonPipe = Handle; @@ -22,95 +17,3 @@ pub fn pipe() -> io::Result<(AnonPipe, AnonPipe)> { unsafe { Ok((Handle::from_raw_handle(read_pipe), Handle::from_raw_handle(write_pipe))) } } } - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl AsHandle for PipeReader { - fn as_handle(&self) -> BorrowedHandle<'_> { - self.0.as_handle() - } -} -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl AsRawHandle for PipeReader { - fn as_raw_handle(&self) -> RawHandle { - self.0.as_raw_handle() - } -} - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl FromRawHandle for PipeReader { - unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self { - unsafe { Self(Handle::from_raw_handle(raw_handle)) } - } -} -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl IntoRawHandle for PipeReader { - fn into_raw_handle(self) -> RawHandle { - self.0.into_raw_handle() - } -} - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl From<PipeReader> for OwnedHandle { - fn from(pipe: PipeReader) -> Self { - Handle::into_inner(pipe.0) - } -} -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl From<PipeReader> for Stdio { - fn from(pipe: PipeReader) -> Self { - Self::from(OwnedHandle::from(pipe)) - } -} - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl AsHandle for PipeWriter { - fn as_handle(&self) -> BorrowedHandle<'_> { - self.0.as_handle() - } -} -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl AsRawHandle for PipeWriter { - fn as_raw_handle(&self) -> RawHandle { - self.0.as_raw_handle() - } -} - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl FromRawHandle for PipeWriter { - unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self { - unsafe { Self(Handle::from_raw_handle(raw_handle)) } - } -} -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl IntoRawHandle for PipeWriter { - fn into_raw_handle(self) -> RawHandle { - self.0.into_raw_handle() - } -} - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl From<PipeWriter> for OwnedHandle { - fn from(pipe: PipeWriter) -> Self { - Handle::into_inner(pipe.0) - } -} -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl From<PipeWriter> for Stdio { - fn from(pipe: PipeWriter) -> Self { - Self::from(OwnedHandle::from(pipe)) - } -} - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl From<OwnedHandle> for PipeReader { - fn from(owned_handle: OwnedHandle) -> Self { - Self(Handle::from_inner(owned_handle)) - } -} - -#[unstable(feature = "anonymous_pipe", issue = "127154")] -impl From<OwnedHandle> for PipeWriter { - fn from(owned_handle: OwnedHandle) -> Self { - Self(Handle::from_inner(owned_handle)) - } -} diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 56aed7dfd8e..defc1681d38 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -286,8 +286,13 @@ pub fn remove_dir_all(_path: &Path) -> io::Result<()> { unsupported() } -pub fn exists(_path: &Path) -> io::Result<bool> { - unsupported() +pub fn exists(path: &Path) -> io::Result<bool> { + let f = uefi_fs::File::from_path(path, r_efi::protocols::file::MODE_READ, 0); + match f { + Ok(_) => Ok(true), + Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(false), + Err(e) => Err(e), + } } pub fn readlink(_p: &Path) -> io::Result<PathBuf> { @@ -317,3 +322,134 @@ pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> { pub fn copy(_from: &Path, _to: &Path) -> io::Result<u64> { unsupported() } + +mod uefi_fs { + use r_efi::protocols::{device_path, file, simple_file_system}; + + use crate::boxed::Box; + use crate::io; + use crate::path::Path; + use crate::ptr::NonNull; + use crate::sys::helpers; + + pub(crate) struct File(NonNull<file::Protocol>); + + impl File { + pub(crate) fn from_path(path: &Path, open_mode: u64, attr: u64) -> io::Result<Self> { + let absolute = crate::path::absolute(path)?; + + let p = helpers::OwnedDevicePath::from_text(absolute.as_os_str())?; + let (vol, mut path_remaining) = Self::open_volume_from_device_path(p.borrow())?; + + vol.open(&mut path_remaining, open_mode, attr) + } + + /// Open Filesystem volume given a devicepath to the volume, or a file/directory in the + /// volume. The path provided should be absolute UEFI device path, without any UEFI shell + /// mappings. + /// + /// Returns + /// 1. The volume as a UEFI File + /// 2. Path relative to the volume. + /// + /// For example, given "PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Slave,0x0)/\abc\run.efi", + /// this will open the volume "PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Slave,0x0)" + /// and return the remaining file path "\abc\run.efi". + fn open_volume_from_device_path( + path: helpers::BorrowedDevicePath<'_>, + ) -> io::Result<(Self, Box<[u16]>)> { + let handles = match helpers::locate_handles(simple_file_system::PROTOCOL_GUID) { + Ok(x) => x, + Err(e) => return Err(e), + }; + for handle in handles { + let volume_device_path: NonNull<device_path::Protocol> = + match helpers::open_protocol(handle, device_path::PROTOCOL_GUID) { + Ok(x) => x, + Err(_) => continue, + }; + let volume_device_path = helpers::BorrowedDevicePath::new(volume_device_path); + + if let Some(left_path) = path_best_match(&volume_device_path, &path) { + return Ok((Self::open_volume(handle)?, left_path)); + } + } + + Err(io::const_error!(io::ErrorKind::NotFound, "Volume Not Found")) + } + + // Open volume on device_handle using SIMPLE_FILE_SYSTEM_PROTOCOL + fn open_volume(device_handle: NonNull<crate::ffi::c_void>) -> io::Result<Self> { + let simple_file_system_protocol = helpers::open_protocol::<simple_file_system::Protocol>( + device_handle, + simple_file_system::PROTOCOL_GUID, + )?; + + let mut file_protocol = crate::ptr::null_mut(); + let r = unsafe { + ((*simple_file_system_protocol.as_ptr()).open_volume)( + simple_file_system_protocol.as_ptr(), + &mut file_protocol, + ) + }; + if r.is_error() { + return Err(io::Error::from_raw_os_error(r.as_usize())); + } + + // Since no error was returned, file protocol should be non-NULL. + let p = NonNull::new(file_protocol).unwrap(); + Ok(Self(p)) + } + + fn open(&self, path: &mut [u16], open_mode: u64, attr: u64) -> io::Result<Self> { + let file_ptr = self.0.as_ptr(); + let mut file_opened = crate::ptr::null_mut(); + + let r = unsafe { + ((*file_ptr).open)(file_ptr, &mut file_opened, path.as_mut_ptr(), open_mode, attr) + }; + + if r.is_error() { + return Err(io::Error::from_raw_os_error(r.as_usize())); + } + + // Since no error was returned, file protocol should be non-NULL. + let p = NonNull::new(file_opened).unwrap(); + Ok(File(p)) + } + } + + impl Drop for File { + fn drop(&mut self) { + let file_ptr = self.0.as_ptr(); + let _ = unsafe { ((*self.0.as_ptr()).close)(file_ptr) }; + } + } + + /// A helper to check that target path is a descendent of source. It is expected to be used with + /// absolute UEFI device paths without any UEFI shell mappings. + /// + /// Returns the path relative to source + /// + /// For example, given "PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Slave,0x0)/" and + /// "PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Slave,0x0)/\abc\run.efi", this will return + /// "\abc\run.efi" + fn path_best_match( + source: &helpers::BorrowedDevicePath<'_>, + target: &helpers::BorrowedDevicePath<'_>, + ) -> Option<Box<[u16]>> { + let mut source_iter = source.iter().take_while(|x| !x.is_end_instance()); + let mut target_iter = target.iter().take_while(|x| !x.is_end_instance()); + + loop { + match (source_iter.next(), target_iter.next()) { + (Some(x), Some(y)) if x == y => continue, + (None, Some(y)) => { + let p = y.to_path().to_text().ok()?; + return helpers::os_string_to_raw(&p); + } + _ => return None, + } + } + } +} diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index d944bc9c9a2..7c3ed8029f7 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -543,7 +543,12 @@ impl FileAttr { SystemTime::new(self.stat.st_atim.tv_sec as i64, self.stat.st_atim.tv_nsec as i64) } - #[cfg(any(target_os = "freebsd", target_os = "openbsd", target_vendor = "apple"))] + #[cfg(any( + target_os = "freebsd", + target_os = "openbsd", + target_vendor = "apple", + target_os = "cygwin", + ))] pub fn created(&self) -> io::Result<SystemTime> { SystemTime::new(self.stat.st_birthtime as i64, self.stat.st_birthtime_nsec as i64) } @@ -553,6 +558,7 @@ impl FileAttr { target_os = "openbsd", target_os = "vita", target_vendor = "apple", + target_os = "cygwin", )))] pub fn created(&self) -> io::Result<SystemTime> { cfg_has_statx! { @@ -960,6 +966,7 @@ impl DirEntry { #[cfg(any( target_os = "linux", + target_os = "cygwin", target_os = "emscripten", target_os = "android", target_os = "solaris", @@ -1220,6 +1227,7 @@ impl File { target_os = "freebsd", target_os = "fuchsia", target_os = "linux", + target_os = "cygwin", target_os = "android", target_os = "netbsd", target_os = "openbsd", @@ -1234,6 +1242,7 @@ impl File { target_os = "fuchsia", target_os = "freebsd", target_os = "linux", + target_os = "cygwin", target_os = "netbsd", target_os = "openbsd", target_os = "nto", diff --git a/library/std/src/sys/net/connection/socket.rs b/library/std/src/sys/net/connection/socket.rs index e154cf039ca..7301bde6881 100644 --- a/library/std/src/sys/net/connection/socket.rs +++ b/library/std/src/sys/net/connection/socket.rs @@ -59,7 +59,8 @@ cfg_if::cfg_if! { target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", target_os = "solaris", target_os = "illumos", - target_os = "haiku", target_os = "nto"))] { + target_os = "haiku", target_os = "nto", + target_os = "cygwin"))] { use libc::MSG_NOSIGNAL; } else { const MSG_NOSIGNAL: c_int = 0x0; diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index e633cf772c5..bbe1e038dcc 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs @@ -81,6 +81,7 @@ impl Socket { target_os = "linux", target_os = "netbsd", target_os = "openbsd", + target_os = "cygwin", target_os = "nto", target_os = "solaris", ))] { @@ -128,6 +129,7 @@ impl Socket { target_os = "hurd", target_os = "netbsd", target_os = "openbsd", + target_os = "cygwin", target_os = "nto", ))] { // Like above, set cloexec atomically @@ -257,6 +259,7 @@ impl Socket { target_os = "hurd", target_os = "netbsd", target_os = "openbsd", + target_os = "cygwin", ))] { unsafe { let fd = cvt_r(|| libc::accept4(self.as_raw_fd(), storage, len, libc::SOCK_CLOEXEC))?; @@ -421,6 +424,7 @@ impl Socket { Ok(()) } + #[cfg(not(target_os = "cygwin"))] pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> { let linger = libc::linger { l_onoff: linger.is_some() as libc::c_int, @@ -430,6 +434,16 @@ impl Socket { setsockopt(self, libc::SOL_SOCKET, SO_LINGER, linger) } + #[cfg(target_os = "cygwin")] + pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> { + let linger = libc::linger { + l_onoff: linger.is_some() as libc::c_ushort, + l_linger: linger.unwrap_or_default().as_secs() as libc::c_ushort, + }; + + setsockopt(self, libc::SOL_SOCKET, SO_LINGER, linger) + } + pub fn linger(&self) -> io::Result<Option<Duration>> { let val: libc::linger = getsockopt(self, libc::SOL_SOCKET, SO_LINGER)?; diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index 60c33c637d7..2faa733f23f 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -374,7 +374,6 @@ impl<'a> BorrowedDevicePath<'a> { device_path_to_text(self.protocol) } - #[expect(dead_code)] pub(crate) const fn iter(&'a self) -> DevicePathIterator<'a> { DevicePathIterator::new(DevicePathNode::new(self.protocol)) } @@ -452,7 +451,6 @@ impl<'a> DevicePathNode<'a> { && self.sub_type() == r_efi::protocols::device_path::End::SUBTYPE_ENTIRE } - #[expect(dead_code)] pub(crate) const fn is_end_instance(&self) -> bool { self.node_type() == r_efi::protocols::device_path::TYPE_END && self.sub_type() == r_efi::protocols::device_path::End::SUBTYPE_INSTANCE @@ -468,7 +466,6 @@ impl<'a> DevicePathNode<'a> { Self::new(node) } - #[expect(dead_code)] pub(crate) fn to_path(&'a self) -> BorrowedDevicePath<'a> { BorrowedDevicePath::new(self.protocol) } diff --git a/library/std/src/sys/pal/unix/args.rs b/library/std/src/sys/pal/unix/args.rs index 1c87a79803c..0bb7b64007a 100644 --- a/library/std/src/sys/pal/unix/args.rs +++ b/library/std/src/sys/pal/unix/args.rs @@ -100,6 +100,7 @@ impl DoubleEndedIterator for Args { target_os = "dragonfly", target_os = "netbsd", target_os = "openbsd", + target_os = "cygwin", target_os = "solaris", target_os = "illumos", target_os = "emscripten", diff --git a/library/std/src/sys/pal/unix/env.rs b/library/std/src/sys/pal/unix/env.rs index 2aee0b5d460..c6609298f4b 100644 --- a/library/std/src/sys/pal/unix/env.rs +++ b/library/std/src/sys/pal/unix/env.rs @@ -108,6 +108,17 @@ pub mod os { pub const EXE_EXTENSION: &str = ""; } +#[cfg(target_os = "cygwin")] +pub mod os { + pub const FAMILY: &str = "unix"; + pub const OS: &str = "cygwin"; + pub const DLL_PREFIX: &str = ""; + pub const DLL_SUFFIX: &str = ".dll"; + pub const DLL_EXTENSION: &str = "dll"; + pub const EXE_SUFFIX: &str = ".exe"; + pub const EXE_EXTENSION: &str = "exe"; +} + #[cfg(target_os = "android")] pub mod os { pub const FAMILY: &str = "unix"; diff --git a/library/std/src/sys/pal/unix/fd.rs b/library/std/src/sys/pal/unix/fd.rs index a08c7ccec2d..f03c440e30e 100644 --- a/library/std/src/sys/pal/unix/fd.rs +++ b/library/std/src/sys/pal/unix/fd.rs @@ -47,6 +47,7 @@ const READ_LIMIT: usize = if cfg!(target_vendor = "apple") { target_os = "netbsd", target_os = "openbsd", target_vendor = "apple", + target_os = "cygwin", ))] const fn max_iov() -> usize { libc::IOV_MAX as usize @@ -74,6 +75,7 @@ const fn max_iov() -> usize { target_os = "horizon", target_os = "vita", target_vendor = "apple", + target_os = "cygwin", )))] const fn max_iov() -> usize { 16 // The minimum value required by POSIX. @@ -503,6 +505,7 @@ impl FileDesc { target_os = "fuchsia", target_os = "l4re", target_os = "linux", + target_os = "cygwin", target_os = "haiku", target_os = "redox", target_os = "vxworks", @@ -525,6 +528,7 @@ impl FileDesc { target_os = "fuchsia", target_os = "l4re", target_os = "linux", + target_os = "cygwin", target_os = "haiku", target_os = "redox", target_os = "vxworks", diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 419abe732ac..e2e537b7bd3 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -380,7 +380,7 @@ cfg_if::cfg_if! { #[link(name = "pthread")] #[link(name = "rt")] unsafe extern "C" {} - } else if #[cfg(any(target_os = "dragonfly", target_os = "openbsd"))] { + } else if #[cfg(any(target_os = "dragonfly", target_os = "openbsd", target_os = "cygwin"))] { #[link(name = "pthread")] unsafe extern "C" {} } else if #[cfg(target_os = "solaris")] { diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index 91f55fcd32b..30282fbf655 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -46,6 +46,7 @@ unsafe extern "C" { any( target_os = "netbsd", target_os = "openbsd", + target_os = "cygwin", target_os = "android", target_os = "redox", target_os = "nuttx", @@ -118,7 +119,12 @@ pub fn error_string(errno: i32) -> String { unsafe extern "C" { #[cfg_attr( all( - any(target_os = "linux", target_os = "hurd", target_env = "newlib"), + any( + target_os = "linux", + target_os = "hurd", + target_env = "newlib", + target_os = "cygwin" + ), not(target_env = "ohos") ), link_name = "__xpg_strerror_r" @@ -395,6 +401,7 @@ pub fn current_exe() -> io::Result<PathBuf> { #[cfg(any( target_os = "linux", + target_os = "cygwin", target_os = "hurd", target_os = "android", target_os = "nuttx", diff --git a/library/std/src/sys/pal/unix/pipe.rs b/library/std/src/sys/pal/unix/pipe.rs index 4a992e32a91..55510153dc8 100644 --- a/library/std/src/sys/pal/unix/pipe.rs +++ b/library/std/src/sys/pal/unix/pipe.rs @@ -27,6 +27,7 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { target_os = "linux", target_os = "netbsd", target_os = "openbsd", + target_os = "cygwin", target_os = "redox" ))] { unsafe { diff --git a/library/std/src/sys/pal/unix/process/process_common.rs b/library/std/src/sys/pal/unix/process/process_common.rs index dd41921f263..a1c747c8df4 100644 --- a/library/std/src/sys/pal/unix/process/process_common.rs +++ b/library/std/src/sys/pal/unix/process/process_common.rs @@ -489,6 +489,12 @@ impl From<AnonPipe> for Stdio { } } +impl From<FileDesc> for Stdio { + fn from(fd: FileDesc) -> Stdio { + Stdio::Fd(fd) + } +} + impl From<File> for Stdio { fn from(file: File) -> Stdio { Stdio::Fd(file.into_inner()) diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index be9a7e91990..f19512233d8 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -1157,7 +1157,7 @@ fn signal_string(signal: i32) -> &'static str { ) ))] libc::SIGSTKFLT => " (SIGSTKFLT)", - #[cfg(any(target_os = "linux", target_os = "nto"))] + #[cfg(any(target_os = "linux", target_os = "nto", target_os = "cygwin"))] libc::SIGPWR => " (SIGPWR)", #[cfg(any( target_os = "freebsd", @@ -1166,6 +1166,7 @@ fn signal_string(signal: i32) -> &'static str { target_os = "dragonfly", target_os = "nto", target_vendor = "apple", + target_os = "cygwin", ))] libc::SIGEMT => " (SIGEMT)", #[cfg(any( diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index abe8d3fbf68..bffe2536299 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -137,7 +137,8 @@ impl Thread { target_os = "linux", target_os = "freebsd", target_os = "dragonfly", - target_os = "nuttx" + target_os = "nuttx", + target_os = "cygwin" ))] pub fn set_name(name: &CStr) { unsafe { @@ -365,6 +366,7 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> { target_os = "linux", target_os = "aix", target_vendor = "apple", + target_os = "cygwin", ))] { #[allow(unused_assignments)] #[allow(unused_mut)] diff --git a/library/std/src/sys/pal/unsupported/pipe.rs b/library/std/src/sys/pal/unsupported/pipe.rs index 6799d21a1ff..988e551de52 100644 --- a/library/std/src/sys/pal/unsupported/pipe.rs +++ b/library/std/src/sys/pal/unsupported/pipe.rs @@ -1,5 +1,6 @@ use crate::fmt; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; +use crate::sys_common::{FromInner, IntoInner}; pub struct AnonPipe(!); @@ -54,3 +55,53 @@ impl AnonPipe { pub fn read2(p1: AnonPipe, _v1: &mut Vec<u8>, _p2: AnonPipe, _v2: &mut Vec<u8>) -> io::Result<()> { match p1.0 {} } + +impl FromInner<!> for AnonPipe { + fn from_inner(inner: !) -> Self { + inner + } +} + +impl IntoInner<!> for AnonPipe { + fn into_inner(self) -> ! { + self.0 + } +} + +#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))] +mod unix_traits { + use super::AnonPipe; + use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; + use crate::sys_common::FromInner; + + impl AsRawFd for AnonPipe { + #[inline] + fn as_raw_fd(&self) -> RawFd { + self.0 + } + } + + impl AsFd for AnonPipe { + fn as_fd(&self) -> BorrowedFd<'_> { + self.0 + } + } + + impl IntoRawFd for AnonPipe { + fn into_raw_fd(self) -> RawFd { + self.0 + } + } + + impl FromRawFd for AnonPipe { + unsafe fn from_raw_fd(_: RawFd) -> Self { + panic!("creating pipe on this platform is unsupported!") + } + } + + impl FromInner<OwnedFd> for AnonPipe { + fn from_inner(_: OwnedFd) -> Self { + panic!("creating pipe on this platform is unsupported!") + } + } +} diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/pal/windows/process.rs index c57ff355d12..50e4baba607 100644 --- a/library/std/src/sys/pal/windows/process.rs +++ b/library/std/src/sys/pal/windows/process.rs @@ -621,6 +621,12 @@ impl From<AnonPipe> for Stdio { } } +impl From<Handle> for Stdio { + fn from(pipe: Handle) -> Stdio { + Stdio::Handle(pipe) + } +} + impl From<File> for Stdio { fn from(file: File) -> Stdio { Stdio::Handle(file.into_inner()) diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs index cd2c7899f4b..b012e47f9aa 100644 --- a/library/std/src/sys/personality/gcc.rs +++ b/library/std/src/sys/personality/gcc.rs @@ -220,7 +220,7 @@ cfg_if::cfg_if! { Ok(action) => action, Err(_) => return uw::_URC_FATAL_PHASE1_ERROR, }; - if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 { + if actions & uw::_UA_SEARCH_PHASE != 0 { match eh_action { EHAction::None | EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND, EHAction::Catch(_) | EHAction::Filter(_) => uw::_URC_HANDLER_FOUND, @@ -230,7 +230,7 @@ cfg_if::cfg_if! { match eh_action { EHAction::None => uw::_URC_CONTINUE_UNWIND, // Forced unwinding hits a terminate action. - EHAction::Filter(_) if actions as i32 & uw::_UA_FORCE_UNWIND as i32 != 0 => uw::_URC_CONTINUE_UNWIND, + EHAction::Filter(_) if actions & uw::_UA_FORCE_UNWIND != 0 => uw::_URC_CONTINUE_UNWIND, EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => { uw::_Unwind_SetGR( context, @@ -248,7 +248,10 @@ cfg_if::cfg_if! { } cfg_if::cfg_if! { - if #[cfg(all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"))] { + if #[cfg(any( + all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"), + target_os = "cygwin", + ))] { /// personality fn called by [Windows Structured Exception Handling][windows-eh] /// /// On x86_64 and AArch64 MinGW targets, the unwinding mechanism is SEH, diff --git a/library/std/src/sys/random/horizon.rs b/library/std/src/sys/random/getrandom.rs index 0be2eae20a7..0be2eae20a7 100644 --- a/library/std/src/sys/random/horizon.rs +++ b/library/std/src/sys/random/getrandom.rs diff --git a/library/std/src/sys/random/mod.rs b/library/std/src/sys/random/mod.rs index 870039602bc..013e886a99b 100644 --- a/library/std/src/sys/random/mod.rs +++ b/library/std/src/sys/random/mod.rs @@ -35,10 +35,10 @@ cfg_if::cfg_if! { } else if #[cfg(target_os = "hermit")] { mod hermit; pub use hermit::fill_bytes; - } else if #[cfg(target_os = "horizon")] { - // FIXME: add arc4random_buf to shim-3ds - mod horizon; - pub use horizon::fill_bytes; + } else if #[cfg(any(target_os = "horizon", target_os = "cygwin"))] { + // FIXME(horizon): add arc4random_buf to shim-3ds + mod getrandom; + pub use getrandom::fill_bytes; } else if #[cfg(any( target_os = "aix", target_os = "hurd", diff --git a/library/std/tests/floats/f128.rs b/library/std/tests/floats/f128.rs index d0e8b157e6b..b4a6c672bf0 100644 --- a/library/std/tests/floats/f128.rs +++ b/library/std/tests/floats/f128.rs @@ -983,3 +983,34 @@ fn test_total_cmp() { assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f128::INFINITY)); assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan())); } + +#[test] +fn test_from() { + assert_eq!(f128::from(false), 0.0); + assert_eq!(f128::from(true), 1.0); + assert_eq!(f128::from(u8::MIN), 0.0); + assert_eq!(f128::from(42_u8), 42.0); + assert_eq!(f128::from(u8::MAX), 255.0); + assert_eq!(f128::from(i8::MIN), -128.0); + assert_eq!(f128::from(42_i8), 42.0); + assert_eq!(f128::from(i8::MAX), 127.0); + assert_eq!(f128::from(u16::MIN), 0.0); + assert_eq!(f128::from(42_u16), 42.0); + assert_eq!(f128::from(u16::MAX), 65535.0); + assert_eq!(f128::from(i16::MIN), -32768.0); + assert_eq!(f128::from(42_i16), 42.0); + assert_eq!(f128::from(i16::MAX), 32767.0); + assert_eq!(f128::from(u32::MIN), 0.0); + assert_eq!(f128::from(42_u32), 42.0); + assert_eq!(f128::from(u32::MAX), 4294967295.0); + assert_eq!(f128::from(i32::MIN), -2147483648.0); + assert_eq!(f128::from(42_i32), 42.0); + assert_eq!(f128::from(i32::MAX), 2147483647.0); + // FIXME(f16_f128): Uncomment these tests once the From<{u64,i64}> impls are added. + // assert_eq!(f128::from(u64::MIN), 0.0); + // assert_eq!(f128::from(42_u64), 42.0); + // assert_eq!(f128::from(u64::MAX), 18446744073709551615.0); + // assert_eq!(f128::from(i64::MIN), -9223372036854775808.0); + // assert_eq!(f128::from(42_i64), 42.0); + // assert_eq!(f128::from(i64::MAX), 9223372036854775807.0); +} diff --git a/library/std/tests/floats/f16.rs b/library/std/tests/floats/f16.rs index 19389a9178e..ca0b8efbe83 100644 --- a/library/std/tests/floats/f16.rs +++ b/library/std/tests/floats/f16.rs @@ -953,3 +953,15 @@ fn test_total_cmp() { assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&f16::INFINITY)); assert_eq!(Ordering::Less, (-s_nan()).total_cmp(&s_nan())); } + +#[test] +fn test_from() { + assert_eq!(f16::from(false), 0.0); + assert_eq!(f16::from(true), 1.0); + assert_eq!(f16::from(u8::MIN), 0.0); + assert_eq!(f16::from(42_u8), 42.0); + assert_eq!(f16::from(u8::MAX), 255.0); + assert_eq!(f16::from(i8::MIN), -128.0); + assert_eq!(f16::from(42_i8), 42.0); + assert_eq!(f16::from(i8::MAX), 127.0); +} diff --git a/library/std/tests/pipe_subprocess.rs b/library/std/tests/pipe_subprocess.rs index 00d99a578d5..c51a4459e71 100644 --- a/library/std/tests/pipe_subprocess.rs +++ b/library/std/tests/pipe_subprocess.rs @@ -1,5 +1,3 @@ -#![feature(anonymous_pipe)] - fn main() { #[cfg(all(not(miri), any(unix, windows), not(target_os = "emscripten")))] { diff --git a/library/std/tests/run-time-detect.rs b/library/std/tests/run-time-detect.rs index dd14c0266aa..e59ae2f3d7f 100644 --- a/library/std/tests/run-time-detect.rs +++ b/library/std/tests/run-time-detect.rs @@ -9,6 +9,10 @@ feature(stdarch_aarch64_feature_detection) )] #![cfg_attr( + all(target_arch = "s390x", target_os = "linux"), + feature(stdarch_s390x_feature_detection) +)] +#![cfg_attr( all(target_arch = "powerpc", target_os = "linux"), feature(stdarch_powerpc_feature_detection) )] @@ -133,6 +137,32 @@ fn powerpc64_linux() { } #[test] +#[cfg(all(target_arch = "s390x", target_os = "linux"))] +fn s390x_linux() { + use std::arch::is_s390x_feature_detected; + // tidy-alphabetical-start + println!("deflate-conversion: {}", is_s390x_feature_detected!("deflate-conversion")); + println!("enhanced-sort: {}", is_s390x_feature_detected!("enhanced-sort")); + println!("guarded-storage: {}", is_s390x_feature_detected!("guarded-storage")); + println!("high-word: {}", is_s390x_feature_detected!("high-word")); + println!("nnp-assist: {}", is_s390x_feature_detected!("nnp-assist")); + println!("transactional-execution: {}", is_s390x_feature_detected!("transactional-execution")); + println!("vector-enhancements-1: {}", is_s390x_feature_detected!("vector-enhancements-1")); + println!("vector-enhancements-2: {}", is_s390x_feature_detected!("vector-enhancements-2")); + println!( + "vector-packed-decimal-enhancement-2: {}", + is_s390x_feature_detected!("vector-packed-decimal-enhancement-2") + ); + println!( + "vector-packed-decimal-enhancement: {}", + is_s390x_feature_detected!("vector-packed-decimal-enhancement") + ); + println!("vector-packed-decimal: {}", is_s390x_feature_detected!("vector-packed-decimal")); + println!("vector: {}", is_s390x_feature_detected!("vector")); + // tidy-alphabetical-end +} + +#[test] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] fn x86_all() { use std::arch::is_x86_feature_detected; diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index ced8e82b8eb..12582569a57 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -27,10 +27,10 @@ pub type _Unwind_Trace_Fn = #[cfg(target_arch = "x86")] pub const unwinder_private_data_size: usize = 5; -#[cfg(all(target_arch = "x86_64", not(target_os = "windows")))] +#[cfg(all(target_arch = "x86_64", not(any(target_os = "windows", target_os = "cygwin"))))] pub const unwinder_private_data_size: usize = 2; -#[cfg(all(target_arch = "x86_64", target_os = "windows"))] +#[cfg(all(target_arch = "x86_64", any(target_os = "windows", target_os = "cygwin")))] pub const unwinder_private_data_size: usize = 6; #[cfg(all(target_arch = "arm", not(target_vendor = "apple")))] @@ -128,16 +128,13 @@ if #[cfg(any(target_vendor = "apple", target_os = "netbsd", not(target_arch = "a // // 32-bit ARM on iOS/tvOS/watchOS use either DWARF/Compact unwinding or // "setjmp-longjmp" / SjLj unwinding. - #[repr(C)] - #[derive(Copy, Clone, PartialEq)] - pub enum _Unwind_Action { - _UA_SEARCH_PHASE = 1, - _UA_CLEANUP_PHASE = 2, - _UA_HANDLER_FRAME = 4, - _UA_FORCE_UNWIND = 8, - _UA_END_OF_STACK = 16, - } - pub use _Unwind_Action::*; + pub type _Unwind_Action = c_int; + + pub const _UA_SEARCH_PHASE: c_int = 1; + pub const _UA_CLEANUP_PHASE: c_int = 2; + pub const _UA_HANDLER_FRAME: c_int = 4; + pub const _UA_FORCE_UNWIND: c_int = 8; + pub const _UA_END_OF_STACK: c_int = 16; #[cfg_attr( all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")), @@ -292,7 +289,10 @@ if #[cfg(all(target_vendor = "apple", not(target_os = "watchos"), target_arch = } // cfg_if! cfg_if::cfg_if! { -if #[cfg(all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"))] { +if #[cfg(any( + all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"), + target_os = "cygwin", + ))] { // We declare these as opaque types. This is fine since you just need to // pass them to _GCC_specific_handler and forget about them. pub enum EXCEPTION_RECORD {} diff --git a/library/unwind/src/unwinding.rs b/library/unwind/src/unwinding.rs index fa8a8c38583..36120bc868e 100644 --- a/library/unwind/src/unwinding.rs +++ b/library/unwind/src/unwinding.rs @@ -2,16 +2,13 @@ use core::ffi::{c_int, c_void}; -#[repr(C)] -#[derive(Copy, Clone, PartialEq)] -pub enum _Unwind_Action { - _UA_SEARCH_PHASE = 1, - _UA_CLEANUP_PHASE = 2, - _UA_HANDLER_FRAME = 4, - _UA_FORCE_UNWIND = 8, - _UA_END_OF_STACK = 16, -} -pub use _Unwind_Action::*; +pub type _Unwind_Action = c_int; + +pub const _UA_SEARCH_PHASE: c_int = 1; +pub const _UA_CLEANUP_PHASE: c_int = 2; +pub const _UA_HANDLER_FRAME: c_int = 4; +pub const _UA_FORCE_UNWIND: c_int = 8; +pub const _UA_END_OF_STACK: c_int = 16; #[repr(C)] #[derive(Debug, Copy, Clone, PartialEq)] diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md index f036603ee70..f9d7c811f60 100644 --- a/src/bootstrap/README.md +++ b/src/bootstrap/README.md @@ -163,7 +163,7 @@ compiler, which will then build the bootstrap binary written in Rust. Because there are two separate codebases behind `x.py`, they need to be kept in sync. In particular, both `bootstrap.py` and the bootstrap binary -parse `config.toml` and read the same command line arguments. `bootstrap.py` +parse `bootstrap.toml` and read the same command line arguments. `bootstrap.py` keeps these in sync by setting various environment variables, and the programs sometimes have to add arguments that are explicitly ignored, to be read by the other. diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 01a9792f1b3..68400ba0ea0 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -726,7 +726,7 @@ class RustBuild(object): def should_fix_bins_and_dylibs(self): """Whether or not `fix_bin_or_dylib` needs to be run; can only be True - on NixOS or if config.toml has `build.patch-binaries-for-nix` set. + on NixOS or if bootstrap.toml has `build.patch-binaries-for-nix` set. """ if self._should_fix_bins_and_dylibs is not None: return self._should_fix_bins_and_dylibs @@ -775,7 +775,7 @@ class RustBuild(object): "The IN_NIX_SHELL environment variable is `{}`;".format( in_nix_shell ), - "you may need to set `patch-binaries-for-nix=true` in config.toml", + "you may need to set `patch-binaries-for-nix=true` in bootstrap.toml", ) return is_nixos @@ -884,7 +884,7 @@ class RustBuild(object): return os.path.join(self.build_dir, self.build, subdir) def get_toml(self, key, section=None): - """Returns the value of the given key in config.toml, otherwise returns None + """Returns the value of the given key in bootstrap.toml, otherwise returns None >>> rb = RustBuild() >>> rb.config_toml = 'key1 = "value1"\\nkey2 = "value2"' @@ -1250,17 +1250,23 @@ def bootstrap(args): "unless you put them in place manually." ) - # Read from `--config`, then `RUST_BOOTSTRAP_CONFIG`, then `./config.toml`, - # then `config.toml` in the root directory. + # Read from `--config` first, followed by `RUST_BOOTSTRAP_CONFIG`. + # If neither is set, check `./bootstrap.toml`, then `bootstrap.toml` in the root directory. + # If those are unavailable, fall back to `./config.toml`, then `config.toml` for + # backward compatibility. toml_path = args.config or os.getenv("RUST_BOOTSTRAP_CONFIG") using_default_path = toml_path is None if using_default_path: - toml_path = "config.toml" + toml_path = "bootstrap.toml" if not os.path.exists(toml_path): - toml_path = os.path.join(rust_root, toml_path) + toml_path = os.path.join(rust_root, "bootstrap.toml") + if not os.path.exists(toml_path): + toml_path = "config.toml" + if not os.path.exists(toml_path): + toml_path = os.path.join(rust_root, "config.toml") # Give a hard error if `--config` or `RUST_BOOTSTRAP_CONFIG` are set to a missing path, - # but not if `config.toml` hasn't been created. + # but not if `bootstrap.toml` hasn't been created. if not using_default_path or os.path.exists(toml_path): with open(toml_path) as config: config_toml = config.read() @@ -1278,7 +1284,9 @@ def bootstrap(args): # profiles to be renamed while maintaining back compatibility # Keep in sync with `profile_aliases` in config.rs profile_aliases = {"user": "dist"} - include_file = "config.{}.toml".format(profile_aliases.get(profile) or profile) + include_file = "bootstrap.{}.toml".format( + profile_aliases.get(profile) or profile + ) include_dir = os.path.join(rust_root, "src", "bootstrap", "defaults") include_path = os.path.join(include_dir, include_file) diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py index 7494536539d..9e12982a43d 100644 --- a/src/bootstrap/bootstrap_test.py +++ b/src/bootstrap/bootstrap_test.py @@ -156,7 +156,7 @@ class ParseArgsInConfigure(unittest.TestCase): class GenerateAndParseConfig(unittest.TestCase): - """Test that we can serialize and deserialize a config.toml file""" + """Test that we can serialize and deserialize a bootstrap.toml file""" def test_no_args(self): build = serialize_and_parse([]) @@ -206,11 +206,11 @@ class BuildBootstrap(unittest.TestCase): # problem in most cases, but there is a scenario where it would cause # the test to fail. # - # When a custom local Cargo is configured in config.toml (with the + # When a custom local Cargo is configured in bootstrap.toml (with the # build.cargo setting), no Cargo is downloaded to any location known by # bootstrap, and bootstrap relies on that setting to find it. # - # In this test though we are not using the config.toml of the caller: + # In this test though we are not using the bootstrap.toml of the caller: # we are generating a blank one instead. If we don't set build.cargo in # it, the test will have no way to find Cargo, failing the test. cargo_bin = os.environ.get("BOOTSTRAP_TEST_CARGO_BIN") diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 77151edd240..f6afe096724 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -367,8 +367,8 @@ if "--help" in sys.argv or "-h" in sys.argv: print("\t\t" + option.desc) print("") print("This configure script is a thin configuration shim over the true") - print("configuration system, `config.toml`. You can explore the comments") - print("in `config.example.toml` next to this configure script to see") + print("configuration system, `bootstrap.toml`. You can explore the comments") + print("in `bootstrap.example.toml` next to this configure script to see") print("more information about what each option is. Additionally you can") print("pass `--set` as an argument to set arbitrary key/value pairs") print("in the TOML configuration if desired") @@ -567,8 +567,8 @@ def apply_args(known_args, option_checking, config): raise RuntimeError("unhandled option {}".format(option.name)) -# "Parse" the `config.example.toml` file into the various sections, and we'll -# use this as a template of a `config.toml` to write out which preserves +# "Parse" the `bootstrap.example.toml` file into the various sections, and we'll +# use this as a template of a `bootstrap.toml` to write out which preserves # all the various comments and whatnot. # # Note that the `target` section is handled separately as we'll duplicate it @@ -581,7 +581,7 @@ def parse_example_config(known_args, config): targets = {} top_level_keys = [] - with open(rust_dir + "/config.example.toml") as example_config: + with open(rust_dir + "/bootstrap.example.toml") as example_config: example_lines = example_config.read().split("\n") for line in example_lines: if cur_section is None: @@ -755,8 +755,8 @@ def quit_if_file_exists(file): if __name__ == "__main__": - # If 'config.toml' already exists, exit the script at this point - quit_if_file_exists("config.toml") + # If 'bootstrap.toml' already exists, exit the script at this point + quit_if_file_exists("bootstrap.toml") if "GITHUB_ACTIONS" in os.environ: print("::group::Configure the build") @@ -766,11 +766,11 @@ if __name__ == "__main__": p("") section_order, sections, targets = parse_args(sys.argv[1:]) - # Now that we've built up our `config.toml`, write it all out in the same + # Now that we've built up our `bootstrap.toml`, write it all out in the same # order that we read it in. p("") - p("writing `config.toml` in current directory") - with bootstrap.output("config.toml") as f: + p("writing `bootstrap.toml` in current directory") + with bootstrap.output("bootstrap.toml") as f: write_config_toml(f, section_order, targets, sections) with bootstrap.output("Makefile") as f: diff --git a/src/bootstrap/defaults/config.compiler.toml b/src/bootstrap/defaults/bootstrap.compiler.toml index 269b90106e3..269b90106e3 100644 --- a/src/bootstrap/defaults/config.compiler.toml +++ b/src/bootstrap/defaults/bootstrap.compiler.toml diff --git a/src/bootstrap/defaults/config.dist.toml b/src/bootstrap/defaults/bootstrap.dist.toml index 7b381b416ca..7b381b416ca 100644 --- a/src/bootstrap/defaults/config.dist.toml +++ b/src/bootstrap/defaults/bootstrap.dist.toml diff --git a/src/bootstrap/defaults/config.library.toml b/src/bootstrap/defaults/bootstrap.library.toml index b43796d6f20..b43796d6f20 100644 --- a/src/bootstrap/defaults/config.library.toml +++ b/src/bootstrap/defaults/bootstrap.library.toml diff --git a/src/bootstrap/defaults/config.tools.toml b/src/bootstrap/defaults/bootstrap.tools.toml index 57c2706f60a..57c2706f60a 100644 --- a/src/bootstrap/defaults/config.tools.toml +++ b/src/bootstrap/defaults/bootstrap.tools.toml diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 6f6aaa878ef..88c2d8d9968 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -77,14 +77,14 @@ fn main() { check_version(&config) }; - // NOTE: Since `./configure` generates a `config.toml`, distro maintainers will see the + // NOTE: Since `./configure` generates a `bootstrap.toml`, distro maintainers will see the // changelog warning, not the `x.py setup` message. let suggest_setup = config.config.is_none() && !matches!(config.cmd, Subcommand::Setup { .. }); if suggest_setup { - println!("WARNING: you have not made a `config.toml`"); + println!("WARNING: you have not made a `bootstrap.toml`"); println!( - "HELP: consider running `./x.py setup` or copying `config.example.toml` by running \ - `cp config.example.toml config.toml`" + "HELP: consider running `./x.py setup` or copying `bootstrap.example.toml` by running \ + `cp bootstrap.example.toml bootstrap.toml`" ); } else if let Some(suggestion) = &changelog_suggestion { println!("{suggestion}"); @@ -98,10 +98,10 @@ fn main() { Build::new(config).build(); if suggest_setup { - println!("WARNING: you have not made a `config.toml`"); + println!("WARNING: you have not made a `bootstrap.toml`"); println!( - "HELP: consider running `./x.py setup` or copying `config.example.toml` by running \ - `cp config.example.toml config.toml`" + "HELP: consider running `./x.py setup` or copying `bootstrap.example.toml` by running \ + `cp bootstrap.example.toml bootstrap.toml`" ); } else if let Some(suggestion) = &changelog_suggestion { println!("{suggestion}"); @@ -160,7 +160,7 @@ fn check_version(config: &Config) -> Option<String> { } // Always try to use `change-id` from .last-warned-change-id first. If it doesn't exist, - // then use the one from the config.toml. This way we never show the same warnings + // then use the one from the bootstrap.toml. This way we never show the same warnings // more than once. if let Ok(t) = fs::read_to_string(&warned_id_path) { let last_warned_id = usize::from_str(&t) @@ -185,16 +185,18 @@ fn check_version(config: &Config) -> Option<String> { msg.push_str("NOTE: to silence this warning, "); msg.push_str(&format!( - "update `config.toml` to use `change-id = {latest_change_id}` instead" + "update `bootstrap.toml` to use `change-id = {latest_change_id}` instead" )); if io::stdout().is_terminal() { t!(fs::write(warned_id_path, latest_change_id.to_string())); } } else { - msg.push_str("WARNING: The `change-id` is missing in the `config.toml`. This means that you will not be able to track the major changes made to the bootstrap configurations.\n"); + msg.push_str("WARNING: The `change-id` is missing in the `bootstrap.toml`. This means that you will not be able to track the major changes made to the bootstrap configurations.\n"); msg.push_str("NOTE: to silence this warning, "); - msg.push_str(&format!("add `change-id = {latest_change_id}` at the top of `config.toml`")); + msg.push_str(&format!( + "add `change-id = {latest_change_id}` at the top of `bootstrap.toml`" + )); }; Some(msg) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 7c83c53d2c2..846b4de8142 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -425,7 +425,7 @@ fn copy_self_contained_objects( } else if target.contains("-wasi") { let srcdir = builder.wasi_libdir(target).unwrap_or_else(|| { panic!( - "Target {:?} does not have a \"wasi-root\" key in Config.toml \ + "Target {:?} does not have a \"wasi-root\" key in bootstrap.toml \ or `$WASI_SDK_PATH` set", target.triple ) @@ -1294,7 +1294,7 @@ pub fn rustc_cargo_env( .env("CFG_VERSION", builder.rust_version()); // Some tools like Cargo detect their own git information in build scripts. When omit-git-hash - // is enabled in config.toml, we pass this environment variable to tell build scripts to avoid + // is enabled in bootstrap.toml, we pass this environment variable to tell build scripts to avoid // detecting git information on their own. if builder.config.omit_git_hash { cargo.env("CFG_OMIT_GIT_HASH", "1"); @@ -1538,7 +1538,7 @@ fn is_codegen_cfg_needed(path: &TaskPath, run: &RunConfig<'_>) -> bool { { run.builder.info( "WARNING: no codegen-backends config matched the requested path to build a codegen backend. \ - HELP: add backend to codegen-backends in config.toml.", + HELP: add backend to codegen-backends in bootstrap.toml.", ); return true; } @@ -1550,7 +1550,7 @@ fn is_codegen_cfg_needed(path: &TaskPath, run: &RunConfig<'_>) -> bool { impl Step for CodegenBackend { type Output = (); const ONLY_HOSTS: bool = true; - /// Only the backends specified in the `codegen-backends` entry of `config.toml` are built. + /// Only the backends specified in the `codegen-backends` entry of `bootstrap.toml` are built. const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index ffb60bd5634..39f9680cb2f 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -519,7 +519,7 @@ impl Step for Rustc { // The REUSE-managed license files let license = |path: &Path| { - builder.install(path, &image.join("share/doc/rust/licences"), 0o644); + builder.install(path, &image.join("share/doc/rust/licenses"), 0o644); }; for entry in t!(std::fs::read_dir(builder.src.join("LICENSES"))).flatten() { license(&entry.path()); @@ -1000,9 +1000,9 @@ impl Step for PlainSourceTarball { let src_files = [ // tidy-alphabetical-start ".gitmodules", + "bootstrap.example.toml", "Cargo.lock", "Cargo.toml", - "config.example.toml", "configure", "CONTRIBUTING.md", "COPYRIGHT", diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 8e913f68184..a8da4146100 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -1218,7 +1218,7 @@ impl Step for RustcBook { cmd.env("RUSTC_BOOTSTRAP", "1"); // If the lib directories are in an unusual location (changed in - // config.toml), then this needs to explicitly update the dylib search + // bootstrap.toml), then this needs to explicitly update the dylib search // path. builder.add_rustc_lib_path(self.compiler, &mut cmd); let doc_generator_guard = builder.msg( diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index 4f96d67a5bd..3e5069225d2 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -85,11 +85,11 @@ fn install_sh( } else { assert!( is_dir_writable_for_user(&prefix), - "User doesn't have write access on `install.prefix` path in the `config.toml`.", + "User doesn't have write access on `install.prefix` path in the `bootstrap.toml`.", ); assert!( is_dir_writable_for_user(&sysconfdir), - "User doesn't have write access on `install.sysconfdir` path in `config.toml`." + "User doesn't have write access on `install.sysconfdir` path in `bootstrap.toml`." ); } diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index e324cf745ff..1e3148d631c 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -350,7 +350,7 @@ impl Step for Llvm { (true, true) => "RelWithDebInfo", }; - // NOTE: remember to also update `config.example.toml` when changing the + // NOTE: remember to also update `bootstrap.example.toml` when changing the // defaults! let llvm_targets = match &builder.config.llvm_targets { Some(s) => s, @@ -471,6 +471,10 @@ impl Step for Llvm { cfg.define("LLVM_BUILD_32_BITS", "ON"); } + if target.starts_with("x86_64") && target.contains("ohos") { + cfg.define("LLVM_TOOL_LLVM_RTDYLD_BUILD", "OFF"); + } + let mut enabled_llvm_projects = Vec::new(); if helpers::forcing_clang_based_tests() { @@ -769,7 +773,9 @@ fn configure_cmake( cflags.push(" "); cflags.push(s); } - + if target.contains("ohos") { + cflags.push(" -D_LINUX_SYSINFO_H"); + } if builder.config.llvm_clang_cl.is_some() { cflags.push(format!(" --target={target}")); } @@ -790,6 +796,9 @@ fn configure_cmake( cxxflags.push(" "); cxxflags.push(s); } + if target.contains("ohos") { + cxxflags.push(" -D_LINUX_SYSINFO_H"); + } if builder.config.llvm_clang_cl.is_some() { cxxflags.push(format!(" --target={target}")); } @@ -1176,6 +1185,10 @@ impl Step for Sanitizers { cfg.define("COMPILER_RT_USE_LIBCXX", "OFF"); cfg.define("LLVM_CONFIG_PATH", &llvm_config); + if self.target.contains("ohos") { + cfg.define("COMPILER_RT_USE_BUILTINS_LIBRARY", "ON"); + } + // On Darwin targets the sanitizer runtimes are build as universal binaries. // Unfortunately sccache currently lacks support to build them successfully. // Disable compiler launcher on Darwin targets to avoid potential issues. diff --git a/src/bootstrap/src/core/build_steps/perf.rs b/src/bootstrap/src/core/build_steps/perf.rs index 6962001fdc2..7f4e88bd73c 100644 --- a/src/bootstrap/src/core/build_steps/perf.rs +++ b/src/bootstrap/src/core/build_steps/perf.rs @@ -147,7 +147,7 @@ pub fn perf(builder: &Builder<'_>, args: &PerfArgs) { }; if is_profiling && builder.build.config.rust_debuginfo_level_rustc == DebuginfoLevel::None { builder.info(r#"WARNING: You are compiling rustc without debuginfo, this will make profiling less useful. -Consider setting `rust.debuginfo-level = 1` in `config.toml`."#); +Consider setting `rust.debuginfo-level = 1` in `bootstrap.toml`."#); } let compiler = builder.compiler(builder.top_stage, builder.config.build); diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 1ef86e674f0..5cacd5b9914 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -35,10 +35,10 @@ impl Step for BuildManifest { // (https://github.com/rust-lang/promote-release). let mut cmd = builder.tool_cmd(Tool::BuildManifest); let sign = builder.config.dist_sign_folder.as_ref().unwrap_or_else(|| { - panic!("\n\nfailed to specify `dist.sign-folder` in `config.toml`\n\n") + panic!("\n\nfailed to specify `dist.sign-folder` in `bootstrap.toml`\n\n") }); let addr = builder.config.dist_upload_addr.as_ref().unwrap_or_else(|| { - panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n") + panic!("\n\nfailed to specify `dist.upload-addr` in `bootstrap.toml`\n\n") }); let today = command("date").arg("+%Y-%m-%d").run_capture_stdout(builder).stdout(); diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index f82ceb3f7fa..80d92135dd3 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -2,8 +2,8 @@ //! //! These are build-and-run steps for `./x.py setup`, which allows quickly setting up the directory //! for modifying, building, and running the compiler and library. Running arbitrary configuration -//! allows setting up things that cannot be simply captured inside the config.toml, in addition to -//! leading people away from manually editing most of the config.toml values. +//! allows setting up things that cannot be simply captured inside the bootstrap.toml, in addition to +//! leading people away from manually editing most of the bootstrap.toml values. use std::env::consts::EXE_SUFFIX; use std::fmt::Write as _; @@ -37,7 +37,7 @@ static PROFILE_DIR: &str = "src/bootstrap/defaults"; impl Profile { fn include_path(&self, src_path: &Path) -> PathBuf { - PathBuf::from(format!("{}/{PROFILE_DIR}/config.{}.toml", src_path.display(), self)) + PathBuf::from(format!("{}/{PROFILE_DIR}/bootstrap.{}.toml", src_path.display(), self)) } pub fn all() -> impl Iterator<Item = Self> { @@ -53,7 +53,7 @@ impl Profile { Compiler => "Contribute to the compiler itself", Tools => "Contribute to tools which depend on the compiler, but do not modify it directly (e.g. rustdoc, clippy, miri)", Dist => "Install Rust from source", - None => "Do not modify `config.toml`" + None => "Do not modify `bootstrap.toml`" } .to_string() } @@ -117,7 +117,7 @@ impl Step for Profile { return; } - let path = &run.builder.config.config.clone().unwrap_or(PathBuf::from("config.toml")); + let path = &run.builder.config.config.clone().unwrap_or(PathBuf::from("bootstrap.toml")); if path.exists() { eprintln!(); eprintln!( @@ -203,7 +203,7 @@ pub fn setup(config: &Config, profile: Profile) { ) } - let path = &config.config.clone().unwrap_or(PathBuf::from("config.toml")); + let path = &config.config.clone().unwrap_or(PathBuf::from("bootstrap.toml")); setup_config_toml(path, profile, config); } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index cff286e99fa..81f6b473c45 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1119,7 +1119,7 @@ impl Step for Tidy { "\ ERROR: no `rustfmt` binary found in {PATH} INFO: `rust.channel` is currently set to \"{CHAN}\" -HELP: if you are testing a beta branch, set `rust.channel` to \"beta\" in the `config.toml` file +HELP: if you are testing a beta branch, set `rust.channel` to \"beta\" in the `bootstrap.toml` file HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to `x.py test`", PATH = inferred_rustfmt_dir.display(), CHAN = builder.config.channel, diff --git a/src/bootstrap/src/core/build_steps/toolstate.rs b/src/bootstrap/src/core/build_steps/toolstate.rs index a65623de95a..fc7acd1fa14 100644 --- a/src/bootstrap/src/core/build_steps/toolstate.rs +++ b/src/bootstrap/src/core/build_steps/toolstate.rs @@ -128,7 +128,7 @@ impl Step for ToolStateCheck { /// Checks tool state status. /// /// This is intended to be used in the `checktools.sh` script. To use - /// this, set `save-toolstates` in `config.toml` so that tool status will + /// this, set `save-toolstates` in `bootstrap.toml` so that tool status will /// be saved to a JSON file. Then, run `x.py test --no-fail-fast` for all /// of the tools to populate the JSON file. After that is done, this /// command can be run to check for any status failures, and exits with an @@ -254,7 +254,7 @@ impl Builder<'_> { /// Updates the actual toolstate of a tool. /// /// The toolstates are saved to the file specified by the key - /// `rust.save-toolstates` in `config.toml`. If unspecified, nothing will be + /// `rust.save-toolstates` in `bootstrap.toml`. If unspecified, nothing will be /// done. The file is updated immediately after this function completes. pub fn save_toolstate(&self, tool: &str, state: ToolState) { use std::io::Write; diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 62d23c4ae6b..a96ccdd12c2 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -215,7 +215,7 @@ impl Cargo { // dynamic libraries. We use this by default on Unix platforms to ensure // that our nightlies behave the same on Windows, that is they work out // of the box. This can be disabled by setting `rpath = false` in `[rust]` - // table of `config.toml` + // table of `bootstrap.toml` // // Ok, so the astute might be wondering "why isn't `-C rpath` used // here?" and that is indeed a good question to ask. This codegen @@ -1073,6 +1073,7 @@ impl Builder<'_> { lint_flags.push("-Wkeyword_idents_2024"); lint_flags.push("-Wunreachable_pub"); lint_flags.push("-Wunsafe_op_in_unsafe_fn"); + lint_flags.push("-Wunused_crate_dependencies"); } // This does not use RUSTFLAGS for two reasons. diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 0b6b8513cc3..a9058f888d3 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -31,9 +31,9 @@ mod cargo; mod tests; /// Builds and performs different [`Self::kind`]s of stuff and actions, taking -/// into account build configuration from e.g. config.toml. +/// into account build configuration from e.g. bootstrap.toml. pub struct Builder<'a> { - /// Build configuration from e.g. config.toml. + /// Build configuration from e.g. bootstrap.toml. pub build: &'a Build, /// The stage to use. Either implicitly determined based on subcommand, or @@ -332,7 +332,7 @@ impl PathSet { } const PATH_REMAP: &[(&str, &[&str])] = &[ - // config.toml uses `rust-analyzer-proc-macro-srv`, but the + // bootstrap.toml uses `rust-analyzer-proc-macro-srv`, but the // actual path is `proc-macro-srv-cli` ("rust-analyzer-proc-macro-srv", &["src/tools/rust-analyzer/crates/proc-macro-srv-cli"]), // Make `x test tests` function the same as `x t tests/*` diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index a07c40bdc83..f8ed8072c3d 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1,6 +1,6 @@ //! Serialized configuration of a build. //! -//! This module implements parsing `config.toml` configuration files to tweak +//! This module implements parsing `bootstrap.toml` configuration files to tweak //! how the build runs. use std::cell::{Cell, RefCell}; @@ -64,7 +64,7 @@ macro_rules! check_ci_llvm { /// useful in scenarios where developers want to see how the tarball sources were /// generated. /// -/// We also use this file to compare the host's config.toml against the CI rustc builder +/// We also use this file to compare the host's bootstrap.toml against the CI rustc builder /// configuration to detect any incompatible options. pub(crate) const BUILDER_CONFIG_FILENAME: &str = "builder-config"; @@ -184,12 +184,12 @@ pub enum GccCiMode { /// Global configuration for the entire build and/or bootstrap. /// -/// This structure is parsed from `config.toml`, and some of the fields are inferred from `git` or build-time parameters. +/// This structure is parsed from `bootstrap.toml`, and some of the fields are inferred from `git` or build-time parameters. /// /// Note that this structure is not decoded directly into, but rather it is /// filled out from the decoded forms of the structs below. For documentation /// each field, see the corresponding fields in -/// `config.example.toml`. +/// `bootstrap.example.toml`. #[derive(Default, Clone)] pub struct Config { pub change_id: Option<usize>, @@ -235,7 +235,7 @@ pub struct Config { pub keep_stage: Vec<u32>, pub keep_stage_std: Vec<u32>, pub src: PathBuf, - /// defaults to `config.toml` + /// defaults to `bootstrap.toml` pub config: Option<PathBuf>, pub jobs: Option<u32>, pub cmd: Subcommand, @@ -470,7 +470,7 @@ impl std::str::FromStr for SplitDebuginfo { impl SplitDebuginfo { /// Returns the default `-Csplit-debuginfo` value for the current target. See the comment for - /// `rust.split-debuginfo` in `config.example.toml`. + /// `rust.split-debuginfo` in `bootstrap.example.toml`. fn default_for_platform(target: TargetSelection) -> Self { if target.contains("apple") { SplitDebuginfo::Unpacked @@ -677,7 +677,7 @@ impl Target { target } } -/// Structure of the `config.toml` file that configuration is read from. +/// Structure of the `bootstrap.toml` file that configuration is read from. /// /// This structure uses `Decodable` to automatically decode a TOML configuration /// file into this format, and then this is traversed and written into the above @@ -959,6 +959,7 @@ define_config! { jobs: Option<u32> = "jobs", compiletest_diff_tool: Option<String> = "compiletest-diff-tool", ccache: Option<StringOrBool> = "ccache", + exclude: Option<Vec<PathBuf>> = "exclude", } } @@ -1397,22 +1398,6 @@ impl Config { "flags.exclude" = ?flags.exclude ); - config.skip = flags - .skip - .into_iter() - .chain(flags.exclude) - .map(|p| { - // Never return top-level path here as it would break `--skip` - // logic on rustc's internal test framework which is utilized - // by compiletest. - if cfg!(windows) { - PathBuf::from(p.to_str().unwrap().replace('/', "\\")) - } else { - p - } - }) - .collect(); - #[cfg(feature = "tracing")] span!( target: "CONFIG_HANDLING", @@ -1500,26 +1485,35 @@ impl Config { config.stage0_metadata = build_helper::stage0_parser::parse_stage0_file(); - // Find configuration file, with the following cascading fallback (first match wins): - // - `--config <path>` - // - `RUST_BOOTSTRAP_CONFIG` - // - `./config.toml` - // - `config.toml` in the root directory. + // Locate the configuration file using the following priority (first match wins): + // 1. `--config <path>` (explicit flag) + // 2. `RUST_BOOTSTRAP_CONFIG` environment variable + // 3. `./bootstrap.toml` (local file) + // 4. `<root>/bootstrap.toml` + // 5. `./config.toml` (fallback for backward compatibility) + // 6. `<root>/config.toml` let toml_path = flags .config .clone() .or_else(|| env::var_os("RUST_BOOTSTRAP_CONFIG").map(PathBuf::from)); let using_default_path = toml_path.is_none(); - let mut toml_path = toml_path.unwrap_or_else(|| PathBuf::from("config.toml")); + let mut toml_path = toml_path.unwrap_or_else(|| PathBuf::from("bootstrap.toml")); + if using_default_path && !toml_path.exists() { - toml_path = config.src.join(toml_path); + toml_path = config.src.join(PathBuf::from("bootstrap.toml")); + if !toml_path.exists() { + toml_path = PathBuf::from("config.toml"); + if !toml_path.exists() { + toml_path = config.src.join(PathBuf::from("config.toml")); + } + } } let file_content = t!(fs::read_to_string(config.src.join("src/ci/channel"))); let ci_channel = file_content.trim_end(); // Give a hard error if `--config` or `RUST_BOOTSTRAP_CONFIG` are set to a missing path, - // but not if `config.toml` hasn't been created. + // but not if `bootstrap.toml` hasn't been created. let mut toml = if !using_default_path || toml_path.exists() { config.config = Some(if cfg!(not(test)) { toml_path.canonicalize().unwrap() @@ -1540,7 +1534,7 @@ impl Config { // same ones used to call the tests (if custom ones are not defined in the toml). If we // don't do that, bootstrap will use its own detection logic to find a suitable rustc // and Cargo, which doesn't work when the caller is specìfying a custom local rustc or - // Cargo in their config.toml. + // Cargo in their bootstrap.toml. let build = toml.build.get_or_insert_with(Default::default); build.rustc = build.rustc.take().or(std::env::var_os("RUSTC").map(|p| p.into())); build.cargo = build.cargo.take().or(std::env::var_os("CARGO").map(|p| p.into())); @@ -1563,7 +1557,7 @@ impl Config { include_path.push("src"); include_path.push("bootstrap"); include_path.push("defaults"); - include_path.push(format!("config.{include}.toml")); + include_path.push(format!("bootstrap.{include}.toml")); let included_toml = get_toml(&include_path).unwrap_or_else(|e| { eprintln!( "ERROR: Failed to parse default config profile at '{}': {e}", @@ -1658,8 +1652,29 @@ impl Config { jobs, compiletest_diff_tool, mut ccache, + exclude, } = toml.build.unwrap_or_default(); + let mut paths: Vec<PathBuf> = flags.skip.into_iter().chain(flags.exclude).collect(); + + if let Some(exclude) = exclude { + paths.extend(exclude); + } + + config.skip = paths + .into_iter() + .map(|p| { + // Never return top-level path here as it would break `--skip` + // logic on rustc's internal test framework which is utilized + // by compiletest. + if cfg!(windows) { + PathBuf::from(p.to_str().unwrap().replace('/', "\\")) + } else { + p + } + }) + .collect(); + config.jobs = Some(threads_from_config(flags.jobs.unwrap_or(jobs.unwrap_or(0)))); if let Some(file_build) = build { @@ -2024,7 +2039,7 @@ impl Config { config.description = description; // We need to override `rust.channel` if it's manually specified when using the CI rustc. - // This is because if the compiler uses a different channel than the one specified in config.toml, + // This is because if the compiler uses a different channel than the one specified in bootstrap.toml, // tests may fail due to using a different channel than the one used by the compiler during tests. if let Some(commit) = &config.download_rustc_commit { if is_user_configured_rust_channel { @@ -2649,7 +2664,7 @@ impl Config { return None; }, Err(e) => { - eprintln!("ERROR: Failed to parse CI rustc config.toml: {e}"); + eprintln!("ERROR: Failed to parse CI rustc bootstrap.toml: {e}"); exit!(2); }, }; @@ -2812,7 +2827,7 @@ impl Config { /// /// `relative_path` should be relative to the root of the git repository, not an absolute path. /// - /// This *does not* update the submodule if `config.toml` explicitly says + /// This *does not* update the submodule if `bootstrap.toml` explicitly says /// not to, or if we're not in a git repository (like a plain source /// tarball). Typically [`crate::Build::require_submodule`] should be /// used instead to provide a nice error to the user if the submodule is @@ -3036,7 +3051,9 @@ impl Config { } println!("ERROR: could not find commit hash for downloading rustc"); println!("HELP: maybe your repository history is too shallow?"); - println!("HELP: consider setting `rust.download-rustc=false` in config.toml"); + println!( + "HELP: consider setting `rust.download-rustc=false` in bootstrap.toml" + ); println!("HELP: or fetch enough history to include one upstream commit"); crate::exit!(1); } diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index 3bb62bbe380..0f8efcfcc76 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -54,7 +54,7 @@ pub struct Flags { /// TOML configuration file for build pub config: Option<PathBuf>, #[arg(global = true, long, value_hint = clap::ValueHint::DirPath, value_name = "DIR")] - /// Build directory, overrides `build.build-dir` in `config.toml` + /// Build directory, overrides `build.build-dir` in `bootstrap.toml` pub build_dir: Option<PathBuf>, #[arg(global = true, long, value_hint = clap::ValueHint::Other, value_name = "BUILD")] @@ -173,7 +173,7 @@ pub struct Flags { #[arg(global = true)] /// paths for the subcommand pub paths: Vec<PathBuf>, - /// override options in config.toml + /// override options in bootstrap.toml #[arg(global = true, value_hint = clap::ValueHint::Other, long, value_name = "section.option=value")] pub set: Vec<String>, /// arguments passed to subcommands @@ -448,7 +448,7 @@ pub enum Subcommand { /// Set up the environment for development #[command(long_about = format!( "\n -x.py setup creates a `config.toml` which changes the defaults for x.py itself, +x.py setup creates a `bootstrap.toml` which changes the defaults for x.py itself, as well as setting up a git pre-push hook, VS Code config and toolchain link. Arguments: This subcommand accepts a 'profile' to use for builds. For example: @@ -461,7 +461,7 @@ Arguments: ./x.py setup editor ./x.py setup link", Profile::all_for_help(" ").trim_end()))] Setup { - /// Either the profile for `config.toml` or another setup action. + /// Either the profile for `bootstrap.toml` or another setup action. /// May be omitted to set up interactively #[arg(value_name = "<PROFILE>|hook|editor|link")] profile: Option<PathBuf>, diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index eff5e033742..7ffd2acb645 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -69,7 +69,7 @@ fn detect_src_and_out() { let expected_src = manifest_dir.ancestors().nth(2).unwrap(); assert_eq!(&cfg.src, expected_src); - // test if build-dir was manually given in config.toml + // test if build-dir was manually given in bootstrap.toml if let Some(custom_build_dir) = build_dir { assert_eq!(&cfg.out, Path::new(custom_build_dir)); } @@ -229,13 +229,15 @@ fn override_toml_duplicate() { #[test] fn profile_user_dist() { fn get_toml(file: &Path) -> Result<TomlConfig, toml::de::Error> { - let contents = - if file.ends_with("config.toml") || env::var_os("RUST_BOOTSTRAP_CONFIG").is_some() { - "profile = \"user\"".to_owned() - } else { - assert!(file.ends_with("config.dist.toml")); - std::fs::read_to_string(file).unwrap() - }; + let contents = if file.ends_with("bootstrap.toml") + || file.ends_with("config.toml") + || env::var_os("RUST_BOOTSTRAP_CONFIG").is_some() + { + "profile = \"user\"".to_owned() + } else { + assert!(file.ends_with("config.dist.toml") || file.ends_with("bootstrap.dist.toml")); + std::fs::read_to_string(file).unwrap() + }; toml::from_str(&contents).and_then(|table: toml::Value| TomlConfig::deserialize(table)) } @@ -402,7 +404,7 @@ fn jobs_precedence() { ); assert_eq!(config.jobs, Some(67890)); - // `--set build.jobs` should take precedence over `config.toml`. + // `--set build.jobs` should take precedence over `bootstrap.toml`. let config = Config::parse_inner( Flags::parse(&[ "check".to_owned(), @@ -420,7 +422,7 @@ fn jobs_precedence() { ); assert_eq!(config.jobs, Some(12345)); - // `--jobs` > `--set build.jobs` > `config.toml` + // `--jobs` > `--set build.jobs` > `bootstrap.toml` let config = Config::parse_inner( Flags::parse(&[ "check".to_owned(), @@ -515,3 +517,18 @@ fn test_explicit_stage() { assert!(!config.explicit_stage_from_config); assert!(!config.is_explicit_stage()); } + +#[test] +fn test_exclude() { + let exclude_path = "compiler"; + let config = parse(&format!("build.exclude=[\"{}\"]", exclude_path)); + + let first_excluded = config + .skip + .first() + .expect("Expected at least one excluded path") + .to_str() + .expect("Failed to convert excluded path to string"); + + assert_eq!(first_excluded, exclude_path); +} diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 98eff664a5b..3776dd13676 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -124,7 +124,7 @@ impl Config { if let Ok(in_nix_shell) = in_nix_shell { eprintln!( "The IN_NIX_SHELL environment variable is `{in_nix_shell}`; \ - you may need to set `patch-binaries-for-nix=true` in config.toml" + you may need to set `patch-binaries-for-nix=true` in bootstrap.toml" ); } } @@ -699,7 +699,7 @@ impl Config { help_on_error = "ERROR: failed to download pre-built rustc from CI NOTE: old builds get deleted after a certain time -HELP: if trying to compile an old commit of rustc, disable `download-rustc` in config.toml: +HELP: if trying to compile an old commit of rustc, disable `download-rustc` in bootstrap.toml: [rust] download-rustc = false @@ -783,7 +783,7 @@ download-rustc = false println!("HELP: Consider rebasing to a newer commit if available."); } Err(e) => { - eprintln!("ERROR: Failed to parse CI LLVM config.toml: {e}"); + eprintln!("ERROR: Failed to parse CI LLVM bootstrap.toml: {e}"); exit!(2); } }; @@ -816,7 +816,7 @@ download-rustc = false HELP: There could be two reasons behind this: 1) The host triple is not supported for `download-ci-llvm`. 2) Old builds get deleted after a certain time. - HELP: In either case, disable `download-ci-llvm` in your config.toml: + HELP: In either case, disable `download-ci-llvm` in your bootstrap.toml: [llvm] download-ci-llvm = false @@ -845,7 +845,7 @@ download-rustc = false HELP: There could be two reasons behind this: 1) The host triple is not supported for `download-ci-gcc`. 2) Old builds get deleted after a certain time. - HELP: In either case, disable `download-ci-gcc` in your config.toml: + HELP: In either case, disable `download-ci-gcc` in your bootstrap.toml: [gcc] download-ci-gcc = false diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 583b8e1198a..dbfebd11f82 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -153,7 +153,7 @@ pub fn check(build: &mut Build) { Couldn't find required command: cmake You should install cmake, or set `download-ci-llvm = true` in the -`[llvm]` section of `config.toml` to download LLVM rather +`[llvm]` section of `bootstrap.toml` to download LLVM rather than building it. " ); @@ -339,7 +339,7 @@ than building it. None => panic!( "when targeting MUSL either the rust.musl-root \ option or the target.$TARGET.musl-root option must \ - be specified in config.toml" + be specified in bootstrap.toml" ), } } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 91574f8bf5d..1fba17dcf30 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -143,7 +143,7 @@ pub enum GitRepo { /// organize). #[derive(Clone)] pub struct Build { - /// User-specified configuration from `config.toml`. + /// User-specified configuration from `bootstrap.toml`. config: Config, // Version information @@ -538,7 +538,7 @@ impl Build { /// This avoids contributors checking in a submodule change by accident. fn update_existing_submodules(&self) { // Avoid running git when there isn't a git checkout, or the user has - // explicitly disabled submodules in `config.toml`. + // explicitly disabled submodules in `bootstrap.toml`. if !self.config.submodules() { return; } @@ -671,7 +671,7 @@ impl Build { } /// Gets the space-separated set of activated features for the standard library. - /// This can be configured with the `std-features` key in config.toml. + /// This can be configured with the `std-features` key in bootstrap.toml. fn std_features(&self, target: TargetSelection) -> String { let mut features: BTreeSet<&str> = self.config.rust_std_features.iter().map(|s| s.as_str()).collect(); @@ -1925,7 +1925,7 @@ Couldn't find required command: ninja (or ninja-build) You should install ninja as described at <https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages>, -or set `ninja = false` in the `[llvm]` section of `config.toml`. +or set `ninja = false` in the `[llvm]` section of `bootstrap.toml`. Alternatively, set `download-ci-llvm = true` in that `[llvm]` section to download LLVM rather than building it. " diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs index 1e84a7deff1..147b009d3f4 100644 --- a/src/bootstrap/src/utils/cc_detect.rs +++ b/src/bootstrap/src/utils/cc_detect.rs @@ -4,8 +4,8 @@ //! C and C++ compilers for each target configured. A compiler is found through //! a number of vectors (in order of precedence) //! -//! 1. Configuration via `target.$target.cc` in `config.toml`. -//! 2. Configuration via `target.$target.android-ndk` in `config.toml`, if +//! 1. Configuration via `target.$target.cc` in `bootstrap.toml`. +//! 2. Configuration via `target.$target.android-ndk` in `bootstrap.toml`, if //! applicable //! 3. Special logic to probe on OpenBSD //! 4. The `CC_$target` environment variable. @@ -122,7 +122,7 @@ pub fn find(build: &Build) { /// Probes and configures the C and C++ compilers for a single target. /// -/// This function uses both user-specified configuration (from `config.toml`) and auto-detection +/// This function uses both user-specified configuration (from `bootstrap.toml`) and auto-detection /// logic to determine the correct C/C++ compilers for the target. It also determines the appropriate /// archiver (`ar`) and sets up additional compilation flags (both handled and unhandled). pub fn find_target(build: &Build, target: TargetSelection) { @@ -186,7 +186,7 @@ pub fn find_target(build: &Build, target: TargetSelection) { } /// Determines the default compiler for a given target and language when not explicitly -/// configured in `config.toml`. +/// configured in `bootstrap.toml`. fn default_compiler( cfg: &mut cc::Build, compiler: Language, @@ -195,7 +195,7 @@ fn default_compiler( ) -> Option<PathBuf> { match &*target.triple { // When compiling for android we may have the NDK configured in the - // config.toml in which case we look there. Otherwise the default + // bootstrap.toml in which case we look there. Otherwise the default // compiler already takes into account the triple in question. t if t.contains("android") => { build.config.android_ndk.as_ref().map(|ndk| ndk_compiler(compiler, &target.triple, ndk)) diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 8036c592108..1a101b02f70 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -380,4 +380,14 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Warning, summary: "Removed `src/tools/rls` tool as it was deprecated long time ago.", }, + ChangeInfo { + change_id: 137147, + severity: ChangeSeverity::Info, + summary: "Added new option `build.exclude` which works the same way as `--exclude` flag on `x`.", + }, + ChangeInfo { + change_id: 137081, + severity: ChangeSeverity::Warning, + summary: "The default configuration filename has changed from `config.toml` to `bootstrap.toml`. `config.toml` is deprecated but remains supported for backward compatibility.", + }, ]; diff --git a/src/ci/citool/src/analysis.rs b/src/ci/citool/src/analysis.rs new file mode 100644 index 00000000000..2088ce29620 --- /dev/null +++ b/src/ci/citool/src/analysis.rs @@ -0,0 +1,362 @@ +use std::collections::{BTreeMap, HashMap, HashSet}; + +use build_helper::metrics::{ + BuildStep, JsonRoot, TestOutcome, TestSuite, TestSuiteMetadata, format_build_steps, +}; + +use crate::metrics; +use crate::metrics::{JobMetrics, JobName, get_test_suites}; +use crate::utils::{output_details, pluralize}; + +pub fn output_bootstrap_stats(metrics: &JsonRoot) { + if !metrics.invocations.is_empty() { + println!("# Bootstrap steps"); + record_bootstrap_step_durations(&metrics); + record_test_suites(&metrics); + } +} + +fn record_bootstrap_step_durations(metrics: &JsonRoot) { + for invocation in &metrics.invocations { + let step = BuildStep::from_invocation(invocation); + let table = format_build_steps(&step); + eprintln!("Step `{}`\n{table}\n", invocation.cmdline); + output_details(&invocation.cmdline, || { + println!("<pre><code>{table}</code></pre>"); + }); + } + eprintln!("Recorded {} bootstrap invocation(s)", metrics.invocations.len()); +} + +fn record_test_suites(metrics: &JsonRoot) { + let suites = metrics::get_test_suites(&metrics); + + if !suites.is_empty() { + let aggregated = aggregate_test_suites(&suites); + let table = render_table(aggregated); + println!("\n# Test results\n"); + println!("{table}"); + } else { + eprintln!("No test suites found in metrics"); + } +} + +fn render_table(suites: BTreeMap<String, TestSuiteRecord>) -> String { + use std::fmt::Write; + + let mut table = "| Test suite | Passed ✅ | Ignored 🚫 | Failed ❌ |\n".to_string(); + writeln!(table, "|:------|------:|------:|------:|").unwrap(); + + fn compute_pct(value: f64, total: f64) -> f64 { + if total == 0.0 { 0.0 } else { value / total } + } + + fn write_row( + buffer: &mut String, + name: &str, + record: &TestSuiteRecord, + surround: &str, + ) -> std::fmt::Result { + let TestSuiteRecord { passed, ignored, failed } = record; + let total = (record.passed + record.ignored + record.failed) as f64; + let passed_pct = compute_pct(*passed as f64, total) * 100.0; + let ignored_pct = compute_pct(*ignored as f64, total) * 100.0; + let failed_pct = compute_pct(*failed as f64, total) * 100.0; + + write!(buffer, "| {surround}{name}{surround} |")?; + write!(buffer, " {surround}{passed} ({passed_pct:.0}%){surround} |")?; + write!(buffer, " {surround}{ignored} ({ignored_pct:.0}%){surround} |")?; + writeln!(buffer, " {surround}{failed} ({failed_pct:.0}%){surround} |")?; + + Ok(()) + } + + let mut total = TestSuiteRecord::default(); + for (name, record) in suites { + write_row(&mut table, &name, &record, "").unwrap(); + total.passed += record.passed; + total.ignored += record.ignored; + total.failed += record.failed; + } + write_row(&mut table, "Total", &total, "**").unwrap(); + table +} + +/// Computes a post merge CI analysis report of test differences +/// between the `parent` and `current` commits. +pub fn output_test_diffs(job_metrics: HashMap<JobName, JobMetrics>) { + let aggregated_test_diffs = aggregate_test_diffs(&job_metrics); + report_test_diffs(aggregated_test_diffs); +} + +#[derive(Default)] +struct TestSuiteRecord { + passed: u64, + ignored: u64, + failed: u64, +} + +fn test_metadata_name(metadata: &TestSuiteMetadata) -> String { + match metadata { + TestSuiteMetadata::CargoPackage { crates, stage, .. } => { + format!("{} (stage {stage})", crates.join(", ")) + } + TestSuiteMetadata::Compiletest { suite, stage, .. } => { + format!("{suite} (stage {stage})") + } + } +} + +fn aggregate_test_suites(suites: &[&TestSuite]) -> BTreeMap<String, TestSuiteRecord> { + let mut records: BTreeMap<String, TestSuiteRecord> = BTreeMap::new(); + for suite in suites { + let name = test_metadata_name(&suite.metadata); + let record = records.entry(name).or_default(); + for test in &suite.tests { + match test.outcome { + TestOutcome::Passed => { + record.passed += 1; + } + TestOutcome::Failed => { + record.failed += 1; + } + TestOutcome::Ignored { .. } => { + record.ignored += 1; + } + } + } + } + records +} + +/// Represents a difference in the outcome of tests between a base and a current commit. +/// Maps test diffs to jobs that contained them. +#[derive(Debug)] +struct AggregatedTestDiffs { + diffs: HashMap<TestDiff, Vec<JobName>>, +} + +fn aggregate_test_diffs(jobs: &HashMap<JobName, JobMetrics>) -> AggregatedTestDiffs { + let mut diffs: HashMap<TestDiff, Vec<JobName>> = HashMap::new(); + + // Aggregate test suites + for (name, metrics) in jobs { + if let Some(parent) = &metrics.parent { + let tests_parent = aggregate_tests(parent); + let tests_current = aggregate_tests(&metrics.current); + for diff in calculate_test_diffs(tests_parent, tests_current) { + diffs.entry(diff).or_default().push(name.to_string()); + } + } + } + + AggregatedTestDiffs { diffs } +} + +#[derive(Eq, PartialEq, Hash, Debug)] +enum TestOutcomeDiff { + ChangeOutcome { before: TestOutcome, after: TestOutcome }, + Missing { before: TestOutcome }, + Added(TestOutcome), +} + +#[derive(Eq, PartialEq, Hash, Debug)] +struct TestDiff { + test: Test, + diff: TestOutcomeDiff, +} + +fn calculate_test_diffs(parent: TestSuiteData, current: TestSuiteData) -> HashSet<TestDiff> { + let mut diffs = HashSet::new(); + for (test, outcome) in ¤t.tests { + match parent.tests.get(test) { + Some(before) => { + if before != outcome { + diffs.insert(TestDiff { + test: test.clone(), + diff: TestOutcomeDiff::ChangeOutcome { + before: before.clone(), + after: outcome.clone(), + }, + }); + } + } + None => { + diffs.insert(TestDiff { + test: test.clone(), + diff: TestOutcomeDiff::Added(outcome.clone()), + }); + } + } + } + for (test, outcome) in &parent.tests { + if !current.tests.contains_key(test) { + diffs.insert(TestDiff { + test: test.clone(), + diff: TestOutcomeDiff::Missing { before: outcome.clone() }, + }); + } + } + + diffs +} + +/// Aggregates test suite executions from all bootstrap invocations in a given CI job. +#[derive(Default)] +struct TestSuiteData { + tests: HashMap<Test, TestOutcome>, +} + +#[derive(Hash, PartialEq, Eq, Debug, Clone)] +struct Test { + name: String, + is_doctest: bool, +} + +/// Extracts all tests from the passed metrics and map them to their outcomes. +fn aggregate_tests(metrics: &JsonRoot) -> TestSuiteData { + let mut tests = HashMap::new(); + let test_suites = get_test_suites(&metrics); + for suite in test_suites { + for test in &suite.tests { + // Poor man's detection of doctests based on the "(line XYZ)" suffix + let is_doctest = matches!(suite.metadata, TestSuiteMetadata::CargoPackage { .. }) + && test.name.contains("(line"); + let test_entry = Test { name: generate_test_name(&test.name, &suite), is_doctest }; + tests.insert(test_entry, test.outcome.clone()); + } + } + TestSuiteData { tests } +} + +/// Normalizes Windows-style path delimiters to Unix-style paths +/// and adds suite metadata to the test name. +fn generate_test_name(name: &str, suite: &TestSuite) -> String { + let name = name.replace('\\', "/"); + let stage = match suite.metadata { + TestSuiteMetadata::CargoPackage { stage, .. } => stage, + TestSuiteMetadata::Compiletest { stage, .. } => stage, + }; + + format!("{name} (stage {stage})") +} + +/// Prints test changes in Markdown format to stdout. +fn report_test_diffs(diff: AggregatedTestDiffs) { + println!("# Test differences"); + if diff.diffs.is_empty() { + println!("No test diffs found"); + return; + } + + fn format_outcome(outcome: &TestOutcome) -> String { + match outcome { + TestOutcome::Passed => "pass".to_string(), + TestOutcome::Failed => "fail".to_string(), + TestOutcome::Ignored { ignore_reason } => { + let reason = match ignore_reason { + Some(reason) => format!(" ({reason})"), + None => String::new(), + }; + format!("ignore{reason}") + } + } + } + + fn format_diff(diff: &TestOutcomeDiff) -> String { + match diff { + TestOutcomeDiff::ChangeOutcome { before, after } => { + format!("{} -> {}", format_outcome(before), format_outcome(after)) + } + TestOutcomeDiff::Missing { before } => { + format!("{} -> [missing]", format_outcome(before)) + } + TestOutcomeDiff::Added(outcome) => { + format!("[missing] -> {}", format_outcome(outcome)) + } + } + } + + fn format_job_group(group: u64) -> String { + format!("**J{group}**") + } + + // It would be quite noisy to repeat the jobs that contained the test changes after/next to + // every test diff. At the same time, grouping the test diffs by + // [unique set of jobs that contained them] also doesn't work well, because the test diffs + // would have to be duplicated several times. + // Instead, we create a set of unique job groups, and then print a job group after each test. + // We then print the job groups at the end, as a sort of index. + let mut grouped_diffs: Vec<(&TestDiff, u64)> = vec![]; + let mut job_list_to_group: HashMap<&[JobName], u64> = HashMap::new(); + let mut job_index: Vec<&[JobName]> = vec![]; + + let original_diff_count = diff.diffs.len(); + let diffs = diff + .diffs + .into_iter() + .filter(|(diff, _)| !diff.test.is_doctest) + .map(|(diff, mut jobs)| { + jobs.sort(); + (diff, jobs) + }) + .collect::<Vec<_>>(); + let doctest_count = original_diff_count.saturating_sub(diffs.len()); + + let max_diff_count = 100; + for (diff, jobs) in diffs.iter().take(max_diff_count) { + let jobs = &*jobs; + let job_group = match job_list_to_group.get(jobs.as_slice()) { + Some(id) => *id, + None => { + let id = job_index.len() as u64; + job_index.push(jobs); + job_list_to_group.insert(jobs, id); + id + } + }; + grouped_diffs.push((diff, job_group)); + } + + // Sort diffs by job group and test name + grouped_diffs.sort_by(|(d1, g1), (d2, g2)| g1.cmp(&g2).then(d1.test.name.cmp(&d2.test.name))); + + output_details( + &format!("Show {} test {}\n", original_diff_count, pluralize("diff", original_diff_count)), + || { + for (diff, job_group) in grouped_diffs { + println!( + "- `{}`: {} ({})", + diff.test.name, + format_diff(&diff.diff), + format_job_group(job_group) + ); + } + + let extra_diffs = diffs.len().saturating_sub(max_diff_count); + if extra_diffs > 0 { + println!( + "\n(and {extra_diffs} additional {})", + pluralize("test diff", extra_diffs) + ); + } + + if doctest_count > 0 { + println!( + "\nAdditionally, {doctest_count} doctest {} were found. These are ignored, as they are noisy.", + pluralize("diff", doctest_count) + ); + } + + // Now print the job group index + println!("\n**Job group index**\n"); + for (group, jobs) in job_index.into_iter().enumerate() { + println!( + "- {}: {}", + format_job_group(group as u64), + jobs.iter().map(|j| format!("`{j}`")).collect::<Vec<_>>().join(", ") + ); + } + }, + ); +} diff --git a/src/ci/citool/src/jobs.rs b/src/ci/citool/src/jobs.rs index 0de8b740227..13880ad466a 100644 --- a/src/ci/citool/src/jobs.rs +++ b/src/ci/citool/src/jobs.rs @@ -185,6 +185,20 @@ fn calculate_jobs( env.extend(crate::yaml_map_to_json(&job.env)); let full_name = format!("{prefix} - {}", job.name); + // When the default `@bors try` job is executed (which is usually done + // for benchmarking performance, running crater or for downloading the + // built toolchain using `rustup-toolchain-install-master`), + // we inject the `DIST_TRY_BUILD` environment variable to the jobs + // to tell `opt-dist` to make the build faster by skipping certain steps. + if let RunType::TryJob { job_patterns } = run_type { + if job_patterns.is_none() { + env.insert( + "DIST_TRY_BUILD".to_string(), + serde_json::value::Value::Number(1.into()), + ); + } + } + GithubActionsJob { name: job.name, full_name, diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index cd690ebeb06..5a84ecb5e47 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -1,24 +1,25 @@ +mod analysis; mod cpu_usage; mod datadog; mod jobs; -mod merge_report; mod metrics; mod utils; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashMap}; use std::path::{Path, PathBuf}; use std::process::Command; +use analysis::output_bootstrap_stats; use anyhow::Context; use clap::Parser; use jobs::JobDatabase; use serde_yaml::Value; +use crate::analysis::output_test_diffs; use crate::cpu_usage::load_cpu_usage; use crate::datadog::upload_datadog_metric; use crate::jobs::RunType; -use crate::merge_report::post_merge_report; -use crate::metrics::postprocess_metrics; +use crate::metrics::{JobMetrics, download_auto_job_metrics, download_job_metrics, load_metrics}; use crate::utils::load_env_var; const CI_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/.."); @@ -137,6 +138,49 @@ fn upload_ci_metrics(cpu_usage_csv: &Path) -> anyhow::Result<()> { Ok(()) } +fn postprocess_metrics( + metrics_path: PathBuf, + parent: Option<String>, + job_name: Option<String>, +) -> anyhow::Result<()> { + let metrics = load_metrics(&metrics_path)?; + output_bootstrap_stats(&metrics); + + let (Some(parent), Some(job_name)) = (parent, job_name) else { + return Ok(()); + }; + + // This command is executed also on PR builds, which might not have parent metrics + // available, because some PR jobs don't run on auto builds, and PR jobs do not upload metrics + // due to missing permissions. + // To avoid having to detect if this is a PR job, and to avoid having failed steps in PR jobs, + // we simply print an error if the parent metrics were not found, but otherwise exit + // successfully. + match download_job_metrics(&job_name, &parent).context("cannot download parent metrics") { + Ok(parent_metrics) => { + let job_metrics = HashMap::from([( + job_name, + JobMetrics { parent: Some(parent_metrics), current: metrics }, + )]); + output_test_diffs(job_metrics); + } + Err(error) => { + eprintln!("Metrics for job `{job_name}` and commit `{parent}` not found: {error:?}"); + } + } + + Ok(()) +} + +fn post_merge_report(db: JobDatabase, current: String, parent: String) -> anyhow::Result<()> { + let metrics = download_auto_job_metrics(&db, &parent, ¤t)?; + + println!("\nComparing {parent} (parent) -> {current} (this PR)\n"); + output_test_diffs(metrics); + + Ok(()) +} + #[derive(clap::Parser)] enum Args { /// Calculate a list of jobs that should be executed on CI. @@ -154,13 +198,19 @@ enum Args { #[clap(long = "type", default_value = "auto")] job_type: JobType, }, - /// Postprocess the metrics.json file generated by bootstrap. + /// Postprocess the metrics.json file generated by bootstrap and output + /// various statistics. + /// If `--parent` and `--job-name` are provided, also display a diff + /// against previous metrics that are downloaded from CI. PostprocessMetrics { /// Path to the metrics.json file metrics_path: PathBuf, - /// Path to a file where the postprocessed metrics summary will be stored. - /// Usually, this will be GITHUB_STEP_SUMMARY on CI. - summary_path: PathBuf, + /// A parent SHA against which to compare. + #[clap(long, requires("job_name"))] + parent: Option<String>, + /// The name of the current job. + #[clap(long, requires("parent"))] + job_name: Option<String>, }, /// Upload CI metrics to Datadog. UploadBuildMetrics { @@ -211,11 +261,11 @@ fn main() -> anyhow::Result<()> { Args::UploadBuildMetrics { cpu_usage_csv } => { upload_ci_metrics(&cpu_usage_csv)?; } - Args::PostprocessMetrics { metrics_path, summary_path } => { - postprocess_metrics(&metrics_path, &summary_path)?; + Args::PostprocessMetrics { metrics_path, parent, job_name } => { + postprocess_metrics(metrics_path, parent, job_name)?; } - Args::PostMergeReport { current: commit, parent } => { - post_merge_report(load_db(default_jobs_file)?, parent, commit)?; + Args::PostMergeReport { current, parent } => { + post_merge_report(load_db(default_jobs_file)?, current, parent)?; } } diff --git a/src/ci/citool/src/merge_report.rs b/src/ci/citool/src/merge_report.rs deleted file mode 100644 index 62daa2e6853..00000000000 --- a/src/ci/citool/src/merge_report.rs +++ /dev/null @@ -1,318 +0,0 @@ -use std::collections::{HashMap, HashSet}; -use std::path::PathBuf; - -use anyhow::Context; -use build_helper::metrics::{JsonRoot, TestOutcome, TestSuiteMetadata}; - -use crate::jobs::JobDatabase; -use crate::metrics::get_test_suites; - -type Sha = String; -type JobName = String; - -/// Computes a post merge CI analysis report between the `parent` and `current` commits. -pub fn post_merge_report(job_db: JobDatabase, parent: Sha, current: Sha) -> anyhow::Result<()> { - let jobs = download_all_metrics(&job_db, &parent, ¤t)?; - let aggregated_test_diffs = aggregate_test_diffs(&jobs)?; - - println!("Comparing {parent} (base) -> {current} (this PR)\n"); - report_test_diffs(aggregated_test_diffs); - - Ok(()) -} - -struct JobMetrics { - parent: Option<JsonRoot>, - current: JsonRoot, -} - -/// Download before/after metrics for all auto jobs in the job database. -fn download_all_metrics( - job_db: &JobDatabase, - parent: &str, - current: &str, -) -> anyhow::Result<HashMap<JobName, JobMetrics>> { - let mut jobs = HashMap::default(); - - for job in &job_db.auto_jobs { - eprintln!("Downloading metrics of job {}", job.name); - let metrics_parent = match download_job_metrics(&job.name, parent) { - Ok(metrics) => Some(metrics), - Err(error) => { - eprintln!( - r#"Did not find metrics for job `{}` at `{}`: {error:?}. -Maybe it was newly added?"#, - job.name, parent - ); - None - } - }; - let metrics_current = download_job_metrics(&job.name, current)?; - jobs.insert( - job.name.clone(), - JobMetrics { parent: metrics_parent, current: metrics_current }, - ); - } - Ok(jobs) -} - -/// Downloads job metrics of the given job for the given commit. -/// Caches the result on the local disk. -fn download_job_metrics(job_name: &str, sha: &str) -> anyhow::Result<JsonRoot> { - let cache_path = PathBuf::from(".citool-cache").join(sha).join(job_name).join("metrics.json"); - if let Some(cache_entry) = - std::fs::read_to_string(&cache_path).ok().and_then(|data| serde_json::from_str(&data).ok()) - { - return Ok(cache_entry); - } - - let url = get_metrics_url(job_name, sha); - let mut response = ureq::get(&url).call()?; - if !response.status().is_success() { - return Err(anyhow::anyhow!( - "Cannot fetch metrics from {url}: {}\n{}", - response.status(), - response.body_mut().read_to_string()? - )); - } - let data: JsonRoot = response - .body_mut() - .read_json() - .with_context(|| anyhow::anyhow!("cannot deserialize metrics from {url}"))?; - - // Ignore errors if cache cannot be created - if std::fs::create_dir_all(cache_path.parent().unwrap()).is_ok() { - if let Ok(serialized) = serde_json::to_string(&data) { - let _ = std::fs::write(&cache_path, &serialized); - } - } - Ok(data) -} - -fn get_metrics_url(job_name: &str, sha: &str) -> String { - let suffix = if job_name.ends_with("-alt") { "-alt" } else { "" }; - format!("https://ci-artifacts.rust-lang.org/rustc-builds{suffix}/{sha}/metrics-{job_name}.json") -} - -/// Represents a difference in the outcome of tests between a base and a current commit. -/// Maps test diffs to jobs that contained them. -#[derive(Debug)] -struct AggregatedTestDiffs { - diffs: HashMap<TestDiff, Vec<JobName>>, -} - -fn aggregate_test_diffs( - jobs: &HashMap<JobName, JobMetrics>, -) -> anyhow::Result<AggregatedTestDiffs> { - let mut diffs: HashMap<TestDiff, Vec<JobName>> = HashMap::new(); - - // Aggregate test suites - for (name, metrics) in jobs { - if let Some(parent) = &metrics.parent { - let tests_parent = aggregate_tests(parent); - let tests_current = aggregate_tests(&metrics.current); - for diff in calculate_test_diffs(tests_parent, tests_current) { - diffs.entry(diff).or_default().push(name.to_string()); - } - } - } - - Ok(AggregatedTestDiffs { diffs }) -} - -#[derive(Eq, PartialEq, Hash, Debug)] -enum TestOutcomeDiff { - ChangeOutcome { before: TestOutcome, after: TestOutcome }, - Missing { before: TestOutcome }, - Added(TestOutcome), -} - -#[derive(Eq, PartialEq, Hash, Debug)] -struct TestDiff { - test: Test, - diff: TestOutcomeDiff, -} - -fn calculate_test_diffs(parent: TestSuiteData, current: TestSuiteData) -> HashSet<TestDiff> { - let mut diffs = HashSet::new(); - for (test, outcome) in ¤t.tests { - match parent.tests.get(test) { - Some(before) => { - if before != outcome { - diffs.insert(TestDiff { - test: test.clone(), - diff: TestOutcomeDiff::ChangeOutcome { - before: before.clone(), - after: outcome.clone(), - }, - }); - } - } - None => { - diffs.insert(TestDiff { - test: test.clone(), - diff: TestOutcomeDiff::Added(outcome.clone()), - }); - } - } - } - for (test, outcome) in &parent.tests { - if !current.tests.contains_key(test) { - diffs.insert(TestDiff { - test: test.clone(), - diff: TestOutcomeDiff::Missing { before: outcome.clone() }, - }); - } - } - - diffs -} - -/// Aggregates test suite executions from all bootstrap invocations in a given CI job. -#[derive(Default)] -struct TestSuiteData { - tests: HashMap<Test, TestOutcome>, -} - -#[derive(Hash, PartialEq, Eq, Debug, Clone)] -struct Test { - name: String, - is_doctest: bool, -} - -/// Extracts all tests from the passed metrics and map them to their outcomes. -fn aggregate_tests(metrics: &JsonRoot) -> TestSuiteData { - let mut tests = HashMap::new(); - let test_suites = get_test_suites(&metrics); - for suite in test_suites { - for test in &suite.tests { - // Poor man's detection of doctests based on the "(line XYZ)" suffix - let is_doctest = matches!(suite.metadata, TestSuiteMetadata::CargoPackage { .. }) - && test.name.contains("(line"); - let test_entry = Test { name: normalize_test_name(&test.name), is_doctest }; - tests.insert(test_entry, test.outcome.clone()); - } - } - TestSuiteData { tests } -} - -/// Normalizes Windows-style path delimiters to Unix-style paths. -fn normalize_test_name(name: &str) -> String { - name.replace('\\', "/") -} - -/// Prints test changes in Markdown format to stdout. -fn report_test_diffs(diff: AggregatedTestDiffs) { - println!("## Test differences"); - if diff.diffs.is_empty() { - println!("No test diffs found"); - return; - } - - fn format_outcome(outcome: &TestOutcome) -> String { - match outcome { - TestOutcome::Passed => "pass".to_string(), - TestOutcome::Failed => "fail".to_string(), - TestOutcome::Ignored { ignore_reason } => { - let reason = match ignore_reason { - Some(reason) => format!(" ({reason})"), - None => String::new(), - }; - format!("ignore{reason}") - } - } - } - - fn format_diff(diff: &TestOutcomeDiff) -> String { - match diff { - TestOutcomeDiff::ChangeOutcome { before, after } => { - format!("{} -> {}", format_outcome(before), format_outcome(after)) - } - TestOutcomeDiff::Missing { before } => { - format!("{} -> [missing]", format_outcome(before)) - } - TestOutcomeDiff::Added(outcome) => { - format!("[missing] -> {}", format_outcome(outcome)) - } - } - } - - fn format_job_group(group: u64) -> String { - format!("**J{group}**") - } - - // It would be quite noisy to repeat the jobs that contained the test changes after/next to - // every test diff. At the same time, grouping the test diffs by - // [unique set of jobs that contained them] also doesn't work well, because the test diffs - // would have to be duplicated several times. - // Instead, we create a set of unique job groups, and then print a job group after each test. - // We then print the job groups at the end, as a sort of index. - let mut grouped_diffs: Vec<(&TestDiff, u64)> = vec![]; - let mut job_list_to_group: HashMap<&[JobName], u64> = HashMap::new(); - let mut job_index: Vec<&[JobName]> = vec![]; - - let original_diff_count = diff.diffs.len(); - let diffs = diff - .diffs - .into_iter() - .filter(|(diff, _)| !diff.test.is_doctest) - .map(|(diff, mut jobs)| { - jobs.sort(); - (diff, jobs) - }) - .collect::<Vec<_>>(); - let doctest_count = original_diff_count.saturating_sub(diffs.len()); - - let max_diff_count = 100; - for (diff, jobs) in diffs.iter().take(max_diff_count) { - let jobs = &*jobs; - let job_group = match job_list_to_group.get(jobs.as_slice()) { - Some(id) => *id, - None => { - let id = job_index.len() as u64; - job_index.push(jobs); - job_list_to_group.insert(jobs, id); - id - } - }; - grouped_diffs.push((diff, job_group)); - } - - // Sort diffs by job group and test name - grouped_diffs.sort_by(|(d1, g1), (d2, g2)| g1.cmp(&g2).then(d1.test.name.cmp(&d2.test.name))); - - for (diff, job_group) in grouped_diffs { - println!( - "- `{}`: {} ({})", - diff.test.name, - format_diff(&diff.diff), - format_job_group(job_group) - ); - } - - let extra_diffs = diffs.len().saturating_sub(max_diff_count); - if extra_diffs > 0 { - println!("\n(and {extra_diffs} additional {})", pluralize("test diff", extra_diffs)); - } - - if doctest_count > 0 { - println!( - "\nAdditionally, {doctest_count} doctest {} were found. These are ignored, as they are noisy.", - pluralize("diff", doctest_count) - ); - } - - // Now print the job group index - println!("\n**Job group index**\n"); - for (group, jobs) in job_index.into_iter().enumerate() { - println!( - "- {}: {}", - format_job_group(group as u64), - jobs.iter().map(|j| format!("`{j}`")).collect::<Vec<_>>().join(", ") - ); - } -} - -fn pluralize(text: &str, count: usize) -> String { - if count == 1 { text.to_string() } else { format!("{text}s") } -} diff --git a/src/ci/citool/src/metrics.rs b/src/ci/citool/src/metrics.rs index 83b3d5ceed0..086aa5009f3 100644 --- a/src/ci/citool/src/metrics.rs +++ b/src/ci/citool/src/metrics.rs @@ -1,146 +1,12 @@ -use std::collections::BTreeMap; -use std::fs::File; -use std::io::Write; +use std::collections::HashMap; use std::path::Path; use anyhow::Context; -use build_helper::metrics::{ - BuildStep, JsonNode, JsonRoot, TestOutcome, TestSuite, TestSuiteMetadata, format_build_steps, -}; +use build_helper::metrics::{JsonNode, JsonRoot, TestSuite}; -pub fn postprocess_metrics(metrics_path: &Path, summary_path: &Path) -> anyhow::Result<()> { - let metrics = load_metrics(metrics_path)?; +use crate::jobs::JobDatabase; - let mut file = File::options() - .append(true) - .create(true) - .open(summary_path) - .with_context(|| format!("Cannot open summary file at {summary_path:?}"))?; - - if !metrics.invocations.is_empty() { - writeln!(file, "# Bootstrap steps")?; - record_bootstrap_step_durations(&metrics, &mut file)?; - record_test_suites(&metrics, &mut file)?; - } - - Ok(()) -} - -fn record_bootstrap_step_durations(metrics: &JsonRoot, file: &mut File) -> anyhow::Result<()> { - for invocation in &metrics.invocations { - let step = BuildStep::from_invocation(invocation); - let table = format_build_steps(&step); - eprintln!("Step `{}`\n{table}\n", invocation.cmdline); - writeln!( - file, - r"<details> -<summary>{}</summary> -<pre><code>{table}</code></pre> -</details> -", - invocation.cmdline - )?; - } - eprintln!("Recorded {} bootstrap invocation(s)", metrics.invocations.len()); - - Ok(()) -} - -fn record_test_suites(metrics: &JsonRoot, file: &mut File) -> anyhow::Result<()> { - let suites = get_test_suites(&metrics); - - if !suites.is_empty() { - let aggregated = aggregate_test_suites(&suites); - let table = render_table(aggregated); - writeln!(file, "\n# Test results\n")?; - writeln!(file, "{table}")?; - } else { - eprintln!("No test suites found in metrics"); - } - - Ok(()) -} - -fn render_table(suites: BTreeMap<String, TestSuiteRecord>) -> String { - use std::fmt::Write; - - let mut table = "| Test suite | Passed ✅ | Ignored 🚫 | Failed ❌ |\n".to_string(); - writeln!(table, "|:------|------:|------:|------:|").unwrap(); - - fn compute_pct(value: f64, total: f64) -> f64 { - if total == 0.0 { 0.0 } else { value / total } - } - - fn write_row( - buffer: &mut String, - name: &str, - record: &TestSuiteRecord, - surround: &str, - ) -> std::fmt::Result { - let TestSuiteRecord { passed, ignored, failed } = record; - let total = (record.passed + record.ignored + record.failed) as f64; - let passed_pct = compute_pct(*passed as f64, total) * 100.0; - let ignored_pct = compute_pct(*ignored as f64, total) * 100.0; - let failed_pct = compute_pct(*failed as f64, total) * 100.0; - - write!(buffer, "| {surround}{name}{surround} |")?; - write!(buffer, " {surround}{passed} ({passed_pct:.0}%){surround} |")?; - write!(buffer, " {surround}{ignored} ({ignored_pct:.0}%){surround} |")?; - writeln!(buffer, " {surround}{failed} ({failed_pct:.0}%){surround} |")?; - - Ok(()) - } - - let mut total = TestSuiteRecord::default(); - for (name, record) in suites { - write_row(&mut table, &name, &record, "").unwrap(); - total.passed += record.passed; - total.ignored += record.ignored; - total.failed += record.failed; - } - write_row(&mut table, "Total", &total, "**").unwrap(); - table -} - -#[derive(Default)] -struct TestSuiteRecord { - passed: u64, - ignored: u64, - failed: u64, -} - -fn test_metadata_name(metadata: &TestSuiteMetadata) -> String { - match metadata { - TestSuiteMetadata::CargoPackage { crates, stage, .. } => { - format!("{} (stage {stage})", crates.join(", ")) - } - TestSuiteMetadata::Compiletest { suite, stage, .. } => { - format!("{suite} (stage {stage})") - } - } -} - -fn aggregate_test_suites(suites: &[&TestSuite]) -> BTreeMap<String, TestSuiteRecord> { - let mut records: BTreeMap<String, TestSuiteRecord> = BTreeMap::new(); - for suite in suites { - let name = test_metadata_name(&suite.metadata); - let record = records.entry(name).or_default(); - for test in &suite.tests { - match test.outcome { - TestOutcome::Passed => { - record.passed += 1; - } - TestOutcome::Failed => { - record.failed += 1; - } - TestOutcome::Ignored { .. } => { - record.ignored += 1; - } - } - } - } - records -} +pub type JobName = String; pub fn get_test_suites(metrics: &JsonRoot) -> Vec<&TestSuite> { fn visit_test_suites<'a>(nodes: &'a [JsonNode], suites: &mut Vec<&'a TestSuite>) { @@ -163,10 +29,68 @@ pub fn get_test_suites(metrics: &JsonRoot) -> Vec<&TestSuite> { suites } -fn load_metrics(path: &Path) -> anyhow::Result<JsonRoot> { +pub fn load_metrics(path: &Path) -> anyhow::Result<JsonRoot> { let metrics = std::fs::read_to_string(path) .with_context(|| format!("Cannot read JSON metrics from {path:?}"))?; let metrics: JsonRoot = serde_json::from_str(&metrics) .with_context(|| format!("Cannot deserialize JSON metrics from {path:?}"))?; Ok(metrics) } + +pub struct JobMetrics { + pub parent: Option<JsonRoot>, + pub current: JsonRoot, +} + +/// Download before/after metrics for all auto jobs in the job database. +/// `parent` and `current` should be commit SHAs. +pub fn download_auto_job_metrics( + job_db: &JobDatabase, + parent: &str, + current: &str, +) -> anyhow::Result<HashMap<JobName, JobMetrics>> { + let mut jobs = HashMap::default(); + + for job in &job_db.auto_jobs { + eprintln!("Downloading metrics of job {}", job.name); + let metrics_parent = match download_job_metrics(&job.name, parent) { + Ok(metrics) => Some(metrics), + Err(error) => { + eprintln!( + r#"Did not find metrics for job `{}` at `{parent}`: {error:?}. +Maybe it was newly added?"#, + job.name + ); + None + } + }; + let metrics_current = download_job_metrics(&job.name, current)?; + jobs.insert( + job.name.clone(), + JobMetrics { parent: metrics_parent, current: metrics_current }, + ); + } + Ok(jobs) +} + +pub fn download_job_metrics(job_name: &str, sha: &str) -> anyhow::Result<JsonRoot> { + let url = get_metrics_url(job_name, sha); + let mut response = ureq::get(&url).call()?; + if !response.status().is_success() { + return Err(anyhow::anyhow!( + "Cannot fetch metrics from {url}: {}\n{}", + response.status(), + response.body_mut().read_to_string()? + )); + } + let data: JsonRoot = response + .body_mut() + .read_json() + .with_context(|| anyhow::anyhow!("cannot deserialize metrics from {url}"))?; + Ok(data) +} + +fn get_metrics_url(job_name: &str, sha: &str) -> String { + let suffix = if job_name.ends_with("-alt") { "-alt" } else { "" }; + format!("https://ci-artifacts.rust-lang.org/rustc-builds{suffix}/{sha}/metrics-{job_name}.json") +} diff --git a/src/ci/citool/src/utils.rs b/src/ci/citool/src/utils.rs index 9cc220987bd..b9b1bf4d455 100644 --- a/src/ci/citool/src/utils.rs +++ b/src/ci/citool/src/utils.rs @@ -9,3 +9,23 @@ pub fn load_env_var(name: &str) -> anyhow::Result<String> { pub fn read_to_string<P: AsRef<Path>>(path: P) -> anyhow::Result<String> { std::fs::read_to_string(&path).with_context(|| format!("Cannot read file {:?}", path.as_ref())) } + +pub fn pluralize(text: &str, count: usize) -> String { + if count == 1 { text.to_string() } else { format!("{text}s") } +} + +/// Outputs a HTML <details> section with the provided summary. +/// Output printed by `func` will be contained within the section. +pub fn output_details<F>(summary: &str, func: F) +where + F: FnOnce(), +{ + println!( + r"<details> +<summary>{summary}</summary> + +" + ); + func(); + println!("</details>\n"); +} diff --git a/src/ci/citool/tests/jobs.rs b/src/ci/citool/tests/jobs.rs index 788f5e7e4f6..c644f885be3 100644 --- a/src/ci/citool/tests/jobs.rs +++ b/src/ci/citool/tests/jobs.rs @@ -14,10 +14,10 @@ fn auto_jobs() { #[test] fn try_jobs() { let stdout = get_matrix("push", "commit", "refs/heads/try"); - insta::assert_snapshot!(stdout, @r#" + insta::assert_snapshot!(stdout, @r###" jobs=[{"name":"dist-x86_64-linux","full_name":"try - dist-x86_64-linux","os":"ubuntu-22.04-16core-64gb","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_TRY_BUILD":1,"TOOLSTATE_PUBLISH":1}}] run_type=try - "#); + "###); } #[test] @@ -30,10 +30,10 @@ try-job: aarch64-gnu try-job: dist-i686-msvc"#, "refs/heads/try", ); - insta::assert_snapshot!(stdout, @r#" - jobs=[{"name":"aarch64-gnu","full_name":"try - aarch64-gnu","os":"ubuntu-22.04-arm","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","DIST_TRY_BUILD":1,"TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"dist-i686-msvc","full_name":"try - dist-i686-msvc","os":"windows-2022","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_REQUIRE_ALL_TOOLS":1,"DIST_TRY_BUILD":1,"RUST_CONFIGURE_ARGS":"--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler","SCRIPT":"python x.py dist bootstrap --include-default-paths","TOOLSTATE_PUBLISH":1}}] + insta::assert_snapshot!(stdout, @r###" + jobs=[{"name":"aarch64-gnu","full_name":"try - aarch64-gnu","os":"ubuntu-22.04-arm","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","DEPLOY_BUCKET":"rust-lang-ci2","TOOLSTATE_PUBLISH":1},"free_disk":true},{"name":"dist-i686-msvc","full_name":"try - dist-i686-msvc","os":"windows-2022","env":{"ARTIFACTS_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZN24CBO55","AWS_REGION":"us-west-1","CACHES_AWS_ACCESS_KEY_ID":"AKIA46X5W6CZI5DHEBFL","CODEGEN_BACKENDS":"llvm,cranelift","DEPLOY_BUCKET":"rust-lang-ci2","DIST_REQUIRE_ALL_TOOLS":1,"RUST_CONFIGURE_ARGS":"--build=i686-pc-windows-msvc --host=i686-pc-windows-msvc --target=i686-pc-windows-msvc,i586-pc-windows-msvc --enable-full-tools --enable-profiler","SCRIPT":"python x.py dist bootstrap --include-default-paths","TOOLSTATE_PUBLISH":1}}] run_type=try - "#); + "###); } #[test] diff --git a/src/ci/citool/tests/test-jobs.yml b/src/ci/citool/tests/test-jobs.yml index ff4d1772f59..3593b3f7df6 100644 --- a/src/ci/citool/tests/test-jobs.yml +++ b/src/ci/citool/tests/test-jobs.yml @@ -53,13 +53,6 @@ envs: try: <<: *production - # The following env var activates faster `try` builds in `opt-dist` by, e.g. - # - building only the more commonly useful components (we rarely need e.g. rust-docs in try - # builds) - # - not running `opt-dist`'s post-optimization smoke tests on the resulting toolchain - # - # If you *want* these to happen however, temporarily comment it before triggering a try build. - DIST_TRY_BUILD: 1 auto: <<: *production diff --git a/src/ci/docker/host-x86_64/dist-ohos/Dockerfile b/src/ci/docker/host-x86_64/dist-ohos/Dockerfile index bbbf0b3adf2..2c514fa0d4d 100644 --- a/src/ci/docker/host-x86_64/dist-ohos/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-ohos/Dockerfile @@ -22,6 +22,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ COPY scripts/ohos-sdk.sh /scripts/ RUN sh /scripts/ohos-sdk.sh +COPY scripts/ohos-openssl.sh /scripts/ +RUN sh /scripts/ohos-openssl.sh + COPY scripts/ohos/aarch64-unknown-linux-ohos-clang.sh /usr/local/bin/ COPY scripts/ohos/aarch64-unknown-linux-ohos-clang++.sh /usr/local/bin/ COPY scripts/ohos/armv7-unknown-linux-ohos-clang.sh /usr/local/bin/ @@ -30,6 +33,14 @@ COPY scripts/ohos/x86_64-unknown-linux-ohos-clang.sh /usr/local/bin/ COPY scripts/ohos/x86_64-unknown-linux-ohos-clang++.sh /usr/local/bin/ # env +ENV AARCH64_UNKNOWN_LINUX_OHOS_OPENSSL_DIR=/opt/ohos-openssl/prelude/arm64-v8a +ENV ARMV7_UNKNOWN_LINUX_OHOS_OPENSSL_DIR=/opt/ohos-openssl/prelude/armeabi-v7a +ENV X86_64_UNKNOWN_LINUX_OHOS_OPENSSL_DIR=/opt/ohos-openssl/prelude/x86_64 + +ENV AARCH64_UNKNOWN_LINUX_OHOS_OPENSSL_NO_VENDOR=1 +ENV ARMV7_UNKNOWN_LINUX_OHOS_OPENSSL_NO_VENDOR=1 +ENV X86_64_UNKNOWN_LINUX_OHOS_OPENSSL_NO_VENDOR=1 + ENV TARGETS=aarch64-unknown-linux-ohos ENV TARGETS=$TARGETS,armv7-unknown-linux-ohos ENV TARGETS=$TARGETS,x86_64-unknown-linux-ohos @@ -49,9 +60,12 @@ ENV \ ENV RUST_CONFIGURE_ARGS \ --enable-profiler \ - --disable-docs + --disable-docs \ + --tools=cargo,clippy,rustdocs,rustfmt,rust-analyzer,rust-analyzer-proc-macro-srv,analysis,src,wasm-component-ld \ + --enable-extended \ + --enable-sanitizers -ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS +ENV SCRIPT python3 ../x.py dist --host=$TARGETS --target $TARGETS COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/scripts/ohos-openssl.sh b/src/ci/docker/scripts/ohos-openssl.sh new file mode 100644 index 00000000000..713ab6131e3 --- /dev/null +++ b/src/ci/docker/scripts/ohos-openssl.sh @@ -0,0 +1,7 @@ +#!/bin/sh +set -ex + +URL=https://github.com/ohos-rs/ohos-openssl/archive/refs/tags/0.1.0.tar.gz + +mkdir -p /opt/ohos-openssl +curl -fL $URL | tar xz -C /opt/ohos-openssl --strip-components=1 diff --git a/src/ci/docker/scripts/ohos-sdk.sh b/src/ci/docker/scripts/ohos-sdk.sh index 321be2b8697..47d630ca76b 100755 --- a/src/ci/docker/scripts/ohos-sdk.sh +++ b/src/ci/docker/scripts/ohos-sdk.sh @@ -1,9 +1,10 @@ #!/bin/sh set -ex -URL=https://repo.huaweicloud.com/openharmony/os/4.0-Release/ohos-sdk-windows_linux-public.tar.gz +URL=https://repo.huaweicloud.com/openharmony/os/5.0.0-Release/ohos-sdk-windows_linux-public.tar.gz -curl $URL | tar xz -C /tmp ohos-sdk/linux/native-linux-x64-4.0.10.13-Release.zip +curl $URL | tar xz -C /tmp linux/native-linux-x64-5.0.0.71-Release.zip mkdir /opt/ohos-sdk cd /opt/ohos-sdk -unzip -qq /tmp/ohos-sdk/linux/native-linux-x64-4.0.10.13-Release.zip +unzip -qq /tmp/linux/native-linux-x64-5.0.0.71-Release.zip +rm /tmp/linux/native-linux-x64-5.0.0.71-Release.zip diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index d8c3625af28..f62ed23d038 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -82,15 +82,13 @@ envs: AWS_REGION: us-west-1 TOOLSTATE_PUBLISH: 1 + # Try builds started through `@bors try` (without specifying custom jobs + # in the PR description) will be passed the `DIST_TRY_BUILD` environment + # variable by citool. + # This tells the `opt-dist` tool to skip building certain components + # and skip running tests, so that the try build finishes faster. try: <<: *production - # The following env var activates faster `try` builds in `opt-dist` by, e.g. - # - building only the more commonly useful components (we rarely need e.g. rust-docs in try - # builds) - # - not running `opt-dist`'s post-optimization smoke tests on the resulting toolchain - # - # If you *want* these to happen however, temporarily comment it before triggering a try build. - DIST_TRY_BUILD: 1 auto: <<: *production @@ -176,7 +174,7 @@ auto: <<: *job-linux-4c - name: dist-ohos - <<: *job-linux-4c + <<: *job-linux-4c-largedisk - name: dist-powerpc-linux <<: *job-linux-4c @@ -262,13 +260,16 @@ auto: - name: test-various <<: *job-linux-4c - - name: x86_64-fuchsia - # Only run this job on the nightly channel. Fuchsia requires - # nightly features to compile, and this job would fail if - # executed on beta and stable. - only_on_channel: nightly - doc_url: https://rustc-dev-guide.rust-lang.org/tests/fuchsia.html - <<: *job-linux-8c + # FIXME: temporarily disabled due to fuchsia server rate limits. See + # <https://rust-lang.zulipchat.com/#narrow/channel/242791-t-infra/topic/fuchsia.20failure/with/506637259>. + # + #- name: x86_64-fuchsia + # # Only run this job on the nightly channel. Fuchsia requires + # # nightly features to compile, and this job would fail if + # # executed on beta and stable. + # only_on_channel: nightly + # doc_url: https://rustc-dev-guide.rust-lang.org/tests/fuchsia.html + # <<: *job-linux-8c # Tests integration with Rust for Linux. # Builds stage 1 compiler and tries to compile a few RfL examples with it. diff --git a/src/ci/run.sh b/src/ci/run.sh index 63e79c737d6..6980d8220e5 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -112,7 +112,11 @@ export RUST_RELEASE_CHANNEL=$(releaseChannel) RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL" if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then - RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp" + if [[ "$CI_JOB_NAME" == *ohos* ]]; then + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-static-stdcpp" + else + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp" + fi RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.remap-debuginfo" if [ "$DEPLOY_ALT" != "" ] && isLinux; then @@ -225,8 +229,8 @@ trap datecheck EXIT # sccache server at the start of the build, but no need to worry if this fails. SCCACHE_IDLE_TIMEOUT=10800 sccache --start-server || true -# Our build may overwrite config.toml, so we remove it here -rm -f config.toml +# Our build may overwrite bootstrap.toml, so we remove it here +rm -f bootstrap.toml $SRC/configure $RUST_CONFIGURE_ARGS diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index eb779d9ab05..6baf43397e8 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -8536f201ffdb2c24925d7f9e87996d7dca93428b +493c38ba371929579fe136df26eccd9516347c7a diff --git a/src/doc/rustc-dev-guide/src/backend/debugging.md b/src/doc/rustc-dev-guide/src/backend/debugging.md index 805291017c2..4f8712dfaf3 100644 --- a/src/doc/rustc-dev-guide/src/backend/debugging.md +++ b/src/doc/rustc-dev-guide/src/backend/debugging.md @@ -38,7 +38,7 @@ which means that LLVM assertion failures can show up as compiler crashes (not ICEs but "real" crashes) and other sorts of weird behavior. If you are encountering these, it is a good idea to try using a compiler with LLVM assertions enabled - either an "alt" nightly or a compiler you build yourself -by setting `[llvm] assertions=true` in your config.toml - and see whether +by setting `[llvm] assertions=true` in your bootstrap.toml - and see whether anything turns up. The rustc build process builds the LLVM tools into @@ -160,7 +160,7 @@ from `./build/<host-triple>/llvm/bin/` with the LLVM IR emitted by rustc. When investigating the implementation of LLVM itself, you should be aware of its [internal debug infrastructure][llvm-debug]. This is provided in LLVM Debug builds, which you enable for rustc -LLVM builds by changing this setting in the config.toml: +LLVM builds by changing this setting in the bootstrap.toml: ``` [llvm] # Indicates whether the LLVM assertions are enabled or not 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 0b45956b160..18c822aad79 100644 --- a/src/doc/rustc-dev-guide/src/backend/updating-llvm.md +++ b/src/doc/rustc-dev-guide/src/backend/updating-llvm.md @@ -144,7 +144,7 @@ so let's go through each in detail. Note that `profile = "compiler"` and other defaults set by `./x setup` download LLVM from CI instead of building it from source. You should disable this temporarily to make sure your changes are being used. - This is done by having the following setting in `config.toml`: + This is done by having the following setting in `bootstrap.toml`: ```toml [llvm] diff --git a/src/doc/rustc-dev-guide/src/building/compiler-documenting.md b/src/doc/rustc-dev-guide/src/building/compiler-documenting.md index 948571ce82e..b031462ea15 100644 --- a/src/doc/rustc-dev-guide/src/building/compiler-documenting.md +++ b/src/doc/rustc-dev-guide/src/building/compiler-documenting.md @@ -36,7 +36,7 @@ like the standard library (std) or the compiler (rustc). - Document internal rustc items Compiler documentation is not built by default. - To create it by default with `x doc`, modify `config.toml`: + To create it by default with `x doc`, modify `bootstrap.toml`: ```toml [build] diff --git a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md index f9a089c23f2..067e2871118 100644 --- a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md +++ b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md @@ -159,15 +159,15 @@ similar to the one declared in section [What is `x.py`](#what-is-xpy), but it works as an independent process to execute the `x.py` rather than calling the shell to run the platform related scripts. -## Create a `config.toml` +## Create a `bootstrap.toml` To start, run `./x setup` and select the `compiler` defaults. This will do some initialization -and create a `config.toml` for you with reasonable defaults. If you use a different default (which +and create a `bootstrap.toml` for you with reasonable defaults. If you use a different default (which you'll likely want to do if you want to contribute to an area of rust other than the compiler, such as rustdoc), make sure to read information about that default (located in `src/bootstrap/defaults`) as the build process may be different for other defaults. -Alternatively, you can write `config.toml` by hand. See `config.example.toml` for all the available +Alternatively, you can write `bootstrap.toml` by hand. See `bootstrap.example.toml` for all the available settings and explanations of them. See `src/bootstrap/defaults` for common settings to change. If you have already built `rustc` and you change settings related to LLVM, then you may have to @@ -206,7 +206,7 @@ See the chapters on Note that building will require a relatively large amount of storage space. You may want to have upwards of 10 or 15 gigabytes available to build the compiler. -Once you've created a `config.toml`, you are now ready to run +Once you've created a `bootstrap.toml`, you are now ready to run `x`. There are a lot of options here, but let's start with what is probably the best "go to" command for building a local compiler: @@ -326,7 +326,7 @@ involve proc macros or build scripts, you must be sure to explicitly build targe host platform (in this case, `x86_64-unknown-linux-gnu`). If you want to always build for other targets without needing to pass flags to `x build`, -you can configure this in the `[build]` section of your `config.toml` like so: +you can configure this in the `[build]` section of your `bootstrap.toml` like so: ```toml [build] @@ -336,8 +336,8 @@ target = ["x86_64-unknown-linux-gnu", "wasm32-wasip1"] Note that building for some targets requires having external dependencies installed (e.g. building musl targets requires a local copy of musl). Any target-specific configuration (e.g. the path to a local copy of musl) -will need to be provided by your `config.toml`. -Please see `config.example.toml` for information on target-specific configuration keys. +will need to be provided by your `bootstrap.toml`. +Please see `bootstrap.example.toml` for information on target-specific configuration keys. For examples of the complete configuration necessary to build a target, please visit [the rustc book](https://doc.rust-lang.org/rustc/platform-support.html), diff --git a/src/doc/rustc-dev-guide/src/building/new-target.md b/src/doc/rustc-dev-guide/src/building/new-target.md index 14d10d4a59d..09ffbe8c882 100644 --- a/src/doc/rustc-dev-guide/src/building/new-target.md +++ b/src/doc/rustc-dev-guide/src/building/new-target.md @@ -37,7 +37,7 @@ able to configure Rust to treat your build as the system LLVM to avoid redundant builds. You can tell Rust to use a pre-built version of LLVM using the `target` section -of `config.toml`: +of `bootstrap.toml`: ```toml [target.x86_64-unknown-linux-gnu] @@ -55,8 +55,8 @@ for codegen tests. This tool is normally built with LLVM, but if you use your own preinstalled LLVM, you will need to provide `FileCheck` in some other way. On Debian-based systems, you can install the `llvm-N-tools` package (where `N` is the LLVM version number, e.g. `llvm-8-tools`). Alternately, you can specify -the path to `FileCheck` with the `llvm-filecheck` config item in `config.toml` -or you can disable codegen test with the `codegen-tests` item in `config.toml`. +the path to `FileCheck` with the `llvm-filecheck` config item in `bootstrap.toml` +or you can disable codegen test with the `codegen-tests` item in `bootstrap.toml`. ## Creating a target specification @@ -141,14 +141,14 @@ After this, run `cargo update -p libc` to update the lockfiles. Beware that if you patch to a local `path` dependency, this will enable warnings for that dependency. Some dependencies are not warning-free, and due -to the `deny-warnings` setting in `config.toml`, the build may suddenly start +to the `deny-warnings` setting in `bootstrap.toml`, the build may suddenly start to fail. To work around warnings, you may want to: - Modify the dependency to remove the warnings -- Or for local development purposes, suppress the warnings by setting deny-warnings = false in config.toml. +- Or for local development purposes, suppress the warnings by setting deny-warnings = false in bootstrap.toml. ```toml -# config.toml +# bootstrap.toml [rust] deny-warnings = false ``` diff --git a/src/doc/rustc-dev-guide/src/building/optimized-build.md b/src/doc/rustc-dev-guide/src/building/optimized-build.md index f8ca1d0dc39..0849464eab3 100644 --- a/src/doc/rustc-dev-guide/src/building/optimized-build.md +++ b/src/doc/rustc-dev-guide/src/building/optimized-build.md @@ -13,7 +13,7 @@ This page describes how you can use these approaches when building `rustc` yours Link-time optimization is a powerful compiler technique that can increase program performance. To enable (Thin-)LTO when building `rustc`, set the `rust.lto` config option to `"thin"` -in `config.toml`: +in `bootstrap.toml`: ```toml [rust] @@ -34,7 +34,7 @@ Enabling LTO on Linux has [produced] speed-ups by up to 10%. Using a different memory allocator for `rustc` can provide significant performance benefits. If you want to enable the `jemalloc` allocator, you can set the `rust.jemalloc` option to `true` -in `config.toml`: +in `bootstrap.toml`: ```toml [rust] @@ -46,7 +46,7 @@ jemalloc = true ## Codegen units Reducing the amount of codegen units per `rustc` crate can produce a faster build of the compiler. -You can modify the number of codegen units for `rustc` and `libstd` in `config.toml` with the +You can modify the number of codegen units for `rustc` and `libstd` in `bootstrap.toml` with the following options: ```toml @@ -67,7 +67,7 @@ RUSTFLAGS="-C target_cpu=x86-64-v3" ./x build ... ``` If you also want to compile LLVM for a specific instruction set, you can set `llvm` flags -in `config.toml`: +in `bootstrap.toml`: ```toml [llvm] diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md index 2498838144e..43ff2ba726f 100644 --- a/src/doc/rustc-dev-guide/src/building/suggested.md +++ b/src/doc/rustc-dev-guide/src/building/suggested.md @@ -123,6 +123,30 @@ Another way is without a plugin, and creating your own logic in your configuration. The following code will work for any checkout of rust-lang/rust (newer than Febuary 2025): ```lua +local function expand_config_variables(option) + local var_placeholders = { + ['${workspaceFolder}'] = function(_) + return vim.lsp.buf.list_workspace_folders()[1] + end, + } + + if type(option) == "table" then + local mt = getmetatable(option) + local result = {} + for k, v in pairs(option) do + result[expand_config_variables(k)] = expand_config_variables(v) + end + return setmetatable(result, mt) + end + if type(option) ~= "string" then + return option + end + local ret = option + for key, fn in pairs(var_placeholders) do + ret = ret:gsub(key, fn) + end + return ret +end lspconfig.rust_analyzer.setup { root_dir = function() local default = lspconfig.rust_analyzer.config_def.default_config.root_dir() @@ -142,7 +166,7 @@ lspconfig.rust_analyzer.setup { -- load rust-lang/rust settings local file = io.open(config) local json = vim.json.decode(file:read("*a")) - client.config.settings["rust-analyzer"] = json.lsp["rust-analyzer"].initialization_options + client.config.settings["rust-analyzer"] = expand_config_variables(json.lsp["rust-analyzer"].initialization_options) client.notify("workspace/didChangeConfiguration", { settings = client.config.settings }) end return true @@ -305,7 +329,7 @@ subsequent rebuilds: ``` If you don't want to include the flag with every command, you can enable it in -the `config.toml`: +the `bootstrap.toml`: ```toml [rust] @@ -384,20 +408,20 @@ ln -s ./src/tools/nix-dev-shell/envrc-shell ./.envrc # Use nix-shell ### Note Note that when using nix on a not-NixOS distribution, it may be necessary to set -**`patch-binaries-for-nix = true` in `config.toml`**. Bootstrap tries to detect +**`patch-binaries-for-nix = true` in `bootstrap.toml`**. Bootstrap tries to detect whether it's running in nix and enable patching automatically, but this detection can have false negatives. -You can also use your nix shell to manage `config.toml`: +You can also use your nix shell to manage `bootstrap.toml`: ```nix let config = pkgs.writeText "rustc-config" '' - # Your config.toml content goes here + # Your bootstrap.toml content goes here '' pkgs.mkShell { /* ... */ - # This environment variable tells bootstrap where our config.toml is. + # This environment variable tells bootstrap where our bootstrap.toml is. RUST_BOOTSTRAP_CONFIG = config; } ``` diff --git a/src/doc/rustc-dev-guide/src/compiler-debugging.md b/src/doc/rustc-dev-guide/src/compiler-debugging.md index c16b3ee7abd..47f39762022 100644 --- a/src/doc/rustc-dev-guide/src/compiler-debugging.md +++ b/src/doc/rustc-dev-guide/src/compiler-debugging.md @@ -11,13 +11,13 @@ chapter](./backend/debugging.md)). ## Configuring the compiler By default, rustc is built without most debug information. To enable debug info, -set `debug = true` in your config.toml. +set `debug = true` in your bootstrap.toml. Setting `debug = true` turns on many different debug options (e.g., `debug-assertions`, `debug-logging`, etc.) which can be individually tweaked if you want to, but many people simply set `debug = true`. -If you want to use GDB to debug rustc, please set `config.toml` with options: +If you want to use GDB to debug rustc, please set `bootstrap.toml` with options: ```toml [rust] @@ -35,14 +35,14 @@ debuginfo-level = 2 The default configuration will enable `symbol-mangling-version` v0. This requires at least GDB v10.2, -otherwise you need to disable new symbol-mangling-version in `config.toml`. +otherwise you need to disable new symbol-mangling-version in `bootstrap.toml`. ```toml [rust] new-symbol-mangling = false ``` -> See the comments in `config.example.toml` for more info. +> See the comments in `bootstrap.example.toml` for more info. You will need to rebuild the compiler after changing any configuration option. @@ -373,7 +373,7 @@ error: aborting due to previous error ## Configuring CodeLLDB for debugging `rustc` -If you are using VSCode, and have edited your `config.toml` to request debugging +If you are using VSCode, and have edited your `bootstrap.toml` to request debugging level 1 or 2 for the parts of the code you're interested in, then you should be able to use the [CodeLLDB] extension in VSCode to debug it. diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 9817326f07b..09a7f912b98 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -81,7 +81,7 @@ smaller user-facing changes. into a PR that ends up not getting merged!** [See this document][mcpinfo] for more info on MCPs. -[mcpinfo]: https://forge.rust-lang.org/compiler/mcp.html +[mcpinfo]: https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#how-do-i-submit-an-mcp [zulip]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler ### Performance diff --git a/src/doc/rustc-dev-guide/src/fuzzing.md b/src/doc/rustc-dev-guide/src/fuzzing.md index 869fc2f71cc..b588ca104cb 100644 --- a/src/doc/rustc-dev-guide/src/fuzzing.md +++ b/src/doc/rustc-dev-guide/src/fuzzing.md @@ -123,7 +123,7 @@ what actually results in superior throughput. You may want to build rustc from source with debug assertions to find additional bugs, though this is a trade-off: it can slow down fuzzing by requiring extra work for every execution. To enable debug assertions, add this -to `config.toml` when compiling rustc: +to `bootstrap.toml` when compiling rustc: ```toml [rust] diff --git a/src/doc/rustc-dev-guide/src/implementing_new_features.md b/src/doc/rustc-dev-guide/src/implementing_new_features.md index fda38ef4fc0..d7561bbbad2 100644 --- a/src/doc/rustc-dev-guide/src/implementing_new_features.md +++ b/src/doc/rustc-dev-guide/src/implementing_new_features.md @@ -44,7 +44,7 @@ like this; for example, the compiler team recommends filing a Major Change Proposal ([MCP][mcp]) as a lightweight way to garner support and feedback without requiring full consensus. -[mcp]: https://forge.rust-lang.org/compiler/mcp.html#public-facing-changes-require-rfcbot-fcp +[mcp]: https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#how-do-i-submit-an-mcp You don't need to have the implementation fully ready for r+ to propose an FCP, but it is generally a good idea to have at least a proof diff --git a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md index 3078ae094c3..6bc21b6deeb 100644 --- a/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md +++ b/src/doc/rustc-dev-guide/src/llvm-coverage-instrumentation.md @@ -34,7 +34,7 @@ Detailed instructions and examples are documented in the [coverage map]: https://llvm.org/docs/CoverageMappingFormat.html [rustc-book-instrument-coverage]: https://doc.rust-lang.org/nightly/rustc/instrument-coverage.html -## Recommended `config.toml` settings +## Recommended `bootstrap.toml` settings When working on the coverage instrumentation code, it is usually necessary to **enable the profiler runtime** by setting `profiler = true` in `[build]`. @@ -83,7 +83,7 @@ statically links coverage-instrumented binaries with LLVM runtime code In the `rustc` source tree, `library/profiler_builtins` bundles the LLVM `compiler-rt` code into a Rust library crate. Note that when building `rustc`, -`profiler_builtins` is only included when `build.profiler = true` is set in `config.toml`. +`profiler_builtins` is only included when `build.profiler = true` is set in `bootstrap.toml`. When compiling with `-C instrument-coverage`, [`CrateLoader::postprocess()`][crate-loader-postprocess] dynamically loads @@ -115,7 +115,7 @@ human-readable coverage report. > Tests in `coverage-run` mode have an implicit `//@ needs-profiler-runtime` > directive, so they will be skipped if the profiler runtime has not been -> [enabled in `config.toml`](#recommended-configtoml-settings). +> [enabled in `bootstrap.toml`](#recommended-configtoml-settings). Finally, the [`tests/codegen/instrument-coverage/testprog.rs`] test compiles a simple Rust program with `-C instrument-coverage` and compares the compiled program's LLVM IR to diff --git a/src/doc/rustc-dev-guide/src/overview.md b/src/doc/rustc-dev-guide/src/overview.md index 21ab0040646..92d0c7b0c38 100644 --- a/src/doc/rustc-dev-guide/src/overview.md +++ b/src/doc/rustc-dev-guide/src/overview.md @@ -351,7 +351,7 @@ approach is to turn [`RefCell`]s into [`Mutex`]s -- that is, we switch to thread-safe internal mutability. However, there are ongoing challenges with lock contention, maintaining query-system invariants under concurrency, and the complexity of the code base. One can try out the current -work by enabling parallel compilation in `config.toml`. It's still early days, +work by enabling parallel compilation in `bootstrap.toml`. It's still early days, but there are already some promising performance improvements. [`RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html diff --git a/src/doc/rustc-dev-guide/src/profile-guided-optimization.md b/src/doc/rustc-dev-guide/src/profile-guided-optimization.md index 995752b0b8b..39bc8b5e862 100644 --- a/src/doc/rustc-dev-guide/src/profile-guided-optimization.md +++ b/src/doc/rustc-dev-guide/src/profile-guided-optimization.md @@ -120,7 +120,7 @@ The `rustc` version of this can be found in `library/profiler_builtins` which basically packs the C code from `compiler-rt` into a Rust crate. In order for `profiler_builtins` to be built, `profiler = true` must be set -in `rustc`'s `config.toml`. +in `rustc`'s `bootstrap.toml`. [compiler-rt-profile]: https://github.com/llvm/llvm-project/tree/main/compiler-rt/lib/profile diff --git a/src/doc/rustc-dev-guide/src/profiling.md b/src/doc/rustc-dev-guide/src/profiling.md index df987e00a58..de06bd7cda7 100644 --- a/src/doc/rustc-dev-guide/src/profiling.md +++ b/src/doc/rustc-dev-guide/src/profiling.md @@ -87,7 +87,7 @@ Example output for the compiler: Since this doesn't seem to work with incremental compilation or `./x check`, you will be compiling rustc _a lot_. -I recommend changing a few settings in `config.toml` to make it bearable: +I recommend changing a few settings in `bootstrap.toml` to make it bearable: ``` [rust] # A debug build takes _a third_ as long on my machine, diff --git a/src/doc/rustc-dev-guide/src/profiling/with_perf.md b/src/doc/rustc-dev-guide/src/profiling/with_perf.md index 51a22d18577..742ea1c41a6 100644 --- a/src/doc/rustc-dev-guide/src/profiling/with_perf.md +++ b/src/doc/rustc-dev-guide/src/profiling/with_perf.md @@ -6,7 +6,7 @@ This is a guide for how to profile rustc with [perf](https://perf.wiki.kernel.or - Get a clean checkout of rust-lang/master, or whatever it is you want to profile. -- Set the following settings in your `config.toml`: +- Set the following settings in your `bootstrap.toml`: - `debuginfo-level = 1` - enables line debuginfo - `jemalloc = false` - lets you do memory use profiling with valgrind - leave everything else the defaults diff --git a/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md b/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md index eda8c3a179c..c47fed24e6e 100644 --- a/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md +++ b/src/doc/rustc-dev-guide/src/profiling/with_rustc_perf.md @@ -9,7 +9,7 @@ which will download and build the suite for you, build a local compiler toolchai You can use the `./x perf <command> [options]` command to use this integration. -You can use normal bootstrap flags for this command, such as `--stage 1` or `--stage 2`, for example to modify the stage of the created sysroot. It might also be useful to configure `config.toml` to better support profiling, e.g. set `rust.debuginfo-level = 1` to add source line information to the built compiler. +You can use normal bootstrap flags for this command, such as `--stage 1` or `--stage 2`, for example to modify the stage of the created sysroot. It might also be useful to configure `bootstrap.toml` to better support profiling, e.g. set `rust.debuginfo-level = 1` to add source line information to the built compiler. `x perf` currently supports the following commands: - `benchmark <id>`: Benchmark the compiler and store the results under the passed `id`. diff --git a/src/doc/rustc-dev-guide/src/profiling/wpa_profiling.md b/src/doc/rustc-dev-guide/src/profiling/wpa_profiling.md index a800c5717e3..d2680d40853 100644 --- a/src/doc/rustc-dev-guide/src/profiling/wpa_profiling.md +++ b/src/doc/rustc-dev-guide/src/profiling/wpa_profiling.md @@ -44,7 +44,7 @@ compiler we're using to build rustc will aid our analysis greatly by allowing WP symbols correctly. Unfortunately, the stage 0 compiler does not have symbols turned on which is why we'll need to build a stage 1 compiler and then a stage 2 compiler ourselves. -To do this, make sure you have set `debuginfo-level = 1` in your `config.toml` file. This tells +To do this, make sure you have set `debuginfo-level = 1` in your `bootstrap.toml` file. This tells rustc to generate debug information which includes stack frames when bootstrapping. Now you can build the stage 1 compiler: `x build --stage 1 -i library` or however diff --git a/src/doc/rustc-dev-guide/src/rustdoc.md b/src/doc/rustc-dev-guide/src/rustdoc.md index 2a0e212f98e..356698148e4 100644 --- a/src/doc/rustc-dev-guide/src/rustdoc.md +++ b/src/doc/rustc-dev-guide/src/rustdoc.md @@ -58,12 +58,12 @@ does is call the `main()` that's in this crate's `lib.rs`, though.) * If you want to copy those docs to a webserver, copy all of `build/host/doc`, since that's where the CSS, JS, fonts, and landing page are. - * For frontend debugging, disable the `rust.docs-minification` option in [`config.toml`]. + * For frontend debugging, disable the `rust.docs-minification` option in [`bootstrap.toml`]. * Use `./x test tests/rustdoc*` to run the tests using a stage1 rustdoc. * See [Rustdoc internals] for more information about tests. -[`config.toml`]: ./building/how-to-build-and-run.md +[`bootstrap.toml`]: ./building/how-to-build-and-run.md ## Code structure diff --git a/src/doc/rustc-dev-guide/src/sanitizers.md b/src/doc/rustc-dev-guide/src/sanitizers.md index 73e888eae68..b1654b15e08 100644 --- a/src/doc/rustc-dev-guide/src/sanitizers.md +++ b/src/doc/rustc-dev-guide/src/sanitizers.md @@ -32,7 +32,7 @@ implementation: * The sanitizer runtime libraries are part of the [compiler-rt] project, and [will be built][sanitizer-build] on [supported targets][sanitizer-targets] - when enabled in `config.toml`: + when enabled in `bootstrap.toml`: ```toml [build] @@ -80,7 +80,7 @@ Sanitizers are validated by code generation tests in [`tests/ui/sanitizer/`][test-ui] directory. Testing sanitizer functionality requires the sanitizer runtimes (built when -`sanitizer = true` in `config.toml`) and target providing support for particular +`sanitizer = true` in `bootstrap.toml`) and target providing support for particular sanitizer. When sanitizer is unsupported on given target, sanitizers tests will be ignored. This behaviour is controlled by compiletest `needs-sanitizer-*` directives. diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index 0c0f750a45d..c04f296ba0b 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -180,6 +180,8 @@ their results can be seen [here](https://github.com/rust-lang-ci/rust/actions), although usually you will be notified of the result by a comment made by bors on the corresponding PR. +Note that if you start the default try job using `@bors try`, it will skip building several `dist` components and running post-optimization tests, to make the build duration shorter. If you want to execute the full build as it would happen before a merge, add an explicit `try-job` pattern with the name of the default try job (currently `dist-x86_64-linux`). + Multiple try builds can execute concurrently across different PRs. <div class="warning"> @@ -435,7 +437,7 @@ To learn more about the dashboard, see the [Datadog CI docs]. ## Determining the CI configuration -If you want to determine which `config.toml` settings are used in CI for a +If you want to determine which `bootstrap.toml` settings are used in CI for a particular job, it is probably easiest to just look at the build log. To do this: diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index a6996e39822..2c35381eadf 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -525,10 +525,10 @@ data into a human-readable code coverage report. Instrumented binaries need to be linked against the LLVM profiler runtime, so `coverage-run` tests are **automatically skipped** unless the profiler runtime -is enabled in `config.toml`: +is enabled in `bootstrap.toml`: ```toml -# config.toml +# bootstrap.toml [build] profiler = true ``` diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index d5b896a8eee..81aa35f1a46 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -160,9 +160,9 @@ settings: stable support for `asm!` - `needs-profiler-runtime` — ignores the test if the profiler runtime was not enabled for the target - (`build.profiler = true` in rustc's `config.toml`) + (`build.profiler = true` in rustc's `bootstrap.toml`) - `needs-sanitizer-support` — ignores if the sanitizer support was not enabled - for the target (`sanitizers = true` in rustc's `config.toml`) + for the target (`sanitizers = true` in rustc's `bootstrap.toml`) - `needs-sanitizer-{address,hwaddress,leak,memory,thread}` — ignores if the corresponding sanitizer is not enabled for the target (AddressSanitizer, hardware-assisted AddressSanitizer, LeakSanitizer, MemorySanitizer or @@ -172,7 +172,7 @@ settings: flag, or running on fuchsia. - `needs-unwind` — ignores if the target does not support unwinding - `needs-rust-lld` — ignores if the rust lld support is not enabled (`rust.lld = - true` in `config.toml`) + true` in `bootstrap.toml`) - `needs-threads` — ignores if the target does not have threading support - `needs-subprocess` — ignores if the target does not have subprocess support - `needs-symlink` — ignores if the target does not support symlinks. This can be diff --git a/src/doc/rustc-dev-guide/src/tests/docker.md b/src/doc/rustc-dev-guide/src/tests/docker.md index a8a388ef90c..032da1ca1e8 100644 --- a/src/doc/rustc-dev-guide/src/tests/docker.md +++ b/src/doc/rustc-dev-guide/src/tests/docker.md @@ -21,7 +21,7 @@ The [`src/ci/docker/run.sh`] script is used to build a specific Docker image, ru build Rust within the image, and either run tests or prepare a set of archives designed for distribution. The script will mount your local Rust source tree in read-only mode, and an `obj` directory in read-write mode. All the compiler artifacts will be stored in the `obj` directory. The shell will start out in the `obj`directory. From there, it will execute `../src/ci/run.sh` which starts the build as defined by the Docker image. You can run `src/ci/docker/run.sh <image-name>` directly. A few important notes regarding the `run.sh` script: -- When executed on CI, the script expects that all submodules are checked out. If some submodule that is accessed by the job is not available, the build will result in an error. You should thus make sure that you have all required submodules checked out locally. You can either do that manually through git, or set `submodules = true` in your `config.toml` and run a command such as `x build` to let bootstrap download the most important submodules (this might not be enough for the given CI job that you are trying to execute though). +- When executed on CI, the script expects that all submodules are checked out. If some submodule that is accessed by the job is not available, the build will result in an error. You should thus make sure that you have all required submodules checked out locally. You can either do that manually through git, or set `submodules = true` in your `bootstrap.toml` and run a command such as `x build` to let bootstrap download the most important submodules (this might not be enough for the given CI job that you are trying to execute though). - `<image-name>` corresponds to a single directory located in one of the `src/ci/docker/host-*` directories. Note that image name does not necessarily correspond to a job name, as some jobs execute the same image, but with different environment variables or Docker build arguments (this is a part of the complexity that makes it difficult to run CI jobs locally). - If you are executing a "dist" job (job beginning with `dist-`), you should set the `DEPLOY=1` environment variable. - If you are executing an "alternative dist" job (job beginning with `dist-` and ending with `-alt`), you should set the `DEPLOY_ALT=1` environment variable. diff --git a/src/doc/rustc-dev-guide/src/tests/running.md b/src/doc/rustc-dev-guide/src/tests/running.md index 03d4123cb02..73c38736812 100644 --- a/src/doc/rustc-dev-guide/src/tests/running.md +++ b/src/doc/rustc-dev-guide/src/tests/running.md @@ -18,7 +18,7 @@ a subset of test collections, and merge queue CI will exercise all of the test collection. </div> -```bash +```text ./x test ``` @@ -45,7 +45,7 @@ tests. For example, a good "smoke test" that can be used after modifying rustc to see if things are generally working correctly would be to exercise the `ui` test suite ([`tests/ui`]): -```bash +```text ./x test tests/ui ``` @@ -53,14 +53,14 @@ Of course, the choice of test suites is somewhat arbitrary, and may not suit the task you are doing. For example, if you are hacking on debuginfo, you may be better off with the debuginfo test suite: -```bash +```text ./x test tests/debuginfo ``` If you only need to test a specific subdirectory of tests for any given test suite, you can pass that directory as a filter to `./x test`: -```bash +```text ./x test tests/ui/const-generics ``` @@ -73,7 +73,7 @@ suite, you can pass that directory as a filter to `./x test`: Likewise, you can test a single file by passing its path: -```bash +```text ./x test tests/ui/const-generics/const-test.rs ``` @@ -81,19 +81,19 @@ Likewise, you can test a single file by passing its path: have to use the `--test-args` argument as described [below](#running-an-individual-test). -```bash +```text ./x test src/tools/miri --test-args tests/fail/uninit/padding-enum.rs ``` ### Run only the tidy script -```bash +```text ./x test tidy ``` ### Run tests on the standard library -```bash +```text ./x test --stage 0 library/std ``` @@ -102,13 +102,13 @@ crates, you have to specify those explicitly. ### Run the tidy script and tests on the standard library -```bash +```text ./x test --stage 0 tidy library/std ``` ### Run tests on the standard library using a stage 1 compiler -```bash +```text ./x test --stage 1 library/std ``` @@ -122,7 +122,7 @@ the tests **usually** work fine with stage 1, there are some limitations. ### Run all tests using a stage 2 compiler -```bash +```text ./x test --stage 2 ``` @@ -134,13 +134,13 @@ You almost never need to do this; CI will run these tests for you. You may want to run unit tests on a specific file with following: -```bash +```text ./x test compiler/rustc_data_structures/src/thin_vec/tests.rs ``` But unfortunately, it's impossible. You should invoke the following instead: -```bash +```text ./x test compiler/rustc_data_structures/ --test-args thin_vec ``` @@ -151,7 +151,7 @@ often the test they are trying to fix. As mentioned earlier, you may pass the full file path to achieve this, or alternatively one may invoke `x` with the `--test-args` option: -```bash +```text ./x test tests/ui --test-args issue-1234 ``` @@ -189,7 +189,7 @@ just like when running the tests without the `--bless` flag. There are a few options for running tests: -* `config.toml` has the `rust.verbose-tests` option. If `false`, each test will +* `bootstrap.toml` has the `rust.verbose-tests` option. If `false`, each test will print a single dot (the default). If `true`, the name of every test will be printed. This is equivalent to the `--quiet` option in the [Rust test harness](https://doc.rust-lang.org/rustc/tests/). @@ -203,7 +203,7 @@ When `--pass $mode` is passed, these tests will be forced to run under the given `$mode` unless the directive `//@ ignore-pass` exists in the test file. For example, you can run all the tests in `tests/ui` as `check-pass`: -```bash +```text ./x test tests/ui --pass check ``` @@ -219,7 +219,7 @@ first look for expected output in `foo.polonius.stderr`, falling back to the usual `foo.stderr` if not found. The following will run the UI test suite in Polonius mode: -```bash +```text ./x test tests/ui --compare-mode=polonius ``` @@ -232,7 +232,7 @@ just `.rs` files, so after [creating a rustup toolchain](../building/how-to-build-and-run.md#creating-a-rustup-toolchain), you can do something like: -```bash +```text rustc +stage1 tests/ui/issue-1234.rs ``` @@ -252,7 +252,7 @@ execution* so be careful where it is used. To do this, first build `remote-test-server` for the remote machine, e.g. for RISC-V -```sh +```text ./x build src/tools/remote-test-server --target riscv64gc-unknown-linux-gnu ``` @@ -264,7 +264,7 @@ On the remote machine, run the `remote-test-server` with the `--bind 0.0.0.0:12345` flag (and optionally `-v` for verbose output). Output should look like this: -```sh +```text $ ./remote-test-server -v --bind 0.0.0.0:12345 starting test server listening on 0.0.0.0:12345! @@ -278,7 +278,7 @@ restrictive IP address when binding. You can test if the `remote-test-server` is working by connecting to it and sending `ping\n`. It should reply `pong`: -```sh +```text $ nc $REMOTE_IP 12345 ping pong @@ -288,7 +288,7 @@ To run tests using the remote runner, set the `TEST_DEVICE_ADDR` environment variable then use `x` as usual. For example, to run `ui` tests for a RISC-V machine with the IP address `1.2.3.4` use -```sh +```text export TEST_DEVICE_ADDR="1.2.3.4:12345" ./x test tests/ui --target riscv64gc-unknown-linux-gnu ``` @@ -296,7 +296,7 @@ export TEST_DEVICE_ADDR="1.2.3.4:12345" If `remote-test-server` was run with the verbose flag, output on the test machine may look something like -``` +```text [...] run "/tmp/work/test1007/a" run "/tmp/work/test1008/a" @@ -353,7 +353,7 @@ coordinate running tests (see [src/bootstrap/src/core/build_steps/test.rs]). First thing to know is that it only supports linux x86_64 at the moment. We will extend its support later on. -You need to update `codegen-backends` value in your `config.toml` file in the +You need to update `codegen-backends` value in your `bootstrap.toml` file in the `[rust]` section and add "gcc" in the array: ```toml @@ -362,21 +362,21 @@ codegen-backends = ["llvm", "gcc"] Then you need to install libgccjit 12. For example with `apt`: -```bash -$ apt install libgccjit-12-dev +```text +apt install libgccjit-12-dev ``` Now you can run the following command: -```bash -$ ./x test compiler/rustc_codegen_gcc/ +```text +./x test compiler/rustc_codegen_gcc/ ``` If it cannot find the `.so` library (if you installed it with `apt` for example), you need to pass the library file path with `LIBRARY_PATH`: -```bash -$ LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12/ ./x test compiler/rustc_codegen_gcc/ +```text +LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12/ ./x test compiler/rustc_codegen_gcc/ ``` If you encounter bugs or problems, don't hesitate to open issues on the diff --git a/src/doc/rustc-dev-guide/src/tracing.md b/src/doc/rustc-dev-guide/src/tracing.md index af484ab5f8f..0cfdf306e92 100644 --- a/src/doc/rustc-dev-guide/src/tracing.md +++ b/src/doc/rustc-dev-guide/src/tracing.md @@ -185,11 +185,11 @@ rustc. While calls to `error!`, `warn!` and `info!` are included in every build of the compiler, calls to `debug!` and `trace!` are only included in the program if -`debug-logging=true` is turned on in config.toml (it is +`debug-logging=true` is turned on in bootstrap.toml (it is turned off by default), so if you don't see `DEBUG` logs, especially if you run the compiler with `RUSTC_LOG=rustc rustc some.rs` and only see `INFO` logs, make sure that `debug-logging=true` is turned on in your -config.toml. +bootstrap.toml. ## Logging etiquette and conventions diff --git a/src/doc/rustc/src/instrument-coverage.md b/src/doc/rustc/src/instrument-coverage.md index 41da47e9206..57679f82f48 100644 --- a/src/doc/rustc/src/instrument-coverage.md +++ b/src/doc/rustc/src/instrument-coverage.md @@ -27,7 +27,7 @@ Rust's source-based code coverage requires the Rust "profiler runtime". Without The Rust `nightly` distribution channel includes the profiler runtime, by default. -> **Important**: If you are building the Rust compiler from the source distribution, the profiler runtime is _not_ enabled in the default `config.example.toml`. Edit your `config.toml` file and ensure the `profiler` feature is set it to `true` (either under the `[build]` section, or under the settings for an individual `[target.<triple>]`): +> **Important**: If you are building the Rust compiler from the source distribution, the profiler runtime is _not_ enabled in the default `bootstrap.example.toml`. Edit your `bootstrap.toml` file and ensure the `profiler` feature is set it to `true` (either under the `[build]` section, or under the settings for an individual `[target.<triple>]`): > > ```toml > # Build the profiler runtime (required when compiling with options that depend diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index c74a9e98496..058b0b0a07a 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -89,9 +89,11 @@ target | notes -------|------- `aarch64-pc-windows-msvc` | ARM64 Windows MSVC `aarch64-unknown-linux-musl` | ARM64 Linux with musl 1.2.3 +[`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | ARM64 OpenHarmony `arm-unknown-linux-gnueabi` | Armv6 Linux (kernel 3.2, glibc 2.17) `arm-unknown-linux-gnueabihf` | Armv6 Linux, hardfloat (kernel 3.2, glibc 2.17) `armv7-unknown-linux-gnueabihf` | Armv7-A Linux, hardfloat (kernel 3.2, glibc 2.17) +[`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | Armv7-A OpenHarmony [`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36) [`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, musl 1.2.5) `powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2, glibc 2.17) @@ -104,6 +106,7 @@ target | notes [`x86_64-unknown-freebsd`](platform-support/freebsd.md) | 64-bit x86 FreeBSD [`x86_64-unknown-illumos`](platform-support/illumos.md) | illumos `x86_64-unknown-linux-musl` | 64-bit Linux with musl 1.2.3 +[`x86_64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | x86_64 OpenHarmony [`x86_64-unknown-netbsd`](platform-support/netbsd.md) | NetBSD/amd64 ## Tier 2 without Host Tools @@ -142,7 +145,6 @@ target | std | notes [`aarch64-linux-android`](platform-support/android.md) | ✓ | ARM64 Android [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ARM64 MinGW (Windows 10+), LLVM ABI [`aarch64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | ARM64 Fuchsia -[`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | ARM64 OpenHarmony `aarch64-unknown-none` | * | Bare ARM64, hardfloat `aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat [`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | ARM64 UEFI @@ -158,7 +160,6 @@ target | std | notes `armv7-unknown-linux-gnueabi` | ✓ | Armv7-A Linux (kernel 4.15, glibc 2.27) `armv7-unknown-linux-musleabi` | ✓ | Armv7-A Linux with musl 1.2.3 `armv7-unknown-linux-musleabihf` | ✓ | Armv7-A Linux with musl 1.2.3, hardfloat -[`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | Armv7-A OpenHarmony [`armv7a-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare Armv7-A [`armv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R [`armv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, hardfloat @@ -204,7 +205,6 @@ target | std | notes [`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | 64-bit x86 MinGW (Windows 10+), LLVM ABI [`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia `x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27) -[`x86_64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | x86_64 OpenHarmony [`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat [`x86_64-unknown-redox`](platform-support/redox.md) | ✓ | Redox OS [`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 64-bit UEFI @@ -407,7 +407,7 @@ target | std | host | notes [`wasm32-wali-linux-musl`](platform-support/wasm32-wali-linux.md) | ? | | WebAssembly with [WALI](https://github.com/arjunr2/WALI) [`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator -[`x86_64-pc-cygwin`](platform-support/x86_64-pc-cygwin.md) | ? | | 64-bit x86 Cygwin | +[`x86_64-pc-cygwin`](platform-support/x86_64-pc-cygwin.md) | ✓ | | 64-bit x86 Cygwin | [`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with default network stack (io-pkt) | [`x86_64-pc-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with new network stack (io-sock) | [`x86_64-pc-nto-qnx800`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 8.0 RTOS | diff --git a/src/doc/rustc/src/platform-support/TEMPLATE.md b/src/doc/rustc/src/platform-support/TEMPLATE.md index 87dde722558..96c79973a16 100644 --- a/src/doc/rustc/src/platform-support/TEMPLATE.md +++ b/src/doc/rustc/src/platform-support/TEMPLATE.md @@ -28,7 +28,7 @@ What format do binaries use by default? ELF, PE, something else? ## Building the target If Rust doesn't build the target by default, how can users build it? Can users -just add it to the `target` list in `config.toml`? +just add it to the `target` list in `bootstrap.toml`? ## Building Rust programs diff --git a/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md index 7a6609b2d76..e2f2379ec44 100644 --- a/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md +++ b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md @@ -54,7 +54,7 @@ exec /path/to/ohos-sdk/linux/native/llvm/bin/clang++ \ ## Building the target -To build a rust toolchain, create a `config.toml` with the following contents: +To build a rust toolchain, create a `bootstrap.toml` with the following contents: ```toml profile = "compiler" diff --git a/src/doc/rustc/src/platform-support/apple-ios.md b/src/doc/rustc/src/platform-support/apple-ios.md index 5045f810400..cfb458fdb73 100644 --- a/src/doc/rustc/src/platform-support/apple-ios.md +++ b/src/doc/rustc/src/platform-support/apple-ios.md @@ -47,7 +47,7 @@ $ rustup target add x86_64-apple-ios ``` The tier 3 targets can be built by enabling them for a `rustc` build in -`config.toml`, by adding, for example: +`bootstrap.toml`, by adding, for example: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/apple-tvos.md b/src/doc/rustc/src/platform-support/apple-tvos.md index 7a3b601579a..166bb1b6db2 100644 --- a/src/doc/rustc/src/platform-support/apple-tvos.md +++ b/src/doc/rustc/src/platform-support/apple-tvos.md @@ -52,7 +52,7 @@ The following APIs are currently known to have missing or incomplete support: ## Building the target The targets can be built by enabling them for a `rustc` build in -`config.toml`, by adding, for example: +`bootstrap.toml`, by adding, for example: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/apple-visionos.md b/src/doc/rustc/src/platform-support/apple-visionos.md index 56224d7e20d..a7bbae168a4 100644 --- a/src/doc/rustc/src/platform-support/apple-visionos.md +++ b/src/doc/rustc/src/platform-support/apple-visionos.md @@ -31,7 +31,7 @@ case `XROS_DEPLOYMENT_TARGET`. ## Building the target The targets can be built by enabling them for a `rustc` build in -`config.toml`, by adding, for example: +`bootstrap.toml`, by adding, for example: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/apple-watchos.md b/src/doc/rustc/src/platform-support/apple-watchos.md index 8ba35f70b85..0bf8cdf3614 100644 --- a/src/doc/rustc/src/platform-support/apple-watchos.md +++ b/src/doc/rustc/src/platform-support/apple-watchos.md @@ -37,7 +37,7 @@ case `WATCHOS_DEPLOYMENT_TARGET`. ## Building the target The targets can be built by enabling them for a `rustc` build in -`config.toml`, by adding, for example: +`bootstrap.toml`, by adding, for example: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/arm64e-apple-darwin.md b/src/doc/rustc/src/platform-support/arm64e-apple-darwin.md index 322a07c5739..3200b7ae1b6 100644 --- a/src/doc/rustc/src/platform-support/arm64e-apple-darwin.md +++ b/src/doc/rustc/src/platform-support/arm64e-apple-darwin.md @@ -16,7 +16,7 @@ See the docs on [`*-apple-darwin`](apple-darwin.md) for general macOS requiremen ## Building the target -You can build Rust with support for the targets by adding it to the `target` list in `config.toml`: +You can build Rust with support for the targets by adding it to the `target` list in `bootstrap.toml`: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/arm64e-apple-ios.md b/src/doc/rustc/src/platform-support/arm64e-apple-ios.md index 3d8ba5c282a..aa99276a68f 100644 --- a/src/doc/rustc/src/platform-support/arm64e-apple-ios.md +++ b/src/doc/rustc/src/platform-support/arm64e-apple-ios.md @@ -14,7 +14,7 @@ See the docs on [`*-apple-ios`](apple-ios.md) for general iOS requirements. ## Building the target -You can build Rust with support for the targets by adding it to the `target` list in `config.toml`: +You can build Rust with support for the targets by adding it to the `target` list in `bootstrap.toml`: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/arm64e-apple-tvos.md b/src/doc/rustc/src/platform-support/arm64e-apple-tvos.md index ec8a996549e..332ea750f20 100644 --- a/src/doc/rustc/src/platform-support/arm64e-apple-tvos.md +++ b/src/doc/rustc/src/platform-support/arm64e-apple-tvos.md @@ -15,7 +15,7 @@ To build this target Xcode 12 or higher on macOS is required. ## Building the target -You can build Rust with support for the targets by adding it to the `target` list in `config.toml`: +You can build Rust with support for the targets by adding it to the `target` list in `bootstrap.toml`: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md b/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md index 15bf55d35a2..67903ae6401 100644 --- a/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md +++ b/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md @@ -56,7 +56,7 @@ To put this in practice: ## Building the target You can build Rust with support for the targets by adding it to the `target` -list in `config.toml`: +list in `bootstrap.toml`: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md b/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md index 3c3e35a51b8..3a5b5a38017 100644 --- a/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md +++ b/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md @@ -21,7 +21,7 @@ The target definition can be seen [here](https://github.com/rust-lang/rust/blob/ ## Building the target Because it is Tier 3, rust does not yet ship pre-compiled artifacts for this target. -Therefore, you can build Rust with support for the target by adding it to the target list in config.toml, a sample configuration is shown below. It is expected that the user already have a working GNU compiler toolchain and update the paths accordingly. +Therefore, you can build Rust with support for the target by adding it to the target list in bootstrap.toml, a sample configuration is shown below. It is expected that the user already have a working GNU compiler toolchain and update the paths accordingly. ```toml [llvm] diff --git a/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md b/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md index 160986aeae9..a085aef2d04 100644 --- a/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md +++ b/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md @@ -50,7 +50,7 @@ This target generates binaries in the ELF format. ## Building the target You can build Rust with support for the target by adding it to the `target` -list in `config.toml` and providing paths to the devkitARM toolchain. +list in `bootstrap.toml` and providing paths to the devkitARM toolchain. ```toml [build] diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md index 1c8acc09c77..f687f6f0695 100644 --- a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md +++ b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md @@ -22,7 +22,7 @@ If you don't already have a suitable toolchain, download one [here](https://tool ### Configure rust -The target can be built by enabling it for a `rustc` build, by placing the following in `config.toml`: +The target can be built by enabling it for a `rustc` build, by placing the following in `bootstrap.toml`: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md b/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md index 32e4f855313..f749b37aa7a 100644 --- a/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md +++ b/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md @@ -36,7 +36,7 @@ If you don't already have a suitable toolchain, you can download from [here](htt ### Configure rust -The target can be built by enabling it for a `rustc` build, by placing the following in `config.toml`: +The target can be built by enabling it for a `rustc` build, by placing the following in `bootstrap.toml`: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md index 489f46e1cb9..bed5b81adc5 100644 --- a/src/doc/rustc/src/platform-support/fuchsia.md +++ b/src/doc/rustc/src/platform-support/fuchsia.md @@ -180,7 +180,7 @@ Fuchsia as well. A recent version (14+) of clang should be sufficient to compile Rust for Fuchsia. x86-64 and AArch64 Fuchsia targets can be enabled using the following -configuration in `config.toml`: +configuration in `bootstrap.toml`: ```toml [build] @@ -212,7 +212,7 @@ cxx = "clang++" By default, the Rust compiler installs itself to `/usr/local` on most UNIX systems. You may want to install it to another location (e.g. a local `install` -directory) by setting a custom prefix in `config.toml`: +directory) by setting a custom prefix in `bootstrap.toml`: ```toml [install] @@ -695,7 +695,7 @@ We can then use the script to start our test environment with: ) ``` -Where `${RUST_SRC_PATH}/build` is the `build-dir` set in `config.toml`. +Where `${RUST_SRC_PATH}/build` is the `build-dir` set in `bootstrap.toml`. Once our environment is started, we can run our tests using `x.py` as usual. The test runner script will run the compiled tests on an emulated Fuchsia device. To @@ -705,7 +705,7 @@ run the full `tests/ui` test suite: ( \ source config-env.sh && \ ./x.py \ - --config config.toml \ + --config bootstrap.toml \ --stage=2 \ test tests/ui \ --target x86_64-unknown-fuchsia \ @@ -893,7 +893,7 @@ through our `x.py` invocation. The full invocation is: ( \ source config-env.sh && \ ./x.py \ - --config config.toml \ + --config bootstrap.toml \ --stage=2 \ test tests/${TEST} \ --target x86_64-unknown-fuchsia \ diff --git a/src/doc/rustc/src/platform-support/hermit.md b/src/doc/rustc/src/platform-support/hermit.md index 5aa787e53e1..df7bc495fce 100644 --- a/src/doc/rustc/src/platform-support/hermit.md +++ b/src/doc/rustc/src/platform-support/hermit.md @@ -31,7 +31,7 @@ Hermit binaries have the ELF format. ## Building the target -You can build Rust with support for the targets by adding it to the `target` list in `config.toml`. +You can build Rust with support for the targets by adding it to the `target` list in `bootstrap.toml`. To run the Hermit build scripts, you also have to enable your host target. The build scripts rely on `llvm-tools` and binaries are linked using `rust-lld`, so those have to be enabled as well. diff --git a/src/doc/rustc/src/platform-support/hexagon-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/hexagon-unknown-linux-musl.md index d858337a949..cfd2b2bac9c 100644 --- a/src/doc/rustc/src/platform-support/hexagon-unknown-linux-musl.md +++ b/src/doc/rustc/src/platform-support/hexagon-unknown-linux-musl.md @@ -44,7 +44,7 @@ Because it is Tier 3, rust does not yet ship pre-compiled artifacts for this target. Therefore, you can build Rust with support for the target by adding it to the -target list in `config.toml`, a sample configuration is shown below. +target list in `bootstrap.toml`, a sample configuration is shown below. ```toml [build] diff --git a/src/doc/rustc/src/platform-support/hexagon-unknown-none-elf.md b/src/doc/rustc/src/platform-support/hexagon-unknown-none-elf.md index a0e26b798ac..c7726eacaf4 100644 --- a/src/doc/rustc/src/platform-support/hexagon-unknown-none-elf.md +++ b/src/doc/rustc/src/platform-support/hexagon-unknown-none-elf.md @@ -28,7 +28,7 @@ This target generates PIC ELF binaries. ## Building the target You can build Rust with support for the target by adding it to the `target` -list in `config.toml`: +list in `bootstrap.toml`: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/i686-apple-darwin.md b/src/doc/rustc/src/platform-support/i686-apple-darwin.md index d69fa97ce63..abb64dcc986 100644 --- a/src/doc/rustc/src/platform-support/i686-apple-darwin.md +++ b/src/doc/rustc/src/platform-support/i686-apple-darwin.md @@ -17,7 +17,7 @@ You'll need the macOS 10.13 SDK shipped with Xcode 9. The location of the SDK can be passed to `rustc` using the common `SDKROOT` environment variable. Once you have that, you can build Rust with support for the target by adding -it to the `target` list in `config.toml`: +it to the `target` list in `bootstrap.toml`: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/kmc-solid.md b/src/doc/rustc/src/platform-support/kmc-solid.md index bbcd0f711c6..44f47927286 100644 --- a/src/doc/rustc/src/platform-support/kmc-solid.md +++ b/src/doc/rustc/src/platform-support/kmc-solid.md @@ -32,7 +32,7 @@ The target can be built by enabling it for a `rustc` build. target = ["aarch64-kmc-solid_asp3"] ``` -Make sure `aarch64-kmc-elf-gcc` is included in `$PATH`. Alternatively, you can use GNU Arm Embedded Toolchain by adding the following to `config.toml`: +Make sure `aarch64-kmc-elf-gcc` is included in `$PATH`. Alternatively, you can use GNU Arm Embedded Toolchain by adding the following to `bootstrap.toml`: ```toml [target.aarch64-kmc-solid_asp3] diff --git a/src/doc/rustc/src/platform-support/loongarch-linux.md b/src/doc/rustc/src/platform-support/loongarch-linux.md index 45eb0a81216..2c9f712ce82 100644 --- a/src/doc/rustc/src/platform-support/loongarch-linux.md +++ b/src/doc/rustc/src/platform-support/loongarch-linux.md @@ -65,7 +65,7 @@ These targets are distributed through `rustup`, and otherwise require no special configuration. If you need to build your own Rust for some reason though, the targets can be -simply enabled in `config.toml`. For example: +simply enabled in `bootstrap.toml`. For example: ```toml [build] @@ -73,7 +73,7 @@ target = ["loongarch64-unknown-linux-gnu"] ``` Make sure the LoongArch toolchain binaries are reachable from `$PATH`. -Alternatively, you can explicitly configure the paths in `config.toml`: +Alternatively, you can explicitly configure the paths in `bootstrap.toml`: ```toml [target.loongarch64-unknown-linux-gnu] diff --git a/src/doc/rustc/src/platform-support/loongarch-none.md b/src/doc/rustc/src/platform-support/loongarch-none.md index bafa85c26e2..6c5d8669830 100644 --- a/src/doc/rustc/src/platform-support/loongarch-none.md +++ b/src/doc/rustc/src/platform-support/loongarch-none.md @@ -46,7 +46,7 @@ scripts. ## Building the target You can build Rust with support for the targets by adding them to the `target` -list in `config.toml`: +list in `bootstrap.toml`: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/mips-release-6.md b/src/doc/rustc/src/platform-support/mips-release-6.md index 9203a31e9f4..b779477996d 100644 --- a/src/doc/rustc/src/platform-support/mips-release-6.md +++ b/src/doc/rustc/src/platform-support/mips-release-6.md @@ -67,7 +67,7 @@ The following procedure outlines the build process for the MIPS64 R6 target with ### Prerequisite: Disable debuginfo -An LLVM bug makes rustc crash if debug or debug info generation is enabled. You need to edit `config.toml` to disable this: +An LLVM bug makes rustc crash if debug or debug info generation is enabled. You need to edit `bootstrap.toml` to disable this: ```toml [rust] @@ -83,7 +83,7 @@ The crate `rustix` may try to link itself against MIPS R2 assembly, resulting in export RUSTFLAGS="--cfg rustix_use_libc" ``` -This will trigger warnings during build, as `-D warnings` is enabled by default. Disable `-D warnings` by editing `config.toml` to append the following: +This will trigger warnings during build, as `-D warnings` is enabled by default. Disable `-D warnings` by editing `bootstrap.toml` to append the following: ```toml [rust] @@ -116,7 +116,7 @@ target = ["mipsisa64r6el-unknown-linux-gnuabi64"] Make sure that `mipsisa64r6el-unknown-linux-gnuabi64-gcc` is available from your executable search path (`$PATH`). -Alternatively, you can specify the directories to all necessary toolchain executables in `config.toml`: +Alternatively, you can specify the directories to all necessary toolchain executables in `bootstrap.toml`: ```toml [target.mipsisa64r6el-unknown-linux-gnuabi64] diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 77e8caaee4c..e097d32277d 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -124,7 +124,7 @@ For conditional compilation, following QNX specific attributes are defined: ## Building the target -1. Create a `config.toml` +1. Create a `bootstrap.toml` Example content: diff --git a/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md b/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md index 1af1410d4bb..ab8641ff69a 100644 --- a/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md +++ b/src/doc/rustc/src/platform-support/nvptx64-nvidia-cuda.md @@ -32,7 +32,7 @@ What format do binaries use by default? ELF, PE, something else? ## Building the target If Rust doesn't build the target by default, how can users build it? Can users -just add it to the `target` list in `config.toml`? +just add it to the `target` list in `bootstrap.toml`? ## Building Rust programs diff --git a/src/doc/rustc/src/platform-support/openharmony.md b/src/doc/rustc/src/platform-support/openharmony.md index 1632f44aeec..ab50cbcdf97 100644 --- a/src/doc/rustc/src/platform-support/openharmony.md +++ b/src/doc/rustc/src/platform-support/openharmony.md @@ -1,6 +1,6 @@ # `*-unknown-linux-ohos` -**Tier: 2** +**Tier: 2 (with Host Tools)** * aarch64-unknown-linux-ohos * armv7-unknown-linux-ohos @@ -18,6 +18,20 @@ system. - Amanieu d'Antras ([@Amanieu](https://github.com/Amanieu)) - Lu Binglun ([@lubinglun](https://github.com/lubinglun)) +## Requirements + +All the ohos targets of Tier 2 with host tools support all extended rust tools. +(exclude `miri`, the support of `miri` will be added soon) + +### Host toolchain + +The targets require a reasonably up-to-date OpenHarmony SDK on the host. + +The targets support `cargo`, which require [ohos-openssl](https://github.com/ohos-rs/ohos-openssl). + +`miri` isn't supported yet, since its dependencies (`libffi` and `tikv-jemalloc-sys`) don't support +compiling for the OHOS targets. + ## Setup The OpenHarmony SDK doesn't currently support Rust compilation directly, so @@ -131,7 +145,7 @@ linker = "/path/to/x86_64-unknown-linux-ohos-clang.sh" ## Building the target from source Instead of using `rustup`, you can instead build a rust toolchain from source. -Create a `config.toml` with the following contents: +Create a `bootstrap.toml` with the following contents: ```toml profile = "compiler" diff --git a/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md b/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md index 89c4cdb2afc..f14fe7df422 100644 --- a/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md +++ b/src/doc/rustc/src/platform-support/pc-windows-gnullvm.md @@ -29,7 +29,7 @@ Like with any other Windows target, created binaries are in PE format. These targets can be easily cross-compiled using [llvm-mingw](https://github.com/mstorsjo/llvm-mingw) toolchain or [MSYS2 CLANG*](https://www.msys2.org/docs/environments/) environments. -Just fill `[target.*]` sections for both build and resulting compiler and set installation prefix in `config.toml`. +Just fill `[target.*]` sections for both build and resulting compiler and set installation prefix in `bootstrap.toml`. Then run `./x.py install`. In my case I had ran `./x.py install --host x86_64-pc-windows-gnullvm --target x86_64-pc-windows-gnullvm` inside MSYS2 MINGW64 shell so `x86_64-pc-windows-gnu` was my build toolchain. diff --git a/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-musl.md index 3bd3f5d8b7f..e1e3d6d31c0 100644 --- a/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-musl.md +++ b/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-musl.md @@ -23,7 +23,7 @@ The target can be built by enabling it for a `rustc` build. target = ["powerpc64le-unknown-linux-musl"] ``` -Make sure your C compiler is included in `$PATH`, then add it to the `config.toml`: +Make sure your C compiler is included in `$PATH`, then add it to the `bootstrap.toml`: ```toml [target.powerpc64le-unknown-linux-musl] diff --git a/src/doc/rustc/src/platform-support/redox.md b/src/doc/rustc/src/platform-support/redox.md index 2bba92d504c..c1a96f1cfc4 100644 --- a/src/doc/rustc/src/platform-support/redox.md +++ b/src/doc/rustc/src/platform-support/redox.md @@ -27,7 +27,7 @@ Redox OS binaries use ELF as file format. ## Building the target -You can build Rust with support for the targets by adding it to the `target` list in `config.toml`. In addition a copy of [relibc] needs to be present in the linker search path. +You can build Rust with support for the targets by adding it to the `target` list in `bootstrap.toml`. In addition a copy of [relibc] needs to be present in the linker search path. ```toml [build] diff --git a/src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md b/src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md index 1fdd594012c..79455b0fbc4 100644 --- a/src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md +++ b/src/doc/rustc/src/platform-support/riscv32im-risc0-zkvm-elf.md @@ -43,7 +43,7 @@ Calling `extern "C"` on the target uses the C calling convention outlined in the ## Building for the zkVM Programs for the zkVM could be built by adding it to the `target` list in -`config.toml`. However, we recommend building programs in our starter template +`bootstrap.toml`. However, we recommend building programs in our starter template generated by the [cargo-risczero] utility and the [risc0-build] crate. This crate calls `rustc` with `-C "link-arg=-Ttext=` so that it maps the text in the appropriate location as well as generating variables that represent the ELF and diff --git a/src/doc/rustc/src/platform-support/riscv32imac-unknown-xous-elf.md b/src/doc/rustc/src/platform-support/riscv32imac-unknown-xous-elf.md index f024cd25bf7..12928edfcac 100644 --- a/src/doc/rustc/src/platform-support/riscv32imac-unknown-xous-elf.md +++ b/src/doc/rustc/src/platform-support/riscv32imac-unknown-xous-elf.md @@ -24,7 +24,7 @@ The target can be built by enabling it for a `rustc` build. target = ["riscv32imac-unknown-xous-elf"] ``` -Make sure your C compiler is included in `$PATH`, then add it to the `config.toml`: +Make sure your C compiler is included in `$PATH`, then add it to the `bootstrap.toml`: ```toml [target.riscv32imac-unknown-xous-elf] diff --git a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md index dda2a50c33d..1ab867fe71e 100644 --- a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md +++ b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md @@ -26,7 +26,7 @@ These targets are distributed through `rustup`, and otherwise require no special configuration. If you need to build your own Rust for some reason though, the targets can be -enabled in `config.toml`. For example: +enabled in `bootstrap.toml`. For example: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md index 5b3dc683038..5e6275d6979 100644 --- a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md +++ b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md @@ -22,7 +22,7 @@ The target can be built by enabling it for a `rustc` build. target = ["riscv64gc-unknown-linux-musl"] ``` -Make sure your C compiler is included in `$PATH`, then add it to the `config.toml`: +Make sure your C compiler is included in `$PATH`, then add it to the `bootstrap.toml`: ```toml [target.riscv64gc-unknown-linux-musl] diff --git a/src/doc/rustc/src/platform-support/s390x-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/s390x-unknown-linux-gnu.md index 6f09ce42dbb..1aa2704cf95 100644 --- a/src/doc/rustc/src/platform-support/s390x-unknown-linux-gnu.md +++ b/src/doc/rustc/src/platform-support/s390x-unknown-linux-gnu.md @@ -34,7 +34,7 @@ This target is distributed through `rustup`, and otherwise requires no special configuration. If you need to build your own Rust for some reason though, the target can be -enabled in `config.toml`. For example: +enabled in `bootstrap.toml`. For example: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md index e00f8db7f8e..3c334620cfc 100644 --- a/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md +++ b/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md @@ -33,7 +33,7 @@ Because it is Tier 3, Rust does not yet ship pre-compiled artifacts for this target. Therefore, you can build Rust with support for the target by adding it to the -target list in `config.toml`, a sample configuration is shown below. +target list in `bootstrap.toml`, a sample configuration is shown below. ```toml [build] diff --git a/src/doc/rustc/src/platform-support/sparc-unknown-none-elf.md b/src/doc/rustc/src/platform-support/sparc-unknown-none-elf.md index f579b1fb8d4..c19b7d7681a 100644 --- a/src/doc/rustc/src/platform-support/sparc-unknown-none-elf.md +++ b/src/doc/rustc/src/platform-support/sparc-unknown-none-elf.md @@ -34,7 +34,7 @@ considerations for binary layout will require linker options or linker scripts. ## Building the target You can build Rust with support for the target by adding it to the `target` -list in `config.toml`: +list in `bootstrap.toml`: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/unikraft-linux-musl.md b/src/doc/rustc/src/platform-support/unikraft-linux-musl.md index c589208c099..b40e99825e5 100644 --- a/src/doc/rustc/src/platform-support/unikraft-linux-musl.md +++ b/src/doc/rustc/src/platform-support/unikraft-linux-musl.md @@ -34,7 +34,7 @@ Instead, the Unikraft build system will produce the final Unikernel image for th ## Building the targets -You can build Rust with support for the targets by adding it to the `target` list in `config.toml`: +You can build Rust with support for the targets by adding it to the `target` list in `bootstrap.toml`: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/unknown-uefi.md b/src/doc/rustc/src/platform-support/unknown-uefi.md index e6917502182..e9979cc912c 100644 --- a/src/doc/rustc/src/platform-support/unknown-uefi.md +++ b/src/doc/rustc/src/platform-support/unknown-uefi.md @@ -252,7 +252,7 @@ This section contains information on how to use std on UEFI. ### Build std The building std part is pretty much the same as the official [docs](https://rustc-dev-guide.rust-lang.org/getting-started.html). -The linker that should be used is `rust-lld`. Here is a sample `config.toml`: +The linker that should be used is `rust-lld`. Here is a sample `bootstrap.toml`: ```toml [rust] lld = true diff --git a/src/doc/rustc/src/platform-support/vxworks.md b/src/doc/rustc/src/platform-support/vxworks.md index 6aa3d8b7361..a2b91f3769d 100644 --- a/src/doc/rustc/src/platform-support/vxworks.md +++ b/src/doc/rustc/src/platform-support/vxworks.md @@ -33,7 +33,7 @@ Rust for each target can be cross-compiled with its specific target vsb configur ## Building the target -You can build Rust with support for the targets by adding it to the `target` list in `config.toml`. In addition the workbench and wr-cc have to configured and activated. +You can build Rust with support for the targets by adding it to the `target` list in `bootstrap.toml`. In addition the workbench and wr-cc have to configured and activated. ```toml [build] diff --git a/src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md b/src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md index d364852b1c1..6949c657db8 100644 --- a/src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md +++ b/src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md @@ -61,7 +61,7 @@ Building this target can be done by: * Configure the `wasm32-unknown-emscripten` target to get built. * Ensure the `WebAssembly` target backend is not disabled in LLVM. -These are all controlled through `config.toml` options. It should be possible +These are all controlled through `bootstrap.toml` options. It should be possible to build this target on any platform. A minimal example configuration would be: ```toml diff --git a/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md b/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md index ba95ab7af6d..150f69e03c6 100644 --- a/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md +++ b/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md @@ -65,7 +65,7 @@ Building this target can be done by: * Configure LLD to be built. * Ensure the `WebAssembly` target backend is not disabled in LLVM. -These are all controlled through `config.toml` options. It should be possible +These are all controlled through `bootstrap.toml` options. It should be possible to build this target on any platform. ## Building Rust programs diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md index 1b0a312ca9c..af20b62b9f6 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md @@ -107,7 +107,7 @@ flag, for example: Users need to install or built wasi-sdk since release 20.0 https://github.com/WebAssembly/wasi-sdk/releases/tag/wasi-sdk-20 -and specify path to *wasi-root* `config.toml` +and specify path to *wasi-root* `bootstrap.toml` ```toml [target.wasm32-wasip1-threads] @@ -115,7 +115,7 @@ wasi-root = ".../wasi-libc/sysroot" ``` After that users can build this by adding it to the `target` list in -`config.toml`, or with `-Zbuild-std`. +`bootstrap.toml`, or with `-Zbuild-std`. ## Building Rust programs diff --git a/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md b/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md index a717f5dad79..157fff419d3 100644 --- a/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md +++ b/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md @@ -64,7 +64,7 @@ This target does not support `panic=unwind` at this time. ## Building the target You can build Rust with support for the target by adding it to the `target` -list in `config.toml`, and the target also requires `lld` to be built to work. +list in `bootstrap.toml`, and the target also requires `lld` to be built to work. ```toml [build] diff --git a/src/doc/rustc/src/platform-support/win7-windows-gnu.md b/src/doc/rustc/src/platform-support/win7-windows-gnu.md index 180a1dc6d26..3a819b0a4e2 100644 --- a/src/doc/rustc/src/platform-support/win7-windows-gnu.md +++ b/src/doc/rustc/src/platform-support/win7-windows-gnu.md @@ -23,7 +23,7 @@ Like any other Windows target, the created binaries are in PE format. ## Building the target -You can build Rust with support for the targets by adding it to the target list in config.toml: +You can build Rust with support for the targets by adding it to the target list in bootstrap.toml: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/win7-windows-msvc.md b/src/doc/rustc/src/platform-support/win7-windows-msvc.md index 77b7d68212b..cbbb44b47aa 100644 --- a/src/doc/rustc/src/platform-support/win7-windows-msvc.md +++ b/src/doc/rustc/src/platform-support/win7-windows-msvc.md @@ -24,7 +24,7 @@ Like any other Windows target, the created binaries are in PE format. ## Building the target -You can build Rust with support for the targets by adding it to the target list in config.toml: +You can build Rust with support for the targets by adding it to the target list in bootstrap.toml: ```toml [build] @@ -73,7 +73,7 @@ Windows SDK, which can be acquired using [`xwin`](https://github.com/Jake-Shadle clang-cl /imsvc "$XWIN/crt/include" /imsvc "$XWIN/sdk/include/ucrt" /imsvc "$XWIN/sdk/include/um" /imsvc "$XWIN/sdk/include/shared" --target="x86_64-pc-windows-msvc" "$@" ``` -- In your config.toml, add the following lines: +- In your bootstrap.toml, add the following lines: ```toml [target.x86_64-win7-windows-msvc] diff --git a/src/doc/rustc/src/platform-support/x86_64-unknown-none.md b/src/doc/rustc/src/platform-support/x86_64-unknown-none.md index bd5fd1d0502..3b8aae3a389 100644 --- a/src/doc/rustc/src/platform-support/x86_64-unknown-none.md +++ b/src/doc/rustc/src/platform-support/x86_64-unknown-none.md @@ -39,7 +39,7 @@ scripts. ## Building the target You can build Rust with support for the target by adding it to the `target` -list in `config.toml`: +list in `bootstrap.toml`: ```toml [build] diff --git a/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md b/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md index 6c2a6a41101..545fffb84f9 100644 --- a/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md +++ b/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md @@ -29,7 +29,7 @@ respects. ## Building the target Users on Apple targets can build this by adding it to the `target` list in -`config.toml`, or with `-Zbuild-std`. +`bootstrap.toml`, or with `-Zbuild-std`. ## Building Rust programs diff --git a/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md b/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md index dbb741422a8..e7414aa9119 100644 --- a/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md +++ b/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md @@ -56,4 +56,4 @@ $Env:RUSTFLAGS = "-Z control-flow-guard" cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc ``` -Alternatively, if you are building the standard library from source, you can set `control-flow-guard = true` in the config.toml file. +Alternatively, if you are building the standard library from source, you can set `control-flow-guard = true` in the bootstrap.toml file. diff --git a/src/doc/unstable-book/src/language-features/asm-goto-with-outputs.md b/src/doc/unstable-book/src/language-features/asm-goto-with-outputs.md new file mode 100644 index 00000000000..3cce5d1d74c --- /dev/null +++ b/src/doc/unstable-book/src/language-features/asm-goto-with-outputs.md @@ -0,0 +1,27 @@ +# `asm_goto_with_outputs` + +The tracking issue for this feature is: [#119364] + +[#119364]: https://github.com/rust-lang/rust/issues/119364 + +------------------------ + +This feature allows label operands to be used together with output operands. + +Example: +```rust,ignore (partial-example, x86-only) + +unsafe { + let a: usize; + asm!( + "mov {}, 1" + "jmp {}", + out(reg) a, + label { + println!("Jumped from asm {}!", a); + } + ); +} +``` + +The output operands are assigned before the label blocks are executed. diff --git a/src/doc/unstable-book/src/language-features/asm-goto.md b/src/doc/unstable-book/src/language-features/asm-goto.md deleted file mode 100644 index 823118bcae1..00000000000 --- a/src/doc/unstable-book/src/language-features/asm-goto.md +++ /dev/null @@ -1,32 +0,0 @@ -# `asm_goto` - -The tracking issue for this feature is: [#119364] - -[#119364]: https://github.com/rust-lang/rust/issues/119364 - ------------------------- - -This feature adds a `label <block>` operand type to `asm!`. - -Example: -```rust,ignore (partial-example, x86-only) - -unsafe { - asm!( - "jmp {}", - label { - println!("Jumped from asm!"); - } - ); -} -``` - -The block must have unit type or diverge. The block starts a new safety context, -so despite outer `unsafe`, you need extra unsafe to perform unsafe operations -within `label <block>`. - -When `label <block>` is used together with `noreturn` option, it means that the -assembly will not fallthrough. It's allowed to jump to a label within the -assembly. In this case, the entire `asm!` expression will have an unit type as -opposed to diverging, if not all label blocks diverge. The `asm!` expression -still diverges if `noreturn` option is used and all label blocks diverge. diff --git a/src/doc/unstable-book/src/language-features/offset-of-enum.md b/src/doc/unstable-book/src/language-features/offset-of-enum.md new file mode 100644 index 00000000000..1960d6299eb --- /dev/null +++ b/src/doc/unstable-book/src/language-features/offset-of-enum.md @@ -0,0 +1,29 @@ +# `offset_of_slice` + +The tracking issue for this feature is: [#120141] + +[#120141]: https://github.com/rust-lang/rust/issues/120141 + +------------------------ + +When the `offset_of_enum` feature is enabled, the [`offset_of!`] macro may be used to obtain the +offsets of fields of `enum`s; to express this, `enum` variants may be traversed as if they were +fields. Variants themselves do not have an offset, so they cannot appear as the last path component. + +```rust +#![feature(offset_of_enum)] +use std::mem; + +#[repr(u8)] +enum Enum { + A(u8, u16), + B { one: u8, two: u16 }, +} + +assert_eq!(mem::offset_of!(Enum, A.0), 1); +assert_eq!(mem::offset_of!(Enum, B.two), 2); + +assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0); +``` + +[`offset_of!`]: ../../std/mem/macro.offset_of.html diff --git a/src/doc/unstable-book/src/language-features/offset-of-slice.md b/src/doc/unstable-book/src/language-features/offset-of-slice.md new file mode 100644 index 00000000000..c887fa07f67 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/offset-of-slice.md @@ -0,0 +1,30 @@ +# `offset_of_slice` + +The tracking issue for this feature is: [#126151] + +[#126151]: https://github.com/rust-lang/rust/issues/126151 + +------------------------ + +When the `offset_of_slice` feature is enabled, the [`offset_of!`] macro may be used to determine +the offset of fields whose type is `[T]`, that is, a slice of dynamic size. + +In general, fields whose type is dynamically sized do not have statically known offsets because +they do not have statically known alignments. However, `[T]` has the same alignment as `T`, so +it specifically may be allowed. + +```rust +#![feature(offset_of_slice)] + +#[repr(C)] +pub struct Struct { + head: u32, + tail: [u8], +} + +fn main() { + assert_eq!(std::mem::offset_of!(Struct, tail), 4); +} +``` + +[`offset_of!`]: ../../std/mem/macro.offset_of.html diff --git a/src/doc/unstable-book/src/language-features/register-tool.md b/src/doc/unstable-book/src/language-features/register-tool.md new file mode 100644 index 00000000000..58b923aab57 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/register-tool.md @@ -0,0 +1,55 @@ +# `register_tool` + +The tracking issue for this feature is: [#66079] + +[#66079]: https://github.com/rust-lang/rust/issues/66079 + +------------------------ + +The `register_tool` language feature informs the compiler that attributes in your code are meant to be used with tools other than the compiler itself. This can be useful if your code has semantic meaning without the external tool, but enables additional features when the tool is present. + +`register_tool` also allows configuring lint levels for external tools. + +Tool attributes are only meant for ignorable attributes. If your code *changes* meaning when the attribute is present, it should not use a tool attribute (because it cannot be compiled with anything other than the external tool, and in a sense is a fork of the language). + +------------------------ + +`#![register_tool(tool)]` is an attribute, and is only valid at the crate root. +Attributes using the registered tool are checked for valid syntax, and lint attributes are checked to be in a valid format. However, the compiler cannot validate the semantics of the attribute, nor can it tell whether the configured lint is present in the external tool. + +Semantically, `clippy::*`, `rustdoc::*`, and `rustfmt::*` lints and attributes all behave as if `#![register_tool(clippy, rustdoc, rustfmt)]` were injected into the crate root, except that the `rustdoc` namespace can only be used for lints, not for attributes. +When compiling with `-Z unstable-features`, `rustc::*` lints can also be used. Like `rustdoc`, the `rustc` namespace can only be used with lints, not attributes. + +The compiler will emit an error if it encounters a lint/attribute whose namespace isn't a registered tool. + +Tool namespaces cannot be nested; `register_tool(main_tool::subtool)` is an error. + +## Examples + +Tool attributes: + +```rust +#![feature(register_tool)] +#![register_tool(c2rust)] + +// Mark which C header file this module was generated from. +#[c2rust::header_src = "operations.h"] +pub mod operations_h { + use std::ffi::c_int; + + // Mark which source line this struct was generated from. + #[c2rust::src_loc = "11:0"] + pub struct Point { + pub x: c_int, + pub y: c_int, + } +} +``` + +Tool lints: + +``` +#![feature(register_tool)] +#![register_tool(bevy)] +#![deny(bevy::duplicate_bevy_dependencies)] +``` diff --git a/src/etc/completions/x.fish b/src/etc/completions/x.fish index 933557ab0d7..937ee73d0ee 100644 --- a/src/etc/completions/x.fish +++ b/src/etc/completions/x.fish @@ -25,7 +25,7 @@ function __fish_x_using_subcommand end complete -c x -n "__fish_x_needs_command" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_needs_command" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_needs_command" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_needs_command" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_needs_command" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_needs_command" -l target -d 'target targets to build' -r -f @@ -45,7 +45,7 @@ complete -c x -n "__fish_x_needs_command" -l rust-profile-generate -d 'generate complete -c x -n "__fish_x_needs_command" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_needs_command" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_needs_command" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_needs_command" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_needs_command" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_needs_command" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_needs_command" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_needs_command" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -75,7 +75,7 @@ complete -c x -n "__fish_x_needs_command" -a "suggest" -d 'Suggest a subset of t complete -c x -n "__fish_x_needs_command" -a "vendor" -d 'Vendor dependencies' complete -c x -n "__fish_x_needs_command" -a "perf" -d 'Perform profiling and benchmarking of the compiler using `rustc-perf`' complete -c x -n "__fish_x_using_subcommand build" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand build" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand build" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand build" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand build" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand build" -l target -d 'target targets to build' -r -f @@ -95,7 +95,7 @@ complete -c x -n "__fish_x_using_subcommand build" -l rust-profile-generate -d ' complete -c x -n "__fish_x_using_subcommand build" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand build" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand build" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand build" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand build" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand build" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand build" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand build" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -108,7 +108,7 @@ complete -c x -n "__fish_x_using_subcommand build" -l enable-bolt-settings -d 'E complete -c x -n "__fish_x_using_subcommand build" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x -n "__fish_x_using_subcommand build" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x -n "__fish_x_using_subcommand check" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand check" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand check" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand check" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand check" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand check" -l target -d 'target targets to build' -r -f @@ -128,7 +128,7 @@ complete -c x -n "__fish_x_using_subcommand check" -l rust-profile-generate -d ' complete -c x -n "__fish_x_using_subcommand check" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand check" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand check" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand check" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand check" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand check" -l all-targets -d 'Check all targets' complete -c x -n "__fish_x_using_subcommand check" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand check" -s i -l incremental -d 'use incremental compilation' @@ -146,7 +146,7 @@ complete -c x -n "__fish_x_using_subcommand clippy" -s D -d 'clippy lints to den complete -c x -n "__fish_x_using_subcommand clippy" -s W -d 'clippy lints to warn on' -r complete -c x -n "__fish_x_using_subcommand clippy" -s F -d 'clippy lints to forbid' -r complete -c x -n "__fish_x_using_subcommand clippy" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand clippy" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand clippy" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand clippy" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand clippy" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand clippy" -l target -d 'target targets to build' -r -f @@ -166,7 +166,7 @@ complete -c x -n "__fish_x_using_subcommand clippy" -l rust-profile-generate -d complete -c x -n "__fish_x_using_subcommand clippy" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand clippy" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand clippy" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand clippy" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand clippy" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand clippy" -l fix complete -c x -n "__fish_x_using_subcommand clippy" -l allow-dirty complete -c x -n "__fish_x_using_subcommand clippy" -l allow-staged @@ -182,7 +182,7 @@ complete -c x -n "__fish_x_using_subcommand clippy" -l enable-bolt-settings -d ' complete -c x -n "__fish_x_using_subcommand clippy" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x -n "__fish_x_using_subcommand clippy" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x -n "__fish_x_using_subcommand fix" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand fix" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand fix" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand fix" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand fix" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand fix" -l target -d 'target targets to build' -r -f @@ -202,7 +202,7 @@ complete -c x -n "__fish_x_using_subcommand fix" -l rust-profile-generate -d 'ge complete -c x -n "__fish_x_using_subcommand fix" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand fix" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand fix" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand fix" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand fix" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand fix" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand fix" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand fix" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -215,7 +215,7 @@ complete -c x -n "__fish_x_using_subcommand fix" -l enable-bolt-settings -d 'Ena complete -c x -n "__fish_x_using_subcommand fix" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x -n "__fish_x_using_subcommand fix" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x -n "__fish_x_using_subcommand fmt" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand fmt" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand fmt" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand fmt" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand fmt" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand fmt" -l target -d 'target targets to build' -r -f @@ -235,7 +235,7 @@ complete -c x -n "__fish_x_using_subcommand fmt" -l rust-profile-generate -d 'ge complete -c x -n "__fish_x_using_subcommand fmt" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand fmt" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand fmt" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand fmt" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand fmt" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand fmt" -l check -d 'check formatting instead of applying' complete -c x -n "__fish_x_using_subcommand fmt" -l all -d 'apply to all appropriate files, not just those that have been modified' complete -c x -n "__fish_x_using_subcommand fmt" -s v -l verbose -d 'use verbose output (-vv for very verbose)' @@ -250,7 +250,7 @@ complete -c x -n "__fish_x_using_subcommand fmt" -l enable-bolt-settings -d 'Ena complete -c x -n "__fish_x_using_subcommand fmt" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x -n "__fish_x_using_subcommand fmt" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x -n "__fish_x_using_subcommand doc" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand doc" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand doc" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand doc" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand doc" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand doc" -l target -d 'target targets to build' -r -f @@ -270,7 +270,7 @@ complete -c x -n "__fish_x_using_subcommand doc" -l rust-profile-generate -d 'ge complete -c x -n "__fish_x_using_subcommand doc" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand doc" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand doc" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand doc" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand doc" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand doc" -l open -d 'open the docs in a browser' complete -c x -n "__fish_x_using_subcommand doc" -l json -d 'render the documentation in JSON format in addition to the usual HTML format' complete -c x -n "__fish_x_using_subcommand doc" -s v -l verbose -d 'use verbose output (-vv for very verbose)' @@ -291,7 +291,7 @@ complete -c x -n "__fish_x_using_subcommand test" -l compare-mode -d 'mode descr complete -c x -n "__fish_x_using_subcommand test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r complete -c x -n "__fish_x_using_subcommand test" -l run -d 'whether to execute run-* tests' -r complete -c x -n "__fish_x_using_subcommand test" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand test" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand test" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand test" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand test" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand test" -l target -d 'target targets to build' -r -f @@ -311,7 +311,7 @@ complete -c x -n "__fish_x_using_subcommand test" -l rust-profile-generate -d 'g complete -c x -n "__fish_x_using_subcommand test" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand test" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand test" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand test" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand test" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand test" -l no-fail-fast -d 'run all tests regardless of failure' complete -c x -n "__fish_x_using_subcommand test" -l no-doc -d 'do not run doc tests' complete -c x -n "__fish_x_using_subcommand test" -l doc -d 'only run doc tests' @@ -333,7 +333,7 @@ complete -c x -n "__fish_x_using_subcommand test" -l skip-stage0-validation -d ' complete -c x -n "__fish_x_using_subcommand test" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x -n "__fish_x_using_subcommand miri" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r complete -c x -n "__fish_x_using_subcommand miri" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand miri" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand miri" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand miri" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand miri" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand miri" -l target -d 'target targets to build' -r -f @@ -353,7 +353,7 @@ complete -c x -n "__fish_x_using_subcommand miri" -l rust-profile-generate -d 'g complete -c x -n "__fish_x_using_subcommand miri" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand miri" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand miri" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand miri" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand miri" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand miri" -l no-fail-fast -d 'run all tests regardless of failure' complete -c x -n "__fish_x_using_subcommand miri" -l no-doc -d 'do not run doc tests' complete -c x -n "__fish_x_using_subcommand miri" -l doc -d 'only run doc tests' @@ -370,7 +370,7 @@ complete -c x -n "__fish_x_using_subcommand miri" -l skip-stage0-validation -d ' complete -c x -n "__fish_x_using_subcommand miri" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x -n "__fish_x_using_subcommand bench" -l test-args -r complete -c x -n "__fish_x_using_subcommand bench" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand bench" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand bench" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand bench" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand bench" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand bench" -l target -d 'target targets to build' -r -f @@ -390,7 +390,7 @@ complete -c x -n "__fish_x_using_subcommand bench" -l rust-profile-generate -d ' complete -c x -n "__fish_x_using_subcommand bench" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand bench" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand bench" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand bench" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand bench" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand bench" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand bench" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand bench" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -404,7 +404,7 @@ complete -c x -n "__fish_x_using_subcommand bench" -l skip-stage0-validation -d complete -c x -n "__fish_x_using_subcommand bench" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x -n "__fish_x_using_subcommand clean" -l stage -d 'Clean a specific stage without touching other artifacts. By default, every stage is cleaned if this option is not used' -r complete -c x -n "__fish_x_using_subcommand clean" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand clean" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand clean" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand clean" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand clean" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand clean" -l target -d 'target targets to build' -r -f @@ -423,7 +423,7 @@ complete -c x -n "__fish_x_using_subcommand clean" -l rust-profile-generate -d ' complete -c x -n "__fish_x_using_subcommand clean" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand clean" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand clean" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand clean" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand clean" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand clean" -l all -d 'Clean the entire build directory (not used by default)' complete -c x -n "__fish_x_using_subcommand clean" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand clean" -s i -l incremental -d 'use incremental compilation' @@ -437,7 +437,7 @@ complete -c x -n "__fish_x_using_subcommand clean" -l enable-bolt-settings -d 'E complete -c x -n "__fish_x_using_subcommand clean" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x -n "__fish_x_using_subcommand clean" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x -n "__fish_x_using_subcommand dist" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand dist" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand dist" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand dist" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand dist" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand dist" -l target -d 'target targets to build' -r -f @@ -457,7 +457,7 @@ complete -c x -n "__fish_x_using_subcommand dist" -l rust-profile-generate -d 'g complete -c x -n "__fish_x_using_subcommand dist" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand dist" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand dist" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand dist" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand dist" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand dist" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand dist" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand dist" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -470,7 +470,7 @@ complete -c x -n "__fish_x_using_subcommand dist" -l enable-bolt-settings -d 'En complete -c x -n "__fish_x_using_subcommand dist" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x -n "__fish_x_using_subcommand dist" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x -n "__fish_x_using_subcommand install" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand install" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand install" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand install" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand install" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand install" -l target -d 'target targets to build' -r -f @@ -490,7 +490,7 @@ complete -c x -n "__fish_x_using_subcommand install" -l rust-profile-generate -d complete -c x -n "__fish_x_using_subcommand install" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand install" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand install" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand install" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand install" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand install" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand install" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand install" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -504,7 +504,7 @@ complete -c x -n "__fish_x_using_subcommand install" -l skip-stage0-validation - complete -c x -n "__fish_x_using_subcommand install" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x -n "__fish_x_using_subcommand run" -l args -d 'arguments for the tool' -r complete -c x -n "__fish_x_using_subcommand run" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand run" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand run" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand run" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand run" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand run" -l target -d 'target targets to build' -r -f @@ -524,7 +524,7 @@ complete -c x -n "__fish_x_using_subcommand run" -l rust-profile-generate -d 'ge complete -c x -n "__fish_x_using_subcommand run" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand run" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand run" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand run" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand run" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand run" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand run" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand run" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -537,7 +537,7 @@ complete -c x -n "__fish_x_using_subcommand run" -l enable-bolt-settings -d 'Ena complete -c x -n "__fish_x_using_subcommand run" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x -n "__fish_x_using_subcommand run" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x -n "__fish_x_using_subcommand setup" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand setup" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand setup" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand setup" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand setup" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand setup" -l target -d 'target targets to build' -r -f @@ -557,7 +557,7 @@ complete -c x -n "__fish_x_using_subcommand setup" -l rust-profile-generate -d ' complete -c x -n "__fish_x_using_subcommand setup" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand setup" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand setup" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand setup" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand setup" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand setup" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand setup" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand setup" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -570,7 +570,7 @@ complete -c x -n "__fish_x_using_subcommand setup" -l enable-bolt-settings -d 'E complete -c x -n "__fish_x_using_subcommand setup" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x -n "__fish_x_using_subcommand setup" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x -n "__fish_x_using_subcommand suggest" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand suggest" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand suggest" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand suggest" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand suggest" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand suggest" -l target -d 'target targets to build' -r -f @@ -590,7 +590,7 @@ complete -c x -n "__fish_x_using_subcommand suggest" -l rust-profile-generate -d complete -c x -n "__fish_x_using_subcommand suggest" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand suggest" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand suggest" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand suggest" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand suggest" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand suggest" -l run -d 'run suggested tests' complete -c x -n "__fish_x_using_subcommand suggest" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand suggest" -s i -l incremental -d 'use incremental compilation' @@ -605,7 +605,7 @@ complete -c x -n "__fish_x_using_subcommand suggest" -l skip-stage0-validation - complete -c x -n "__fish_x_using_subcommand suggest" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x -n "__fish_x_using_subcommand vendor" -l sync -d 'Additional `Cargo.toml` to sync and vendor' -r -F complete -c x -n "__fish_x_using_subcommand vendor" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand vendor" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand vendor" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand vendor" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand vendor" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand vendor" -l target -d 'target targets to build' -r -f @@ -625,7 +625,7 @@ complete -c x -n "__fish_x_using_subcommand vendor" -l rust-profile-generate -d complete -c x -n "__fish_x_using_subcommand vendor" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand vendor" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand vendor" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand vendor" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand vendor" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand vendor" -l versioned-dirs -d 'Always include version in subdir name' complete -c x -n "__fish_x_using_subcommand vendor" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand vendor" -s i -l incremental -d 'use incremental compilation' @@ -639,7 +639,7 @@ complete -c x -n "__fish_x_using_subcommand vendor" -l enable-bolt-settings -d ' complete -c x -n "__fish_x_using_subcommand vendor" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x -n "__fish_x_using_subcommand vendor" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l target -d 'target targets to build' -r -f @@ -659,7 +659,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -681,7 +681,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',Opt\t'',Clippy\t''}" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l target -d 'target targets to build' -r -f @@ -700,7 +700,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -717,7 +717,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',Opt\t'',Clippy\t''}" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l target -d 'target targets to build' -r -f @@ -736,7 +736,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -753,7 +753,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',Opt\t'',Clippy\t''}" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l target -d 'target targets to build' -r -f @@ -772,7 +772,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -789,7 +789,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',Opt\t'',Clippy\t''}" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l target -d 'target targets to build' -r -f @@ -808,7 +808,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -821,7 +821,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l config -d 'TOML configuration file for build' -r -F -complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l build -d 'build target of the stage0 compiler' -r -f complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l host -d 'host targets to build' -r -f complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l target -d 'target targets to build' -r -f @@ -841,7 +841,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l set -d 'override options in config.toml' -r -f +complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l include-default-paths -d 'include default paths in addition to the provided ones' diff --git a/src/etc/completions/x.ps1 b/src/etc/completions/x.ps1 index b848b95d88f..1fe526ed9de 100644 --- a/src/etc/completions/x.ps1 +++ b/src/etc/completions/x.ps1 @@ -22,7 +22,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { $completions = @(switch ($command) { 'x' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -43,7 +43,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -79,7 +79,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { } 'x;build' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -100,7 +100,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -119,7 +119,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { } 'x;check' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -140,7 +140,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--all-targets', '--all-targets', [CompletionResultType]::ParameterName, 'Check all targets') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') @@ -164,7 +164,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('-W', '-W ', [CompletionResultType]::ParameterName, 'clippy lints to warn on') [CompletionResult]::new('-F', '-F ', [CompletionResultType]::ParameterName, 'clippy lints to forbid') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -185,7 +185,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--fix', '--fix', [CompletionResultType]::ParameterName, 'fix') [CompletionResult]::new('--allow-dirty', '--allow-dirty', [CompletionResultType]::ParameterName, 'allow-dirty') [CompletionResult]::new('--allow-staged', '--allow-staged', [CompletionResultType]::ParameterName, 'allow-staged') @@ -207,7 +207,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { } 'x;fix' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -228,7 +228,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -247,7 +247,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { } 'x;fmt' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -268,7 +268,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--check', '--check', [CompletionResultType]::ParameterName, 'check formatting instead of applying') [CompletionResult]::new('--all', '--all', [CompletionResultType]::ParameterName, 'apply to all appropriate files, not just those that have been modified') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') @@ -289,7 +289,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { } 'x;doc' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -310,7 +310,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--open', '--open', [CompletionResultType]::ParameterName, 'open the docs in a browser') [CompletionResult]::new('--json', '--json', [CompletionResultType]::ParameterName, 'render the documentation in JSON format in addition to the usual HTML format') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') @@ -337,7 +337,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--pass', '--pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode') [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -358,7 +358,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--no-fail-fast', '--no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure') [CompletionResult]::new('--no-doc', '--no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests') [CompletionResult]::new('--doc', '--doc', [CompletionResultType]::ParameterName, 'only run doc tests') @@ -386,7 +386,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { 'x;miri' { [CompletionResult]::new('--test-args', '--test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -407,7 +407,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--no-fail-fast', '--no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure') [CompletionResult]::new('--no-doc', '--no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests') [CompletionResult]::new('--doc', '--doc', [CompletionResultType]::ParameterName, 'only run doc tests') @@ -430,7 +430,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { 'x;bench' { [CompletionResult]::new('--test-args', '--test-args', [CompletionResultType]::ParameterName, 'test-args') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -451,7 +451,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -471,7 +471,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { 'x;clean' { [CompletionResult]::new('--stage', '--stage', [CompletionResultType]::ParameterName, 'Clean a specific stage without touching other artifacts. By default, every stage is cleaned if this option is not used') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -491,7 +491,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--all', '--all', [CompletionResultType]::ParameterName, 'Clean the entire build directory (not used by default)') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') @@ -511,7 +511,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { } 'x;dist' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -532,7 +532,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -551,7 +551,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { } 'x;install' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -572,7 +572,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -592,7 +592,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { 'x;run' { [CompletionResult]::new('--args', '--args', [CompletionResultType]::ParameterName, 'arguments for the tool') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -613,7 +613,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -632,7 +632,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { } 'x;setup' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -653,7 +653,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -672,7 +672,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { } 'x;suggest' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -693,7 +693,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'run suggested tests') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') @@ -714,7 +714,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { 'x;vendor' { [CompletionResult]::new('--sync', '--sync', [CompletionResultType]::ParameterName, 'Additional `Cargo.toml` to sync and vendor') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -735,7 +735,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--versioned-dirs', '--versioned-dirs', [CompletionResultType]::ParameterName, 'Always include version in subdir name') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') @@ -755,7 +755,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { } 'x;perf' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -776,7 +776,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -804,7 +804,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked') [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -824,7 +824,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -847,7 +847,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked') [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -867,7 +867,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -890,7 +890,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked') [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -910,7 +910,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -933,7 +933,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked') [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -953,7 +953,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -972,7 +972,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { } 'x;perf;compare' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -993,7 +993,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index ff4f7425da6..99cd4f0043b 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -25,7 +25,7 @@ function __fish_x.py_using_subcommand end complete -c x.py -n "__fish_x.py_needs_command" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_needs_command" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_needs_command" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_needs_command" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_needs_command" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_needs_command" -l target -d 'target targets to build' -r -f @@ -45,7 +45,7 @@ complete -c x.py -n "__fish_x.py_needs_command" -l rust-profile-generate -d 'gen complete -c x.py -n "__fish_x.py_needs_command" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_needs_command" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_needs_command" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_needs_command" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_needs_command" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_needs_command" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_needs_command" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_needs_command" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -75,7 +75,7 @@ complete -c x.py -n "__fish_x.py_needs_command" -a "suggest" -d 'Suggest a subse complete -c x.py -n "__fish_x.py_needs_command" -a "vendor" -d 'Vendor dependencies' complete -c x.py -n "__fish_x.py_needs_command" -a "perf" -d 'Perform profiling and benchmarking of the compiler using `rustc-perf`' complete -c x.py -n "__fish_x.py_using_subcommand build" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand build" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand build" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand build" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand build" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand build" -l target -d 'target targets to build' -r -f @@ -95,7 +95,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand build" -l rust-profile-generat complete -c x.py -n "__fish_x.py_using_subcommand build" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand build" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand build" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand build" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand build" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand build" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand build" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand build" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -108,7 +108,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand build" -l enable-bolt-settings complete -c x.py -n "__fish_x.py_using_subcommand build" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x.py -n "__fish_x.py_using_subcommand build" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand check" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand check" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand check" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand check" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand check" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand check" -l target -d 'target targets to build' -r -f @@ -128,7 +128,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand check" -l rust-profile-generat complete -c x.py -n "__fish_x.py_using_subcommand check" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand check" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand check" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand check" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand check" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand check" -l all-targets -d 'Check all targets' complete -c x.py -n "__fish_x.py_using_subcommand check" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand check" -s i -l incremental -d 'use incremental compilation' @@ -146,7 +146,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand clippy" -s D -d 'clippy lints complete -c x.py -n "__fish_x.py_using_subcommand clippy" -s W -d 'clippy lints to warn on' -r complete -c x.py -n "__fish_x.py_using_subcommand clippy" -s F -d 'clippy lints to forbid' -r complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l target -d 'target targets to build' -r -f @@ -166,7 +166,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l rust-profile-genera complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l fix complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l allow-dirty complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l allow-staged @@ -182,7 +182,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l enable-bolt-setting complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x.py -n "__fish_x.py_using_subcommand clippy" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand fix" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand fix" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand fix" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand fix" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand fix" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand fix" -l target -d 'target targets to build' -r -f @@ -202,7 +202,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand fix" -l rust-profile-generate complete -c x.py -n "__fish_x.py_using_subcommand fix" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand fix" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand fix" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand fix" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand fix" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand fix" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand fix" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand fix" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -215,7 +215,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand fix" -l enable-bolt-settings - complete -c x.py -n "__fish_x.py_using_subcommand fix" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x.py -n "__fish_x.py_using_subcommand fix" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l target -d 'target targets to build' -r -f @@ -235,7 +235,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l rust-profile-generate complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l check -d 'check formatting instead of applying' complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l all -d 'apply to all appropriate files, not just those that have been modified' complete -c x.py -n "__fish_x.py_using_subcommand fmt" -s v -l verbose -d 'use verbose output (-vv for very verbose)' @@ -250,7 +250,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l enable-bolt-settings - complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x.py -n "__fish_x.py_using_subcommand fmt" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand doc" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand doc" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand doc" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand doc" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand doc" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand doc" -l target -d 'target targets to build' -r -f @@ -270,7 +270,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand doc" -l rust-profile-generate complete -c x.py -n "__fish_x.py_using_subcommand doc" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand doc" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand doc" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand doc" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand doc" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand doc" -l open -d 'open the docs in a browser' complete -c x.py -n "__fish_x.py_using_subcommand doc" -l json -d 'render the documentation in JSON format in addition to the usual HTML format' complete -c x.py -n "__fish_x.py_using_subcommand doc" -s v -l verbose -d 'use verbose output (-vv for very verbose)' @@ -291,7 +291,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand test" -l compare-mode -d 'mode complete -c x.py -n "__fish_x.py_using_subcommand test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r complete -c x.py -n "__fish_x.py_using_subcommand test" -l run -d 'whether to execute run-* tests' -r complete -c x.py -n "__fish_x.py_using_subcommand test" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand test" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand test" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand test" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand test" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand test" -l target -d 'target targets to build' -r -f @@ -311,7 +311,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand test" -l rust-profile-generate complete -c x.py -n "__fish_x.py_using_subcommand test" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand test" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand test" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand test" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand test" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand test" -l no-fail-fast -d 'run all tests regardless of failure' complete -c x.py -n "__fish_x.py_using_subcommand test" -l no-doc -d 'do not run doc tests' complete -c x.py -n "__fish_x.py_using_subcommand test" -l doc -d 'only run doc tests' @@ -333,7 +333,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand test" -l skip-stage0-validatio complete -c x.py -n "__fish_x.py_using_subcommand test" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand miri" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r complete -c x.py -n "__fish_x.py_using_subcommand miri" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand miri" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand miri" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand miri" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand miri" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand miri" -l target -d 'target targets to build' -r -f @@ -353,7 +353,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand miri" -l rust-profile-generate complete -c x.py -n "__fish_x.py_using_subcommand miri" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand miri" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand miri" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand miri" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand miri" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand miri" -l no-fail-fast -d 'run all tests regardless of failure' complete -c x.py -n "__fish_x.py_using_subcommand miri" -l no-doc -d 'do not run doc tests' complete -c x.py -n "__fish_x.py_using_subcommand miri" -l doc -d 'only run doc tests' @@ -370,7 +370,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand miri" -l skip-stage0-validatio complete -c x.py -n "__fish_x.py_using_subcommand miri" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand bench" -l test-args -r complete -c x.py -n "__fish_x.py_using_subcommand bench" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand bench" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand bench" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand bench" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand bench" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand bench" -l target -d 'target targets to build' -r -f @@ -390,7 +390,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand bench" -l rust-profile-generat complete -c x.py -n "__fish_x.py_using_subcommand bench" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand bench" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand bench" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand bench" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand bench" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand bench" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand bench" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand bench" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -404,7 +404,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand bench" -l skip-stage0-validati complete -c x.py -n "__fish_x.py_using_subcommand bench" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand clean" -l stage -d 'Clean a specific stage without touching other artifacts. By default, every stage is cleaned if this option is not used' -r complete -c x.py -n "__fish_x.py_using_subcommand clean" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand clean" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand clean" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand clean" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand clean" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand clean" -l target -d 'target targets to build' -r -f @@ -423,7 +423,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand clean" -l rust-profile-generat complete -c x.py -n "__fish_x.py_using_subcommand clean" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand clean" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand clean" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand clean" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand clean" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand clean" -l all -d 'Clean the entire build directory (not used by default)' complete -c x.py -n "__fish_x.py_using_subcommand clean" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand clean" -s i -l incremental -d 'use incremental compilation' @@ -437,7 +437,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand clean" -l enable-bolt-settings complete -c x.py -n "__fish_x.py_using_subcommand clean" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x.py -n "__fish_x.py_using_subcommand clean" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand dist" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand dist" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand dist" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand dist" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand dist" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand dist" -l target -d 'target targets to build' -r -f @@ -457,7 +457,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand dist" -l rust-profile-generate complete -c x.py -n "__fish_x.py_using_subcommand dist" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand dist" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand dist" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand dist" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand dist" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand dist" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand dist" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand dist" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -470,7 +470,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand dist" -l enable-bolt-settings complete -c x.py -n "__fish_x.py_using_subcommand dist" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x.py -n "__fish_x.py_using_subcommand dist" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand install" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand install" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand install" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand install" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand install" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand install" -l target -d 'target targets to build' -r -f @@ -490,7 +490,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand install" -l rust-profile-gener complete -c x.py -n "__fish_x.py_using_subcommand install" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand install" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand install" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand install" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand install" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand install" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand install" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand install" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -504,7 +504,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand install" -l skip-stage0-valida complete -c x.py -n "__fish_x.py_using_subcommand install" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand run" -l args -d 'arguments for the tool' -r complete -c x.py -n "__fish_x.py_using_subcommand run" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand run" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand run" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand run" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand run" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand run" -l target -d 'target targets to build' -r -f @@ -524,7 +524,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand run" -l rust-profile-generate complete -c x.py -n "__fish_x.py_using_subcommand run" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand run" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand run" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand run" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand run" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand run" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand run" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand run" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -537,7 +537,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand run" -l enable-bolt-settings - complete -c x.py -n "__fish_x.py_using_subcommand run" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x.py -n "__fish_x.py_using_subcommand run" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand setup" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand setup" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand setup" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand setup" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand setup" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand setup" -l target -d 'target targets to build' -r -f @@ -557,7 +557,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand setup" -l rust-profile-generat complete -c x.py -n "__fish_x.py_using_subcommand setup" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand setup" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand setup" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand setup" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand setup" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand setup" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand setup" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand setup" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -570,7 +570,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand setup" -l enable-bolt-settings complete -c x.py -n "__fish_x.py_using_subcommand setup" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x.py -n "__fish_x.py_using_subcommand setup" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l target -d 'target targets to build' -r -f @@ -590,7 +590,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l rust-profile-gener complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l run -d 'run suggested tests' complete -c x.py -n "__fish_x.py_using_subcommand suggest" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand suggest" -s i -l incremental -d 'use incremental compilation' @@ -605,7 +605,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l skip-stage0-valida complete -c x.py -n "__fish_x.py_using_subcommand suggest" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l sync -d 'Additional `Cargo.toml` to sync and vendor' -r -F complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l target -d 'target targets to build' -r -f @@ -625,7 +625,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l rust-profile-genera complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l versioned-dirs -d 'Always include version in subdir name' complete -c x.py -n "__fish_x.py_using_subcommand vendor" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand vendor" -s i -l incremental -d 'use incremental compilation' @@ -639,7 +639,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l enable-bolt-setting complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x.py -n "__fish_x.py_using_subcommand vendor" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l target -d 'target targets to build' -r -f @@ -659,7 +659,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subc complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -681,7 +681,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',Opt\t'',Clippy\t''}" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l target -d 'target targets to build' -r -f @@ -700,7 +700,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -717,7 +717,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',Opt\t'',Clippy\t''}" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l target -d 'target targets to build' -r -f @@ -736,7 +736,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -753,7 +753,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',Opt\t'',Clippy\t''}" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l target -d 'target targets to build' -r -f @@ -772,7 +772,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -789,7 +789,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l scenarios -d 'Select the scenarios that should be benchmarked' -r -f -a "{Full\t'',IncrFull\t'',IncrUnchanged\t'',IncrPatched\t''}" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l profiles -d 'Select the profiles that should be benchmarked' -r -f -a "{Check\t'',Debug\t'',Doc\t'',Opt\t'',Clippy\t''}" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l target -d 'target targets to build' -r -f @@ -808,7 +808,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -821,7 +821,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l skip-stage0-validation -d 'Skip stage0 compiler validation' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l config -d 'TOML configuration file for build' -r -F -complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l build-dir -d 'Build directory, overrides `build.build-dir` in `bootstrap.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l build -d 'build target of the stage0 compiler' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l target -d 'target targets to build' -r -f @@ -841,7 +841,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r -complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l set -d 'override options in config.toml' -r -f +complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l include-default-paths -d 'include default paths in addition to the provided ones' diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index e5ee174f4ca..065689411d6 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -22,7 +22,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { $completions = @(switch ($command) { 'x.py' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -43,7 +43,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -79,7 +79,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { } 'x.py;build' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -100,7 +100,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -119,7 +119,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { } 'x.py;check' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -140,7 +140,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--all-targets', '--all-targets', [CompletionResultType]::ParameterName, 'Check all targets') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') @@ -164,7 +164,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('-W', '-W ', [CompletionResultType]::ParameterName, 'clippy lints to warn on') [CompletionResult]::new('-F', '-F ', [CompletionResultType]::ParameterName, 'clippy lints to forbid') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -185,7 +185,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--fix', '--fix', [CompletionResultType]::ParameterName, 'fix') [CompletionResult]::new('--allow-dirty', '--allow-dirty', [CompletionResultType]::ParameterName, 'allow-dirty') [CompletionResult]::new('--allow-staged', '--allow-staged', [CompletionResultType]::ParameterName, 'allow-staged') @@ -207,7 +207,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { } 'x.py;fix' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -228,7 +228,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -247,7 +247,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { } 'x.py;fmt' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -268,7 +268,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--check', '--check', [CompletionResultType]::ParameterName, 'check formatting instead of applying') [CompletionResult]::new('--all', '--all', [CompletionResultType]::ParameterName, 'apply to all appropriate files, not just those that have been modified') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') @@ -289,7 +289,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { } 'x.py;doc' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -310,7 +310,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--open', '--open', [CompletionResultType]::ParameterName, 'open the docs in a browser') [CompletionResult]::new('--json', '--json', [CompletionResultType]::ParameterName, 'render the documentation in JSON format in addition to the usual HTML format') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') @@ -337,7 +337,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--pass', '--pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode') [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -358,7 +358,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--no-fail-fast', '--no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure') [CompletionResult]::new('--no-doc', '--no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests') [CompletionResult]::new('--doc', '--doc', [CompletionResultType]::ParameterName, 'only run doc tests') @@ -386,7 +386,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { 'x.py;miri' { [CompletionResult]::new('--test-args', '--test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -407,7 +407,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--no-fail-fast', '--no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure') [CompletionResult]::new('--no-doc', '--no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests') [CompletionResult]::new('--doc', '--doc', [CompletionResultType]::ParameterName, 'only run doc tests') @@ -430,7 +430,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { 'x.py;bench' { [CompletionResult]::new('--test-args', '--test-args', [CompletionResultType]::ParameterName, 'test-args') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -451,7 +451,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -471,7 +471,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { 'x.py;clean' { [CompletionResult]::new('--stage', '--stage', [CompletionResultType]::ParameterName, 'Clean a specific stage without touching other artifacts. By default, every stage is cleaned if this option is not used') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -491,7 +491,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--all', '--all', [CompletionResultType]::ParameterName, 'Clean the entire build directory (not used by default)') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') @@ -511,7 +511,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { } 'x.py;dist' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -532,7 +532,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -551,7 +551,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { } 'x.py;install' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -572,7 +572,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -592,7 +592,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { 'x.py;run' { [CompletionResult]::new('--args', '--args', [CompletionResultType]::ParameterName, 'arguments for the tool') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -613,7 +613,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -632,7 +632,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { } 'x.py;setup' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -653,7 +653,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -672,7 +672,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { } 'x.py;suggest' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -693,7 +693,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'run suggested tests') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') @@ -714,7 +714,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { 'x.py;vendor' { [CompletionResult]::new('--sync', '--sync', [CompletionResultType]::ParameterName, 'Additional `Cargo.toml` to sync and vendor') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -735,7 +735,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--versioned-dirs', '--versioned-dirs', [CompletionResultType]::ParameterName, 'Always include version in subdir name') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') @@ -755,7 +755,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { } 'x.py;perf' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -776,7 +776,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -804,7 +804,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked') [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -824,7 +824,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -847,7 +847,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked') [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -867,7 +867,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -890,7 +890,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked') [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -910,7 +910,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -933,7 +933,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--scenarios', '--scenarios', [CompletionResultType]::ParameterName, 'Select the scenarios that should be benchmarked') [CompletionResult]::new('--profiles', '--profiles', [CompletionResultType]::ParameterName, 'Select the profiles that should be benchmarked') [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -953,7 +953,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -972,7 +972,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { } 'x.py;perf;compare' { [CompletionResult]::new('--config', '--config', [CompletionResultType]::ParameterName, 'TOML configuration file for build') - [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`') + [CompletionResult]::new('--build-dir', '--build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `bootstrap.toml`') [CompletionResult]::new('--build', '--build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler') [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', '--target', [CompletionResultType]::ParameterName, 'target targets to build') @@ -993,7 +993,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--rust-profile-use', '--rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build') [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build') [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive') - [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in config.toml') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh index 71afd5e73ca..417935630ab 100644 --- a/src/etc/completions/x.py.zsh +++ b/src/etc/completions/x.py.zsh @@ -16,7 +16,7 @@ _x.py() { local context curcontext="$curcontext" state line _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -37,7 +37,7 @@ _x.py() { '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -66,7 +66,7 @@ _x.py() { (build) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -87,7 +87,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -108,7 +108,7 @@ _arguments "${_arguments_options[@]}" : \ (check) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -129,7 +129,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--all-targets[Check all targets]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ @@ -155,7 +155,7 @@ _arguments "${_arguments_options[@]}" : \ '*-W+[clippy lints to warn on]:LINT:_default' \ '*-F+[clippy lints to forbid]:LINT:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -176,7 +176,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--fix[]' \ '--allow-dirty[]' \ '--allow-staged[]' \ @@ -200,7 +200,7 @@ _arguments "${_arguments_options[@]}" : \ (fix) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -221,7 +221,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -242,7 +242,7 @@ _arguments "${_arguments_options[@]}" : \ (fmt) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -263,7 +263,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--check[check formatting instead of applying]' \ '--all[apply to all appropriate files, not just those that have been modified]' \ '*-v[use verbose output (-vv for very verbose)]' \ @@ -286,7 +286,7 @@ _arguments "${_arguments_options[@]}" : \ (doc) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -307,7 +307,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--open[open the docs in a browser]' \ '--json[render the documentation in JSON format in addition to the usual HTML format]' \ '*-v[use verbose output (-vv for very verbose)]' \ @@ -336,7 +336,7 @@ _arguments "${_arguments_options[@]}" : \ '--pass=[force {check,build,run}-pass tests to this mode]:check | build | run:_default' \ '--run=[whether to execute run-* tests]:auto | always | never:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -357,7 +357,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--no-fail-fast[run all tests regardless of failure]' \ '--no-doc[do not run doc tests]' \ '--doc[only run doc tests]' \ @@ -387,7 +387,7 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ '*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -408,7 +408,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--no-fail-fast[run all tests regardless of failure]' \ '--no-doc[do not run doc tests]' \ '--doc[only run doc tests]' \ @@ -433,7 +433,7 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ '*--test-args=[]:TEST_ARGS:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -454,7 +454,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -476,7 +476,7 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ '--stage=[Clean a specific stage without touching other artifacts. By default, every stage is cleaned if this option is not used]:N:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -496,7 +496,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--all[Clean the entire build directory (not used by default)]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ @@ -518,7 +518,7 @@ _arguments "${_arguments_options[@]}" : \ (dist) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -539,7 +539,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -560,7 +560,7 @@ _arguments "${_arguments_options[@]}" : \ (install) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -581,7 +581,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -603,7 +603,7 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ '*--args=[arguments for the tool]:ARGS:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -624,7 +624,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -645,7 +645,7 @@ _arguments "${_arguments_options[@]}" : \ (setup) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -666,7 +666,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -681,14 +681,14 @@ _arguments "${_arguments_options[@]}" : \ '--skip-stage0-validation[Skip stage0 compiler validation]' \ '-h[Print help (see more with '\''--help'\'')]' \ '--help[Print help (see more with '\''--help'\'')]' \ -'::profile -- Either the profile for `config.toml` or another setup action. May be omitted to set up interactively:_files' \ +'::profile -- Either the profile for `bootstrap.toml` or another setup action. May be omitted to set up interactively:_files' \ '*::paths -- paths for the subcommand:_files' \ && ret=0 ;; (suggest) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -709,7 +709,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--run[run suggested tests]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ @@ -732,7 +732,7 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ '*--sync=[Additional \`Cargo.toml\` to sync and vendor]:SYNC:_files' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -753,7 +753,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--versioned-dirs[Always include version in subdir name]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ @@ -775,7 +775,7 @@ _arguments "${_arguments_options[@]}" : \ (perf) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -796,7 +796,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -830,7 +830,7 @@ _arguments "${_arguments_options[@]}" : \ '*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \ '*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc Opt Clippy)' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -850,7 +850,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -875,7 +875,7 @@ _arguments "${_arguments_options[@]}" : \ '*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \ '*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc Opt Clippy)' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -895,7 +895,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -920,7 +920,7 @@ _arguments "${_arguments_options[@]}" : \ '*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \ '*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc Opt Clippy)' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -940,7 +940,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -965,7 +965,7 @@ _arguments "${_arguments_options[@]}" : \ '*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \ '*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc Opt Clippy)' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -985,7 +985,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -1007,7 +1007,7 @@ _arguments "${_arguments_options[@]}" : \ (compare) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -1028,7 +1028,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ diff --git a/src/etc/completions/x.zsh b/src/etc/completions/x.zsh index b08eb06f8e6..c6eff630dbf 100644 --- a/src/etc/completions/x.zsh +++ b/src/etc/completions/x.zsh @@ -16,7 +16,7 @@ _x() { local context curcontext="$curcontext" state line _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -37,7 +37,7 @@ _x() { '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -66,7 +66,7 @@ _x() { (build) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -87,7 +87,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -108,7 +108,7 @@ _arguments "${_arguments_options[@]}" : \ (check) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -129,7 +129,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--all-targets[Check all targets]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ @@ -155,7 +155,7 @@ _arguments "${_arguments_options[@]}" : \ '*-W+[clippy lints to warn on]:LINT:_default' \ '*-F+[clippy lints to forbid]:LINT:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -176,7 +176,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--fix[]' \ '--allow-dirty[]' \ '--allow-staged[]' \ @@ -200,7 +200,7 @@ _arguments "${_arguments_options[@]}" : \ (fix) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -221,7 +221,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -242,7 +242,7 @@ _arguments "${_arguments_options[@]}" : \ (fmt) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -263,7 +263,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--check[check formatting instead of applying]' \ '--all[apply to all appropriate files, not just those that have been modified]' \ '*-v[use verbose output (-vv for very verbose)]' \ @@ -286,7 +286,7 @@ _arguments "${_arguments_options[@]}" : \ (doc) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -307,7 +307,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--open[open the docs in a browser]' \ '--json[render the documentation in JSON format in addition to the usual HTML format]' \ '*-v[use verbose output (-vv for very verbose)]' \ @@ -336,7 +336,7 @@ _arguments "${_arguments_options[@]}" : \ '--pass=[force {check,build,run}-pass tests to this mode]:check | build | run:_default' \ '--run=[whether to execute run-* tests]:auto | always | never:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -357,7 +357,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--no-fail-fast[run all tests regardless of failure]' \ '--no-doc[do not run doc tests]' \ '--doc[only run doc tests]' \ @@ -387,7 +387,7 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ '*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -408,7 +408,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--no-fail-fast[run all tests regardless of failure]' \ '--no-doc[do not run doc tests]' \ '--doc[only run doc tests]' \ @@ -433,7 +433,7 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ '*--test-args=[]:TEST_ARGS:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -454,7 +454,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -476,7 +476,7 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ '--stage=[Clean a specific stage without touching other artifacts. By default, every stage is cleaned if this option is not used]:N:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -496,7 +496,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--all[Clean the entire build directory (not used by default)]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ @@ -518,7 +518,7 @@ _arguments "${_arguments_options[@]}" : \ (dist) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -539,7 +539,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -560,7 +560,7 @@ _arguments "${_arguments_options[@]}" : \ (install) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -581,7 +581,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -603,7 +603,7 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ '*--args=[arguments for the tool]:ARGS:_default' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -624,7 +624,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -645,7 +645,7 @@ _arguments "${_arguments_options[@]}" : \ (setup) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -666,7 +666,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -681,14 +681,14 @@ _arguments "${_arguments_options[@]}" : \ '--skip-stage0-validation[Skip stage0 compiler validation]' \ '-h[Print help (see more with '\''--help'\'')]' \ '--help[Print help (see more with '\''--help'\'')]' \ -'::profile -- Either the profile for `config.toml` or another setup action. May be omitted to set up interactively:_files' \ +'::profile -- Either the profile for `bootstrap.toml` or another setup action. May be omitted to set up interactively:_files' \ '*::paths -- paths for the subcommand:_files' \ && ret=0 ;; (suggest) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -709,7 +709,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--run[run suggested tests]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ @@ -732,7 +732,7 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ '*--sync=[Additional \`Cargo.toml\` to sync and vendor]:SYNC:_files' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -753,7 +753,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '--versioned-dirs[Always include version in subdir name]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ @@ -775,7 +775,7 @@ _arguments "${_arguments_options[@]}" : \ (perf) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -796,7 +796,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -830,7 +830,7 @@ _arguments "${_arguments_options[@]}" : \ '*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \ '*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc Opt Clippy)' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -850,7 +850,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -875,7 +875,7 @@ _arguments "${_arguments_options[@]}" : \ '*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \ '*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc Opt Clippy)' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -895,7 +895,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -920,7 +920,7 @@ _arguments "${_arguments_options[@]}" : \ '*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \ '*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc Opt Clippy)' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -940,7 +940,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -965,7 +965,7 @@ _arguments "${_arguments_options[@]}" : \ '*--scenarios=[Select the scenarios that should be benchmarked]:SCENARIOS:(Full IncrFull IncrUnchanged IncrPatched)' \ '*--profiles=[Select the profiles that should be benchmarked]:PROFILES:(Check Debug Doc Opt Clippy)' \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -985,7 +985,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -1007,7 +1007,7 @@ _arguments "${_arguments_options[@]}" : \ (compare) _arguments "${_arguments_options[@]}" : \ '--config=[TOML configuration file for build]:FILE:_files' \ -'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \ +'--build-dir=[Build directory, overrides \`build.build-dir\` in \`bootstrap.toml\`]:DIR:_files -/' \ '--build=[build target of the stage0 compiler]:BUILD:' \ '--host=[host targets to build]:HOST:' \ '--target=[target targets to build]:TARGET:' \ @@ -1028,7 +1028,7 @@ _arguments "${_arguments_options[@]}" : \ '--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \ '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \ '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \ -'*--set=[override options in config.toml]:section.option=value:' \ +'*--set=[override options in bootstrap.toml]:section.option=value:' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ diff --git a/src/etc/lldb_batchmode.py b/src/etc/lldb_batchmode.py index cf88c53e085..5cc9bb23628 100644 --- a/src/etc/lldb_batchmode.py +++ b/src/etc/lldb_batchmode.py @@ -40,7 +40,7 @@ def print_debug(s): def normalize_whitespace(s): """Replace newlines, tabs, multiple spaces, etc with exactly one space""" - return re.sub("\s+", " ", s) + return re.sub(r"\s+", " ", s) def breakpoint_callback(frame, bp_loc, dict): @@ -234,7 +234,7 @@ try: if ( command == "run" or command == "r" - or re.match("^process\s+launch.*", command) + or re.match(r"^process\s+launch.*", command) ): # Before starting to run the program, let the thread sleep a bit, so all # breakpoint added events can be processed diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0f476c8c9ff..4ecf702d7b6 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -125,7 +125,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< items.extend(doc.items.values().flat_map(|(item, renamed, _)| { // Now we actually lower the imports, skipping everything else. if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind { - let name = renamed.unwrap_or_else(|| cx.tcx.hir_name(item.hir_id())); + let name = renamed.unwrap_or(kw::Empty); // using kw::Empty is a bit of a hack clean_use_statement(item, name, path, hir::UseKind::Glob, cx, &mut inserted) } else { // skip everything else @@ -1488,6 +1488,9 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo // The only time this happens is if we're inside the rustdoc for Fn(), // which only has one associated type, which is not a GAT, so whatever. } + GenericArgs::ReturnTypeNotation => { + // Never move these. + } } bounds.extend(mem::take(pred_bounds)); false @@ -1626,8 +1629,7 @@ fn first_non_private<'tcx>( if let Some(use_def_id) = reexp.id() && let Some(local_use_def_id) = use_def_id.as_local() && let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(local_use_def_id) - && !item.ident.name.is_empty() - && let hir::ItemKind::Use(path, _) = item.kind + && let hir::ItemKind::Use(path, hir::UseKind::Single(_)) = item.kind { for res in &path.res { if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res { @@ -1772,7 +1774,7 @@ fn maybe_expand_private_type_alias<'tcx>( } else { return None; }; - let hir::ItemKind::TyAlias(ty, generics) = alias else { return None }; + let hir::ItemKind::TyAlias(_, ty, generics) = alias else { return None }; let final_seg = &path.segments.last().expect("segments were empty"); let mut args = DefIdMap::default(); @@ -2553,36 +2555,42 @@ fn clean_generic_args<'tcx>( generic_args: &hir::GenericArgs<'tcx>, cx: &mut DocContext<'tcx>, ) -> GenericArgs { - // FIXME(return_type_notation): Fix RTN parens rendering - if let Some((inputs, output)) = generic_args.paren_sugar_inputs_output() { - let inputs = inputs.iter().map(|x| clean_ty(x, cx)).collect(); - let output = match output.kind { - hir::TyKind::Tup(&[]) => None, - _ => Some(Box::new(clean_ty(output, cx))), - }; - GenericArgs::Parenthesized { inputs, output } - } else { - let args = generic_args - .args - .iter() - .map(|arg| match arg { - hir::GenericArg::Lifetime(lt) if !lt.is_anonymous() => { - GenericArg::Lifetime(clean_lifetime(lt, cx)) - } - hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()), - hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty.as_unambig_ty(), cx)), - hir::GenericArg::Const(ct) => { - GenericArg::Const(Box::new(clean_const(ct.as_unambig_ct(), cx))) - } - hir::GenericArg::Infer(_inf) => GenericArg::Infer, - }) - .collect(); - let constraints = generic_args - .constraints - .iter() - .map(|c| clean_assoc_item_constraint(c, cx)) - .collect::<ThinVec<_>>(); - GenericArgs::AngleBracketed { args, constraints } + match generic_args.parenthesized { + hir::GenericArgsParentheses::No => { + let args = generic_args + .args + .iter() + .map(|arg| match arg { + hir::GenericArg::Lifetime(lt) if !lt.is_anonymous() => { + GenericArg::Lifetime(clean_lifetime(lt, cx)) + } + hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()), + hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty.as_unambig_ty(), cx)), + hir::GenericArg::Const(ct) => { + GenericArg::Const(Box::new(clean_const(ct.as_unambig_ct(), cx))) + } + hir::GenericArg::Infer(_inf) => GenericArg::Infer, + }) + .collect(); + let constraints = generic_args + .constraints + .iter() + .map(|c| clean_assoc_item_constraint(c, cx)) + .collect::<ThinVec<_>>(); + GenericArgs::AngleBracketed { args, constraints } + } + hir::GenericArgsParentheses::ParenSugar => { + let Some((inputs, output)) = generic_args.paren_sugar_inputs_output() else { + bug!(); + }; + let inputs = inputs.iter().map(|x| clean_ty(x, cx)).collect(); + let output = match output.kind { + hir::TyKind::Tup(&[]) => None, + _ => Some(Box::new(clean_ty(output, cx))), + }; + GenericArgs::Parenthesized { inputs, output } + } + hir::GenericArgsParentheses::ReturnTypeNotation => GenericArgs::ReturnTypeNotation, } } @@ -2785,20 +2793,24 @@ fn clean_maybe_renamed_item<'tcx>( use hir::ItemKind; let def_id = item.owner_id.to_def_id(); - let mut name = renamed.unwrap_or_else(|| cx.tcx.hir_name(item.hir_id())); + let mut name = renamed.unwrap_or_else(|| { + // FIXME: using kw::Empty is a bit of a hack + cx.tcx.hir_opt_name(item.hir_id()).unwrap_or(kw::Empty) + }); + cx.with_param_env(def_id, |cx| { let kind = match item.kind { - ItemKind::Static(ty, mutability, body_id) => StaticItem(Static { + ItemKind::Static(_, ty, mutability, body_id) => StaticItem(Static { type_: Box::new(clean_ty(ty, cx)), mutability, expr: Some(body_id), }), - ItemKind::Const(ty, generics, body_id) => ConstantItem(Box::new(Constant { + ItemKind::Const(_, ty, generics, body_id) => ConstantItem(Box::new(Constant { generics: clean_generics(generics, cx), type_: clean_ty(ty, cx), kind: ConstantKind::Local { body: body_id, def_id }, })), - ItemKind::TyAlias(hir_ty, generics) => { + ItemKind::TyAlias(_, hir_ty, generics) => { *cx.current_type_aliases.entry(def_id).or_insert(0) += 1; let rustdoc_ty = clean_ty(hir_ty, cx); let type_ = @@ -2831,34 +2843,34 @@ fn clean_maybe_renamed_item<'tcx>( )); return ret; } - ItemKind::Enum(ref def, generics) => EnumItem(Enum { + ItemKind::Enum(_, ref def, generics) => EnumItem(Enum { variants: def.variants.iter().map(|v| clean_variant(v, cx)).collect(), generics: clean_generics(generics, cx), }), - ItemKind::TraitAlias(generics, bounds) => TraitAliasItem(TraitAlias { + ItemKind::TraitAlias(_, generics, bounds) => TraitAliasItem(TraitAlias { generics: clean_generics(generics, cx), bounds: bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(), }), - ItemKind::Union(ref variant_data, generics) => UnionItem(Union { + ItemKind::Union(_, ref variant_data, generics) => UnionItem(Union { generics: clean_generics(generics, cx), fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(), }), - ItemKind::Struct(ref variant_data, generics) => StructItem(Struct { + ItemKind::Struct(_, ref variant_data, generics) => StructItem(Struct { ctor_kind: variant_data.ctor_kind(), generics: clean_generics(generics, cx), fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(), }), ItemKind::Impl(impl_) => return clean_impl(impl_, item.owner_id.def_id, cx), - ItemKind::Macro(macro_def, MacroKind::Bang) => MacroItem(Macro { + ItemKind::Macro(_, macro_def, MacroKind::Bang) => MacroItem(Macro { source: display_macro_source(cx, name, macro_def), macro_rules: macro_def.macro_rules, }), - ItemKind::Macro(_, macro_kind) => clean_proc_macro(item, &mut name, macro_kind, cx), + ItemKind::Macro(_, _, macro_kind) => clean_proc_macro(item, &mut name, macro_kind, cx), // proc macros can have a name set by attributes ItemKind::Fn { ref sig, generics, body: body_id, .. } => { clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx) } - ItemKind::Trait(_, _, generics, bounds, item_ids) => { + ItemKind::Trait(_, _, _, generics, bounds, item_ids) => { let items = item_ids .iter() .map(|ti| clean_trait_item(cx.tcx.hir_trait_item(ti.id), cx)) @@ -2871,7 +2883,7 @@ fn clean_maybe_renamed_item<'tcx>( bounds: bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(), })) } - ItemKind::ExternCrate(orig_name) => { + ItemKind::ExternCrate(orig_name, _) => { return clean_extern_crate(item, name, orig_name, cx); } ItemKind::Use(path, kind) => { diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs index 88db853d7c3..31f9c284d7d 100644 --- a/src/librustdoc/clean/render_macro_matchers.rs +++ b/src/librustdoc/clean/render_macro_matchers.rs @@ -4,8 +4,8 @@ use rustc_ast_pretty::pprust::PrintState; use rustc_ast_pretty::pprust::state::State as Printer; use rustc_middle::ty::TyCtxt; use rustc_session::parse::ParseSess; -use rustc_span::Span; use rustc_span::symbol::{Ident, Symbol, kw}; +use rustc_span::{FileName, Span}; /// Render a macro matcher in a format suitable for displaying to the user /// as part of an item declaration. @@ -63,7 +63,7 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option<String // Create a Parser. let psess = ParseSess::new(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec()); - let file_name = source_map.span_to_filename(span); + let file_name = FileName::macro_expansion_source_code(&snippet); let mut parser = match rustc_parse::new_parser_from_source_str(&psess, file_name, snippet.clone()) { Ok(parser) => parser, diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index b8db82e540c..41943b94d1e 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -102,6 +102,10 @@ pub(crate) fn merge_bounds( } } }, + PP::ReturnTypeNotation => { + // Cannot merge bounds with RTN. + return false; + } }; true }) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 228d9108e4e..3b2dcb3db81 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -5,7 +5,7 @@ use std::{fmt, iter}; use arrayvec::ArrayVec; use rustc_abi::{ExternAbi, VariantIdx}; -use rustc_attr_parsing::{ConstStability, Deprecation, Stability, StableSince}; +use rustc_attr_parsing::{AttributeKind, ConstStability, Deprecation, Stability, StableSince}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId}; @@ -226,7 +226,7 @@ impl ExternalCrate { .filter_map(|&id| { let item = tcx.hir_item(id); match item.kind { - hir::ItemKind::Mod(_) => { + hir::ItemKind::Mod(..) => { as_keyword(Res::Def(DefKind::Mod, id.owner_id.to_def_id())) } _ => None, @@ -282,7 +282,7 @@ impl ExternalCrate { .filter_map(|&id| { let item = tcx.hir_item(id); match item.kind { - hir::ItemKind::Mod(_) => { + hir::ItemKind::Mod(..) => { as_primitive(Res::Def(DefKind::Mod, id.owner_id.to_def_id())) } _ => None, @@ -756,12 +756,7 @@ impl Item { Some(tcx.visibility(def_id)) } - pub(crate) fn attributes( - &self, - tcx: TyCtxt<'_>, - cache: &Cache, - keep_as_is: bool, - ) -> Vec<String> { + pub(crate) fn attributes(&self, tcx: TyCtxt<'_>, cache: &Cache, is_json: bool) -> Vec<String> { const ALLOWED_ATTRIBUTES: &[Symbol] = &[sym::export_name, sym::link_section, sym::no_mangle, sym::non_exhaustive]; @@ -772,8 +767,14 @@ impl Item { .other_attrs .iter() .filter_map(|attr| { - if keep_as_is { - Some(rustc_hir_pretty::attribute_to_string(&tcx, attr)) + if is_json { + if matches!(attr, hir::Attribute::Parsed(AttributeKind::Deprecation { .. })) { + // rustdoc-json stores this in `Item::deprecation`, so we + // don't want it it `Item::attrs`. + None + } else { + Some(rustc_hir_pretty::attribute_to_string(&tcx, attr)) + } } else if ALLOWED_ATTRIBUTES.contains(&attr.name_or_empty()) { Some( rustc_hir_pretty::attribute_to_string(&tcx, attr) @@ -786,7 +787,9 @@ impl Item { } }) .collect(); - if !keep_as_is + + // Add #[repr(...)] + if !is_json && let Some(def_id) = self.def_id() && let ItemType::Struct | ItemType::Enum | ItemType::Union = self.type_() { @@ -2259,8 +2262,12 @@ impl GenericArg { #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub(crate) enum GenericArgs { + /// `<args, constraints = ..>` AngleBracketed { args: ThinVec<GenericArg>, constraints: ThinVec<AssocItemConstraint> }, + /// `(inputs) -> output` Parenthesized { inputs: ThinVec<Type>, output: Option<Box<Type>> }, + /// `(..)` + ReturnTypeNotation, } impl GenericArgs { @@ -2270,6 +2277,7 @@ impl GenericArgs { args.is_empty() && constraints.is_empty() } GenericArgs::Parenthesized { inputs, output } => inputs.is_empty() && output.is_none(), + GenericArgs::ReturnTypeNotation => false, } } pub(crate) fn constraints(&self) -> Box<dyn Iterator<Item = AssocItemConstraint> + '_> { @@ -2294,6 +2302,7 @@ impl GenericArgs { }) .into_iter(), ), + GenericArgs::ReturnTypeNotation => Box::new([].into_iter()), } } } @@ -2305,8 +2314,10 @@ impl<'a> IntoIterator for &'a GenericArgs { match self { GenericArgs::AngleBracketed { args, .. } => Box::new(args.iter().cloned()), GenericArgs::Parenthesized { inputs, .. } => { + // FIXME: This isn't really right, since `Fn(A, B)` is `Fn<(A, B)>` Box::new(inputs.iter().cloned().map(GenericArg::Type)) } + GenericArgs::ReturnTypeNotation => Box::new([].into_iter()), } } } diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index 18ad442d017..d0072256941 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -80,7 +80,7 @@ impl<'tcx> HirCollector<'tcx> { pub fn collect_crate(mut self) -> Vec<ScrapedDocTest> { let tcx = self.tcx; - self.visit_testable("".to_string(), CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID), |this| { + self.visit_testable(None, CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID), |this| { tcx.hir_walk_toplevel_module(this) }); self.collector.tests @@ -90,7 +90,7 @@ impl<'tcx> HirCollector<'tcx> { impl HirCollector<'_> { fn visit_testable<F: FnOnce(&mut Self)>( &mut self, - name: String, + name: Option<String>, def_id: LocalDefId, sp: Span, nested: F, @@ -103,9 +103,10 @@ impl HirCollector<'_> { return; } - let has_name = !name.is_empty(); - if has_name { + let mut has_name = false; + if let Some(name) = name { self.collector.cur_path.push(name); + has_name = true; } // The collapse-docs pass won't combine sugared/raw doc attributes, or included files with @@ -153,9 +154,9 @@ impl<'tcx> intravisit::Visitor<'tcx> for HirCollector<'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item<'_>) { let name = match &item.kind { hir::ItemKind::Impl(impl_) => { - rustc_hir_pretty::id_to_string(&self.tcx, impl_.self_ty.hir_id) + Some(rustc_hir_pretty::id_to_string(&self.tcx, impl_.self_ty.hir_id)) } - _ => item.ident.to_string(), + _ => item.kind.ident().map(|ident| ident.to_string()), }; self.visit_testable(name, item.owner_id.def_id, item.span, |this| { @@ -164,31 +165,46 @@ impl<'tcx> intravisit::Visitor<'tcx> for HirCollector<'tcx> { } fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem<'_>) { - self.visit_testable(item.ident.to_string(), item.owner_id.def_id, item.span, |this| { - intravisit::walk_trait_item(this, item); - }); + self.visit_testable( + Some(item.ident.to_string()), + item.owner_id.def_id, + item.span, + |this| { + intravisit::walk_trait_item(this, item); + }, + ); } fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem<'_>) { - self.visit_testable(item.ident.to_string(), item.owner_id.def_id, item.span, |this| { - intravisit::walk_impl_item(this, item); - }); + self.visit_testable( + Some(item.ident.to_string()), + item.owner_id.def_id, + item.span, + |this| { + intravisit::walk_impl_item(this, item); + }, + ); } fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'_>) { - self.visit_testable(item.ident.to_string(), item.owner_id.def_id, item.span, |this| { - intravisit::walk_foreign_item(this, item); - }); + self.visit_testable( + Some(item.ident.to_string()), + item.owner_id.def_id, + item.span, + |this| { + intravisit::walk_foreign_item(this, item); + }, + ); } fn visit_variant(&mut self, v: &'tcx hir::Variant<'_>) { - self.visit_testable(v.ident.to_string(), v.def_id, v.span, |this| { + self.visit_testable(Some(v.ident.to_string()), v.def_id, v.span, |this| { intravisit::walk_variant(this, v); }); } fn visit_field_def(&mut self, f: &'tcx hir::FieldDef<'_>) { - self.visit_testable(f.ident.to_string(), f.def_id, f.span, |this| { + self.visit_testable(Some(f.ident.to_string()), f.def_id, f.span, |this| { intravisit::walk_field_def(this, f); }); } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index e93b9eb272a..41e9a5a6651 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -332,6 +332,9 @@ impl clean::GenericArgs { } } } + clean::GenericArgs::ReturnTypeNotation => { + f.write_str("(..)")?; + } } Ok(()) }) diff --git a/src/librustdoc/html/length_limit/tests.rs b/src/librustdoc/html/length_limit/tests.rs index 2185c034890..4ebecfd5f24 100644 --- a/src/librustdoc/html/length_limit/tests.rs +++ b/src/librustdoc/html/length_limit/tests.rs @@ -9,41 +9,41 @@ fn empty() { #[test] fn basic() { let mut buf = HtmlWithLimit::new(60); - buf.push("Hello "); + let _ = buf.push("Hello "); buf.open_tag("em"); - buf.push("world"); + let _ = buf.push("world"); buf.close_tag(); - buf.push("!"); + let _ = buf.push("!"); assert_eq!(buf.finish(), "Hello <em>world</em>!"); } #[test] fn no_tags() { let mut buf = HtmlWithLimit::new(60); - buf.push("Hello"); - buf.push(" world!"); + let _ = buf.push("Hello"); + let _ = buf.push(" world!"); assert_eq!(buf.finish(), "Hello world!"); } #[test] fn limit_0() { let mut buf = HtmlWithLimit::new(0); - buf.push("Hello "); + let _ = buf.push("Hello "); buf.open_tag("em"); - buf.push("world"); + let _ = buf.push("world"); buf.close_tag(); - buf.push("!"); + let _ = buf.push("!"); assert_eq!(buf.finish(), ""); } #[test] fn exactly_limit() { let mut buf = HtmlWithLimit::new(12); - buf.push("Hello "); + let _ = buf.push("Hello "); buf.open_tag("em"); - buf.push("world"); + let _ = buf.push("world"); buf.close_tag(); - buf.push("!"); + let _ = buf.push("!"); assert_eq!(buf.finish(), "Hello <em>world</em>!"); } @@ -51,11 +51,11 @@ fn exactly_limit() { fn multiple_nested_tags() { let mut buf = HtmlWithLimit::new(60); buf.open_tag("p"); - buf.push("This is a "); + let _ = buf.push("This is a "); buf.open_tag("em"); - buf.push("paragraph"); + let _ = buf.push("paragraph"); buf.open_tag("strong"); - buf.push("!"); + let _ = buf.push("!"); buf.close_tag(); buf.close_tag(); buf.close_tag(); @@ -66,11 +66,11 @@ fn multiple_nested_tags() { fn forgot_to_close_tags() { let mut buf = HtmlWithLimit::new(60); buf.open_tag("p"); - buf.push("This is a "); + let _ = buf.push("This is a "); buf.open_tag("em"); - buf.push("paragraph"); + let _ = buf.push("paragraph"); buf.open_tag("strong"); - buf.push("!"); + let _ = buf.push("!"); assert_eq!(buf.finish(), "<p>This is a <em>paragraph<strong>!</strong></em></p>"); } @@ -78,10 +78,10 @@ fn forgot_to_close_tags() { fn past_the_limit() { let mut buf = HtmlWithLimit::new(20); buf.open_tag("p"); - (0..10).try_for_each(|n| { + let _ = (0..10).try_for_each(|n| { buf.open_tag("strong"); - buf.push("word#")?; - buf.push(&n.to_string())?; + let _ = buf.push("word#")?; + let _ = buf.push(&n.to_string())?; buf.close_tag(); ControlFlow::Continue(()) }); @@ -100,8 +100,8 @@ fn past_the_limit() { fn quickly_past_the_limit() { let mut buf = HtmlWithLimit::new(6); buf.open_tag("p"); - buf.push("Hello"); - buf.push(" World"); + let _ = buf.push("Hello"); + let _ = buf.push(" World"); // intentionally not closing <p> before finishing assert_eq!(buf.finish(), "<p>Hello</p>"); } @@ -110,7 +110,7 @@ fn quickly_past_the_limit() { fn close_too_many() { let mut buf = HtmlWithLimit::new(60); buf.open_tag("p"); - buf.push("Hello"); + let _ = buf.push("Hello"); buf.close_tag(); // This call does not panic because there are valid cases // where `close_tag()` is called with no tags left to close. diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 079651e8603..b067dbf750e 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1568,7 +1568,7 @@ fn markdown_summary_with_limit( let mut buf = HtmlWithLimit::new(length_limit); let mut stopped_early = false; - p.try_for_each(|event| { + let _ = p.try_for_each(|event| { match &event { Event::Text(text) => { let r = diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index b2ad2fa773a..8dfde1679fe 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1465,8 +1465,6 @@ pub(crate) fn notable_traits_button( ty: &clean::Type, cx: &Context<'_>, ) -> Option<impl fmt::Display> { - let mut has_notable_trait = false; - if ty.is_unit() { // Very common fast path. return None; @@ -1484,27 +1482,19 @@ pub(crate) fn notable_traits_button( return None; } - if let Some(impls) = cx.cache().impls.get(&did) { - for i in impls { - let impl_ = i.inner_impl(); - if impl_.polarity != ty::ImplPolarity::Positive { - continue; - } - - if !ty.is_doc_subtype_of(&impl_.for_, cx.cache()) { + let impls = cx.cache().impls.get(&did)?; + let has_notable_trait = impls + .iter() + .map(Impl::inner_impl) + .filter(|impl_| { + impl_.polarity == ty::ImplPolarity::Positive // Two different types might have the same did, // without actually being the same. - continue; - } - if let Some(trait_) = &impl_.trait_ { - let trait_did = trait_.def_id(); - - if cx.cache().traits.get(&trait_did).is_some_and(|t| t.is_notable_trait(cx.tcx())) { - has_notable_trait = true; - } - } - } - } + && ty.is_doc_subtype_of(&impl_.for_, cx.cache()) + }) + .filter_map(|impl_| impl_.trait_.as_ref()) + .filter_map(|trait_| cx.cache().traits.get(&trait_.def_id())) + .any(|t| t.is_notable_trait(cx.tcx())); has_notable_trait.then(|| { cx.types_with_notable_traits.borrow_mut().insert(ty.clone()); diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index 3228f71df07..3676051b1bd 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -242,10 +242,9 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { // Now that we confirmed it's a file import, we want to get the span for the module // name only and not all the "mod foo;". if let Node::Item(item) = self.tcx.hir_node(id) { - self.matches.insert( - item.ident.span, - LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)), - ); + let (ident, _) = item.expect_mod(); + self.matches + .insert(ident.span, LinkFromSrc::Local(clean::Span::new(m.spans.inner_span))); } } else { // If it's a "mod foo {}", we want to look to its documentation page. @@ -273,22 +272,22 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { fn visit_item(&mut self, item: &'tcx Item<'tcx>) { match item.kind { ItemKind::Static(..) - | ItemKind::Const(_, _, _) + | ItemKind::Const(..) | ItemKind::Fn { .. } - | ItemKind::Macro(_, _) - | ItemKind::TyAlias(_, _) - | ItemKind::Enum(_, _) - | ItemKind::Struct(_, _) - | ItemKind::Union(_, _) - | ItemKind::Trait(_, _, _, _, _) - | ItemKind::TraitAlias(_, _) => self.extract_info_from_hir_id(item.hir_id()), + | ItemKind::Macro(..) + | ItemKind::TyAlias(..) + | ItemKind::Enum(..) + | ItemKind::Struct(..) + | ItemKind::Union(..) + | ItemKind::Trait(..) + | ItemKind::TraitAlias(..) => self.extract_info_from_hir_id(item.hir_id()), ItemKind::Impl(_) - | ItemKind::Use(_, _) - | ItemKind::ExternCrate(_) + | ItemKind::Use(..) + | ItemKind::ExternCrate(..) | ItemKind::ForeignMod { .. } | ItemKind::GlobalAsm { .. } // We already have "visit_mod" above so no need to check it here. - | ItemKind::Mod(_) => {} + | ItemKind::Mod(..) => {} } intravisit::walk_item(self, item); } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 6369433a4b5..a5351b350dd 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -176,6 +176,7 @@ impl FromClean<clean::GenericArgs> for GenericArgs { inputs: inputs.into_json(renderer), output: output.map(|a| (*a).into_json(renderer)), }, + ReturnTypeNotation => GenericArgs::ReturnTypeNotation, } } } diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 45b8dafa907..f8f670f575b 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -240,7 +240,7 @@ impl DocVisitor<'_> for CoverageCalculator<'_, '_> { data: hir::VariantData::Tuple(_, _, _), .. }) | hir::Node::Item(hir::Item { - kind: hir::ItemKind::Struct(hir::VariantData::Tuple(_, _, _), _), + kind: hir::ItemKind::Struct(_, hir::VariantData::Tuple(_, _, _), _), .. }) ) diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 68e381fa3f1..254549e72c6 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -144,9 +144,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { && inserted.insert(def_id) { let item = self.cx.tcx.hir_expect_item(local_def_id); - top_level_module - .items - .insert((local_def_id, Some(item.ident.name)), (item, None, None)); + let (ident, _, _) = item.expect_macro(); + top_level_module.items.insert((local_def_id, Some(ident.name)), (item, None, None)); } } @@ -224,11 +223,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { def_id: LocalDefId, res: Res, renamed: Option<Symbol>, - glob: bool, please_inline: bool, ) -> bool { debug!("maybe_inline_local (renamed: {renamed:?}) res: {res:?}"); + let glob = renamed.is_none(); if renamed == Some(kw::Underscore) { // We never inline `_` reexports. return false; @@ -286,7 +285,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { is_hidden && // If it's a doc hidden module, we need to keep it in case some of its inner items // are re-exported. - !matches!(item, Node::Item(&hir::Item { kind: hir::ItemKind::Mod(_), .. })) + !matches!(item, Node::Item(&hir::Item { kind: hir::ItemKind::Mod(..), .. })) ) || // The imported item is public and not `doc(hidden)` so no need to inline it. self.reexport_public_and_not_hidden(def_id, res_did) @@ -297,7 +296,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let is_bang_macro = matches!( item, - Node::Item(&hir::Item { kind: hir::ItemKind::Macro(_, MacroKind::Bang), .. }) + Node::Item(&hir::Item { kind: hir::ItemKind::Macro(_, _, MacroKind::Bang), .. }) ); if !self.view_item_stack.insert(res_did) && !is_bang_macro { @@ -311,7 +310,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { Node::Item(_) if is_bang_macro && !please_inline && renamed.is_some() && is_hidden => { return false; } - Node::Item(&hir::Item { kind: hir::ItemKind::Mod(m), .. }) if glob => { + Node::Item(&hir::Item { kind: hir::ItemKind::Mod(_, m), .. }) if glob => { let prev = mem::replace(&mut self.inlining, true); for &i in m.item_ids { let i = tcx.hir_item(i); @@ -378,7 +377,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // attribute can still be visible. || match item.kind { hir::ItemKind::Impl(..) => true, - hir::ItemKind::Macro(_, MacroKind::Bang) => { + hir::ItemKind::Macro(_, _, MacroKind::Bang) => { self.cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) } _ => false, @@ -419,7 +418,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } return; } - let name = renamed.unwrap_or(item.ident.name); + let get_name = || renamed.unwrap_or(item.kind.ident().unwrap().name); let tcx = self.cx.tcx; let def_id = item.owner_id.to_def_id(); @@ -459,15 +458,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } _ => false, }); - let is_glob = kind == hir::UseKind::Glob; - let ident = if is_glob { None } else { Some(name) }; - if self.maybe_inline_local( - item.owner_id.def_id, - res, - ident, - is_glob, - please_inline, - ) { + let ident = match kind { + hir::UseKind::Single(ident) => Some(renamed.unwrap_or(ident.name)), + hir::UseKind::Glob => None, + hir::UseKind::ListStem => unreachable!(), + }; + if self.maybe_inline_local(item.owner_id.def_id, res, ident, please_inline) + { debug!("Inlining {:?}", item.owner_id.def_id); continue; } @@ -475,7 +472,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { self.add_to_current_mod(item, renamed, import_id); } } - hir::ItemKind::Macro(macro_def, _) => { + hir::ItemKind::Macro(_, macro_def, _) => { // `#[macro_export] macro_rules!` items are handled separately in `visit()`, // above, since they need to be documented at the module top level. Accordingly, // we only want to handle macros if one of three conditions holds: @@ -495,8 +492,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { self.add_to_current_mod(item, renamed, import_id); } } - hir::ItemKind::Mod(m) => { - self.enter_mod(item.owner_id.def_id, m, name, renamed, import_id); + hir::ItemKind::Mod(_, m) => { + self.enter_mod(item.owner_id.def_id, m, get_name(), renamed, import_id); } hir::ItemKind::Fn { .. } | hir::ItemKind::ExternCrate(..) @@ -512,7 +509,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { hir::ItemKind::Const(..) => { // Underscore constants do not correspond to a nameable item and // so are never useful in documentation. - if name != kw::Underscore { + if get_name() != kw::Underscore { self.add_to_current_mod(item, renamed, import_id); } } diff --git a/src/llvm-project b/src/llvm-project -Subproject 1c3bb96fdb6db7b8e8f24edb016099c223fdd27 +Subproject acaea3d2bb8f351b740db7ebce7d7a40b9e2148 diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 8ec7cffe066..44e82c7d8b1 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -30,7 +30,7 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc /// This integer is incremented with every breaking change to the API, /// and is returned along with the JSON blob as [`Crate::format_version`]. /// Consuming code should assert that this value matches the format version(s) that it supports. -pub const FORMAT_VERSION: u32 = 41; +pub const FORMAT_VERSION: u32 = 42; /// The root of the emitted JSON blob. /// @@ -229,6 +229,8 @@ pub enum GenericArgs { /// The output type provided after the `->`, if present. output: Option<Type>, }, + /// `T::method(..)` + ReturnTypeNotation, } /// One argument in a list of generic arguments to a path segment. diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs index c0ae4960e10..39528a8f55c 100644 --- a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs +++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs @@ -5,7 +5,7 @@ use clippy_config::types::{ }; use clippy_utils::diagnostics::span_lint_and_note; use rustc_hir::{ - AssocItemKind, FieldDef, HirId, ImplItemRef, IsAuto, Item, ItemKind, Mod, QPath, TraitItemRef, TyKind, UseKind, + AssocItemKind, FieldDef, HirId, ImplItemRef, IsAuto, Item, ItemKind, Mod, QPath, TraitItemRef, TyKind, Variant, VariantData, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; @@ -178,8 +178,8 @@ impl ArbitrarySourceItemOrdering { /// Produces a linting warning for incorrectly ordered item members. fn lint_member_name<T: LintContext>( cx: &T, - ident: &rustc_span::symbol::Ident, - before_ident: &rustc_span::symbol::Ident, + ident: &rustc_span::Ident, + before_ident: &rustc_span::Ident, ) { span_lint_and_note( cx, @@ -192,21 +192,21 @@ impl ArbitrarySourceItemOrdering { } fn lint_member_item<T: LintContext>(cx: &T, item: &Item<'_>, before_item: &Item<'_>) { - let span = if item.ident.as_str().is_empty() { - &item.span + let span = if let Some(ident) = item.kind.ident() { + ident.span } else { - &item.ident.span + item.span }; - let (before_span, note) = if before_item.ident.as_str().is_empty() { + let (before_span, note) = if let Some(ident) = before_item.kind.ident() { ( - &before_item.span, - "should be placed before the following item".to_owned(), + ident.span, + format!("should be placed before `{}`", ident.as_str(),), ) } else { ( - &before_item.ident.span, - format!("should be placed before `{}`", before_item.ident.as_str(),), + before_item.span, + "should be placed before the following item".to_owned(), ) }; @@ -218,9 +218,9 @@ impl ArbitrarySourceItemOrdering { span_lint_and_note( cx, ARBITRARY_SOURCE_ITEM_ORDERING, - *span, + span, "incorrect ordering of items (must be alphabetically ordered)", - Some(*before_span), + Some(before_span), note, ); } @@ -244,7 +244,7 @@ impl ArbitrarySourceItemOrdering { impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { match &item.kind { - ItemKind::Enum(enum_def, _generics) if self.enable_ordering_for_enum => { + ItemKind::Enum(_, enum_def, _generics) if self.enable_ordering_for_enum => { let mut cur_v: Option<&Variant<'_>> = None; for variant in enum_def.variants { if variant.span.in_external_macro(cx.sess().source_map()) { @@ -259,7 +259,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { cur_v = Some(variant); } }, - ItemKind::Struct(VariantData::Struct { fields, .. }, _generics) if self.enable_ordering_for_struct => { + ItemKind::Struct(_, VariantData::Struct { fields, .. }, _generics) if self.enable_ordering_for_struct => { let mut cur_f: Option<&FieldDef<'_>> = None; for field in *fields { if field.span.in_external_macro(cx.sess().source_map()) { @@ -274,7 +274,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { cur_f = Some(field); } }, - ItemKind::Trait(is_auto, _safety, _generics, _generic_bounds, item_ref) + ItemKind::Trait(is_auto, _safety, _ident, _generics, _generic_bounds, item_ref) if self.enable_ordering_for_trait && *is_auto == IsAuto::No => { let mut cur_t: Option<&TraitItemRef> = None; @@ -351,50 +351,24 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { continue; } - // The following exceptions (skipping with `continue;`) may not be - // complete, edge cases have not been explored further than what - // appears in the existing code base. - if item.ident.name == rustc_span::symbol::kw::Empty { - if let ItemKind::Impl(_) = item.kind { - // Sorting trait impls for unnamed types makes no sense. - if get_item_name(item).is_empty() { - continue; - } - } else if let ItemKind::ForeignMod { .. } = item.kind { - continue; - } else if let ItemKind::GlobalAsm { .. } = item.kind { - continue; - } else if let ItemKind::Use(path, use_kind) = item.kind { - if path.segments.is_empty() { - // Use statements that contain braces get caught here. - // They will still be linted internally. - continue; - } else if path.segments.len() >= 2 - && (path.segments[0].ident.name == rustc_span::sym::std - || path.segments[0].ident.name == rustc_span::sym::core) - && path.segments[1].ident.name == rustc_span::sym::prelude - { - // Filters the autogenerated prelude use statement. - // e.g. `use std::prelude::rustc_2021` - } else if use_kind == UseKind::Glob { - // Filters glob kinds of uses. - // e.g. `use std::sync::*` - } else { - // This can be used for debugging. - // println!("Unknown autogenerated use statement: {:?}", item); - } - continue; - } - } + let ident = if let Some(ident) = item.kind.ident() { + ident + } else if let ItemKind::Impl(_) = item.kind + && !get_item_name(item).is_empty() + { + rustc_span::Ident::empty() // FIXME: a bit strange, is there a better way to do it? + } else { + continue; + }; - if item.ident.name.as_str().starts_with('_') { + if ident.name.as_str().starts_with('_') { // Filters out unnamed macro-like impls for various derives, // e.g. serde::Serialize or num_derive::FromPrimitive. continue; } - if item.ident.name == rustc_span::sym::std && item.span.is_dummy() { - if let ItemKind::ExternCrate(None) = item.kind { + if ident.name == rustc_span::sym::std && item.span.is_dummy() { + if let ItemKind::ExternCrate(None, _) = item.kind { // Filters the auto-included Rust standard library. continue; } @@ -525,6 +499,8 @@ fn get_item_name(item: &Item<'_>) -> String { String::new() } }, - _ => item.ident.name.as_str().to_owned(), + // FIXME: `Ident::empty` for anonymous items is a bit strange, is there + // a better way to do it? + _ => item.kind.ident().unwrap_or(rustc_span::Ident::empty()).name.as_str().to_owned(), } } diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs index f9a2f011a14..54ec8c7b275 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/mod.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs @@ -16,7 +16,7 @@ mod utils; use clippy_config::Conf; use clippy_utils::msrvs::{self, Msrv, MsrvStack}; use rustc_ast::{self as ast, Attribute, MetaItemInner, MetaItemKind}; -use rustc_hir::{ImplItem, Item, TraitItem}; +use rustc_hir::{ImplItem, Item, ItemKind, TraitItem}; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; use rustc_session::impl_lint_pass; use rustc_span::sym; @@ -466,8 +466,8 @@ impl Attributes { impl<'tcx> LateLintPass<'tcx> for Attributes { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { let attrs = cx.tcx.hir_attrs(item.hir_id()); - if is_relevant_item(cx, item) { - inline_always::check(cx, item.span, item.ident.name, attrs); + if let ItemKind::Fn { ident, .. } = item.kind && is_relevant_item(cx, item) { + inline_always::check(cx, item.span, ident.name, attrs); } repr_attributes::check(cx, item.span, attrs, self.msrv); } diff --git a/src/tools/clippy/clippy_lints/src/attrs/utils.rs b/src/tools/clippy/clippy_lints/src/attrs/utils.rs index 0e650e49392..a5ce2137bff 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/utils.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/utils.rs @@ -24,7 +24,7 @@ pub(super) fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool { if let ItemKind::Fn { body: eid, .. } = item.kind { is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir_body(eid).value) } else { - true + false } } diff --git a/src/tools/clippy/clippy_lints/src/default.rs b/src/tools/clippy/clippy_lints/src/default.rs index ffdd946aadb..886c325b355 100644 --- a/src/tools/clippy/clippy_lints/src/default.rs +++ b/src/tools/clippy/clippy_lints/src/default.rs @@ -134,7 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for Default { && let ty::Adt(adt, args) = *binding_type.kind() && adt.is_struct() && let variant = adt.non_enum_variant() - && (adt.did().is_local() || !variant.is_field_list_non_exhaustive()) + && !variant.field_list_has_applicable_non_exhaustive() && let module_did = cx.tcx.parent_module(stmt.hir_id) && variant .fields diff --git a/src/tools/clippy/clippy_lints/src/disallowed_types.rs b/src/tools/clippy/clippy_lints/src/disallowed_types.rs index 3659946b704..38903596414 100644 --- a/src/tools/clippy/clippy_lints/src/disallowed_types.rs +++ b/src/tools/clippy/clippy_lints/src/disallowed_types.rs @@ -99,7 +99,7 @@ impl_lint_pass!(DisallowedTypes => [DISALLOWED_TYPES]); impl<'tcx> LateLintPass<'tcx> for DisallowedTypes { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { - if let ItemKind::Use(path, UseKind::Single) = &item.kind { + if let ItemKind::Use(path, UseKind::Single(_)) = &item.kind { for res in &path.res { self.check_res_emit(cx, res, item.span); } diff --git a/src/tools/clippy/clippy_lints/src/enum_clike.rs b/src/tools/clippy/clippy_lints/src/enum_clike.rs index 2e1f8ac615a..f01b5c840d2 100644 --- a/src/tools/clippy/clippy_lints/src/enum_clike.rs +++ b/src/tools/clippy/clippy_lints/src/enum_clike.rs @@ -38,7 +38,7 @@ impl<'tcx> LateLintPass<'tcx> for UnportableVariant { if cx.tcx.data_layout.pointer_size.bits() != 64 { return; } - if let ItemKind::Enum(def, _) = &item.kind { + if let ItemKind::Enum(_, def, _) = &item.kind { for var in def.variants { if let Some(anon_const) = &var.disr_expr { let def_id = cx.tcx.hir_body_owner_def_id(anon_const.body); diff --git a/src/tools/clippy/clippy_lints/src/error_impl_error.rs b/src/tools/clippy/clippy_lints/src/error_impl_error.rs index 1e6447dc253..6525648efb1 100644 --- a/src/tools/clippy/clippy_lints/src/error_impl_error.rs +++ b/src/tools/clippy/clippy_lints/src/error_impl_error.rs @@ -37,8 +37,8 @@ declare_lint_pass!(ErrorImplError => [ERROR_IMPL_ERROR]); impl<'tcx> LateLintPass<'tcx> for ErrorImplError { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { match item.kind { - ItemKind::TyAlias(..) - if item.ident.name == sym::Error + ItemKind::TyAlias(ident, ..) + if ident.name == sym::Error && is_visible_outside_module(cx, item.owner_id.def_id) && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && let Some(error_def_id) = cx.tcx.get_diagnostic_item(sym::Error) @@ -47,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for ErrorImplError { span_lint( cx, ERROR_IMPL_ERROR, - item.ident.span, + ident.span, "exported type alias named `Error` that implements `Error`", ); }, diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 9298f56b68b..3433b2cd857 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -91,7 +91,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal { } // find `self` ty for this trait if relevant - if let ItemKind::Trait(_, _, _, _, items) = item.kind { + if let ItemKind::Trait(_, _, _, _, _, items) = item.kind { for trait_item in items { if trait_item.id.owner_id.def_id == fn_def_id { // be sure we have `self` parameter in this function diff --git a/src/tools/clippy/clippy_lints/src/excessive_bools.rs b/src/tools/clippy/clippy_lints/src/excessive_bools.rs index 54a1ac21c85..2509c04cd86 100644 --- a/src/tools/clippy/clippy_lints/src/excessive_bools.rs +++ b/src/tools/clippy/clippy_lints/src/excessive_bools.rs @@ -122,7 +122,7 @@ fn check_fn_decl(cx: &LateContext<'_>, decl: &FnDecl<'_>, sp: Span, max: u64) { impl<'tcx> LateLintPass<'tcx> for ExcessiveBools { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { - if let ItemKind::Struct(variant_data, _) = &item.kind + if let ItemKind::Struct(_, variant_data, _) = &item.kind && variant_data.fields().len() as u64 > self.max_struct_bools && has_n_bools( variant_data.fields().iter().map(|field| field.ty), diff --git a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs index 591912cc8d5..5a74e97c97c 100644 --- a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs +++ b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs @@ -76,7 +76,7 @@ impl LateLintPass<'_> for ExhaustiveItems { "exported enums should not be exhaustive", [].as_slice(), ), - ItemKind::Struct(v, ..) => ( + ItemKind::Struct(_, v, ..) => ( EXHAUSTIVE_STRUCTS, "exported structs should not be exhaustive", v.fields(), diff --git a/src/tools/clippy/clippy_lints/src/functions/result.rs b/src/tools/clippy/clippy_lints/src/functions/result.rs index cade56f5822..07a92a4ed70 100644 --- a/src/tools/clippy/clippy_lints/src/functions/result.rs +++ b/src/tools/clippy/clippy_lints/src/functions/result.rs @@ -103,7 +103,7 @@ fn check_result_large_err<'tcx>(cx: &LateContext<'tcx>, err_ty: Ty<'tcx>, hir_ty .did() .as_local() && let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(local_def_id) - && let hir::ItemKind::Enum(ref def, _) = item.kind + && let hir::ItemKind::Enum(_, ref def, _) = item.kind { let variants_size = AdtVariantInfo::new(cx, *adt, subst); if let Some((first_variant, variants)) = variants_size.split_first() diff --git a/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs b/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs index 6363f717a5c..8de6125d1f2 100644 --- a/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs +++ b/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs @@ -8,7 +8,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::{EnumDef, FieldDef, Item, ItemKind, OwnerId, Variant, VariantData}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; -use rustc_span::Span; +use rustc_span::{Ident, Span}; use rustc_span::symbol::Symbol; declare_clippy_lint! { @@ -196,16 +196,16 @@ fn have_no_extra_prefix(prefixes: &[&str]) -> bool { prefixes.iter().all(|p| p == &"" || p == &"_") } -fn check_fields(cx: &LateContext<'_>, threshold: u64, item: &Item<'_>, fields: &[FieldDef<'_>]) { +fn check_fields(cx: &LateContext<'_>, threshold: u64, ident: Ident, span: Span, fields: &[FieldDef<'_>]) { if (fields.len() as u64) < threshold { return; } - check_struct_name_repetition(cx, item, fields); + check_struct_name_repetition(cx, ident, fields); // if the SyntaxContext of the identifiers of the fields and struct differ dont lint them. // this prevents linting in macros in which the location of the field identifier names differ - if !fields.iter().all(|field| item.ident.span.eq_ctxt(field.ident.span)) { + if !fields.iter().all(|field| ident.span.eq_ctxt(field.ident.span)) { return; } @@ -256,7 +256,7 @@ fn check_fields(cx: &LateContext<'_>, threshold: u64, item: &Item<'_>, fields: & span_lint_and_help( cx, STRUCT_FIELD_NAMES, - item.span, + span, format!("all fields have the same {what}fix: `{value}`"), None, format!("remove the {what}fixes"), @@ -264,11 +264,11 @@ fn check_fields(cx: &LateContext<'_>, threshold: u64, item: &Item<'_>, fields: & } } -fn check_struct_name_repetition(cx: &LateContext<'_>, item: &Item<'_>, fields: &[FieldDef<'_>]) { - let snake_name = to_snake_case(item.ident.name.as_str()); +fn check_struct_name_repetition(cx: &LateContext<'_>, ident: Ident, fields: &[FieldDef<'_>]) { + let snake_name = to_snake_case(ident.name.as_str()); let item_name_words: Vec<&str> = snake_name.split('_').collect(); for field in fields { - if field.ident.span.eq_ctxt(item.ident.span) { + if field.ident.span.eq_ctxt(ident.span) { //consider linting only if the field identifier has the same SyntaxContext as the item(struct) let field_words: Vec<&str> = field.ident.name.as_str().split('_').collect(); if field_words.len() >= item_name_words.len() { @@ -397,19 +397,23 @@ fn check_variant(cx: &LateContext<'_>, threshold: u64, def: &EnumDef<'_>, item_n } impl LateLintPass<'_> for ItemNameRepetitions { - fn check_item_post(&mut self, _cx: &LateContext<'_>, _item: &Item<'_>) { + fn check_item_post(&mut self, _cx: &LateContext<'_>, item: &Item<'_>) { + let Some(_ident) = item.kind.ident() else { return }; + let last = self.modules.pop(); assert!(last.is_some()); } fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { - let item_name = item.ident.name.as_str(); + let Some(ident) = item.kind.ident() else { return }; + + let item_name = ident.name.as_str(); let item_camel = to_camel_case(item_name); if !item.span.from_expansion() && is_present_in_source(cx, item.span) { if let [.., (mod_name, mod_camel, mod_owner_id)] = &*self.modules { // constants don't have surrounding modules if !mod_camel.is_empty() { - if mod_name == &item.ident.name + if mod_name == &ident.name && let ItemKind::Mod(..) = item.kind && (!self.allow_private_module_inception || cx.tcx.visibility(mod_owner_id.def_id).is_public()) { @@ -438,7 +442,7 @@ impl LateLintPass<'_> for ItemNameRepetitions { Some(c) if is_word_beginning(c) => span_lint( cx, MODULE_NAME_REPETITIONS, - item.ident.span, + ident.span, "item name starts with its containing module's name", ), _ => (), @@ -450,7 +454,7 @@ impl LateLintPass<'_> for ItemNameRepetitions { span_lint( cx, MODULE_NAME_REPETITIONS, - item.ident.span, + ident.span, "item name ends with its containing module's name", ); } @@ -462,13 +466,13 @@ impl LateLintPass<'_> for ItemNameRepetitions { && span_is_local(item.span) { match item.kind { - ItemKind::Enum(def, _) => check_variant(cx, self.enum_threshold, &def, item_name, item.span), - ItemKind::Struct(VariantData::Struct { fields, .. }, _) => { - check_fields(cx, self.struct_threshold, item, fields); + ItemKind::Enum(_, def, _) => check_variant(cx, self.enum_threshold, &def, item_name, item.span), + ItemKind::Struct(_, VariantData::Struct { fields, .. }, _) => { + check_fields(cx, self.struct_threshold, ident, item.span, fields); }, _ => (), } } - self.modules.push((item.ident.name, item_camel, item.owner_id)); + self.modules.push((ident.name, item_camel, item.owner_id)); } } diff --git a/src/tools/clippy/clippy_lints/src/items_after_test_module.rs b/src/tools/clippy/clippy_lints/src/items_after_test_module.rs index 9df044f25eb..dd63de288b8 100644 --- a/src/tools/clippy/clippy_lints/src/items_after_test_module.rs +++ b/src/tools/clippy/clippy_lints/src/items_after_test_module.rs @@ -44,7 +44,7 @@ declare_clippy_lint! { declare_lint_pass!(ItemsAfterTestModule => [ITEMS_AFTER_TEST_MODULE]); fn cfg_test_module<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool { - if let ItemKind::Mod(test_mod) = item.kind + if let ItemKind::Mod(_, test_mod) = item.kind && item.span.hi() == test_mod.spans.inner_span.hi() && is_cfg_test(cx.tcx, item.hir_id()) && !item.span.from_expansion() @@ -67,14 +67,20 @@ impl LateLintPass<'_> for ItemsAfterTestModule { let after: Vec<_> = items .filter(|item| { // Ignore the generated test main function - !(item.ident.name == sym::main - && item.span.ctxt().outer_expn_data().kind == ExpnKind::AstPass(AstPass::TestHarness)) + if let ItemKind::Fn { ident, .. } = item.kind + && ident.name == sym::main + && item.span.ctxt().outer_expn_data().kind == ExpnKind::AstPass(AstPass::TestHarness) + { + false + } else { + true + } }) .collect(); if let Some(last) = after.last() && after.iter().all(|&item| { - !matches!(item.kind, ItemKind::Mod(_)) && !item.span.from_expansion() && !is_from_proc_macro(cx, item) + !matches!(item.kind, ItemKind::Mod(..)) && !item.span.from_expansion() && !is_from_proc_macro(cx, item) }) && !fulfill_or_allowed(cx, ITEMS_AFTER_TEST_MODULE, after.iter().map(|item| item.hir_id())) { diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs index cabf10b7e0e..394005e9912 100644 --- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs @@ -48,7 +48,7 @@ impl_lint_pass!(LargeConstArrays => [LARGE_CONST_ARRAYS]); impl<'tcx> LateLintPass<'tcx> for LargeConstArrays { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { - if let ItemKind::Const(_, generics, _) = &item.kind + if let ItemKind::Const(ident, _, generics, _) = &item.kind // Since static items may not have generics, skip generic const items. // FIXME(generic_const_items): I don't think checking `generics.hwcp` suffices as it // doesn't account for empty where-clauses that only consist of keyword `where` IINM. @@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays { && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()) && u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size) { - let hi_pos = item.ident.span.lo() - BytePos::from_usize(1); + let hi_pos = ident.span.lo() - BytePos::from_usize(1); let sugg_span = Span::new( hi_pos - BytePos::from_usize("const".len()), hi_pos, diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs index d9953dbc261..d08efa0ec9c 100644 --- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs +++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs @@ -73,7 +73,7 @@ impl_lint_pass!(LargeEnumVariant => [LARGE_ENUM_VARIANT]); impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &Item<'tcx>) { - if let ItemKind::Enum(ref def, _) = item.kind + if let ItemKind::Enum(ident, ref def, _) = item.kind && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && let ty::Adt(adt, subst) = ty.kind() && adt.variants().len() > 1 @@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant { let mut applicability = Applicability::MaybeIncorrect; if is_copy(cx, ty) || maybe_copy(cx, ty) { diag.span_note( - item.ident.span, + ident.span, "boxing a variant would require the type no longer be `Copy`", ); } else { diff --git a/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs index 3939318bee6..ca51d8b618e 100644 --- a/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs +++ b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs @@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { // Integer modules are "TBD" deprecated, and the contents are too, // so lint on the `use` statement directly. - if let ItemKind::Use(path, kind @ (UseKind::Single | UseKind::Glob)) = item.kind + if let ItemKind::Use(path, kind @ (UseKind::Single(_) | UseKind::Glob)) = item.kind && !item.span.in_external_macro(cx.sess().source_map()) && let Some(def_id) = path.res[0].opt_def_id() && self.msrv.meets(cx, msrvs::NUMERIC_ASSOCIATED_CONSTANTS) @@ -72,7 +72,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants { "importing a legacy numeric constant" }, |diag| { - if item.ident.name == kw::Underscore { + if let UseKind::Single(ident) = kind && ident.name == kw::Underscore { diag.help("remove this import"); return; } diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index 98ba52f1270..72e22ae59d8 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -17,7 +17,7 @@ use rustc_middle::ty::{self, AssocKind, FnSig, Ty}; use rustc_session::declare_lint_pass; use rustc_span::source_map::Spanned; use rustc_span::symbol::sym; -use rustc_span::{Span, Symbol}; +use rustc_span::{Ident, Span, Symbol}; use rustc_trait_selection::traits::supertrait_def_ids; declare_clippy_lint! { @@ -123,10 +123,10 @@ declare_lint_pass!(LenZero => [LEN_ZERO, LEN_WITHOUT_IS_EMPTY, COMPARISON_TO_EMP impl<'tcx> LateLintPass<'tcx> for LenZero { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { - if let ItemKind::Trait(_, _, _, _, trait_items) = item.kind + if let ItemKind::Trait(_, _, ident, _, _, trait_items) = item.kind && !item.span.from_expansion() { - check_trait_items(cx, item, trait_items); + check_trait_items(cx, item, ident, trait_items); } } @@ -150,10 +150,10 @@ impl<'tcx> LateLintPass<'tcx> for LenZero { let (name, kind) = match cx.tcx.hir_node(ty_hir_id) { Node::ForeignItem(x) => (x.ident.name, "extern type"), Node::Item(x) => match x.kind { - ItemKind::Struct(..) => (x.ident.name, "struct"), - ItemKind::Enum(..) => (x.ident.name, "enum"), - ItemKind::Union(..) => (x.ident.name, "union"), - _ => (x.ident.name, "type"), + ItemKind::Struct(ident, ..) => (ident.name, "struct"), + ItemKind::Enum(ident, ..) => (ident.name, "enum"), + ItemKind::Union(ident, ..) => (ident.name, "union"), + _ => (x.kind.ident().unwrap().name, "type"), }, _ => return, }; @@ -250,7 +250,7 @@ fn span_without_enclosing_paren(cx: &LateContext<'_>, span: Span) -> Span { } } -fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items: &[TraitItemRef]) { +fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Ident, trait_items: &[TraitItemRef]) { fn is_named_self(cx: &LateContext<'_>, item: &TraitItemRef, name: Symbol) -> bool { item.ident.name == name && if let AssocItemKind::Fn { has_self } = item.kind { @@ -300,7 +300,7 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items visited_trait.span, format!( "trait `{}` has a `len` method but no (possibly inherited) `is_empty` method", - visited_trait.ident.name + ident.name ), ); } diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs index fb5d49a1004..5afcf51167d 100644 --- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs +++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs @@ -129,7 +129,7 @@ impl BreakAfterExprVisitor { }; get_enclosing_block(cx, hir_id).is_some_and(|block| { - visitor.visit_block(block); + let _ = visitor.visit_block(block); visitor.break_after_expr }) } diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs index 64b07a5536b..067b92cd46e 100644 --- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs +++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs @@ -87,7 +87,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { } match item.kind { - ItemKind::Enum(def, _) if def.variants.len() > 1 => { + ItemKind::Enum(_, def, _) if def.variants.len() > 1 => { let iter = def.variants.iter().filter_map(|v| { (matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir_attrs(v.hir_id))) .then_some((v.def_id, v.span)) @@ -98,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { self.potential_enums.push((item.owner_id.def_id, id, item.span, span)); } }, - ItemKind::Struct(variant_data, _) => { + ItemKind::Struct(_, variant_data, _) => { let fields = variant_data.fields(); let private_fields = fields .iter() diff --git a/src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs b/src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs index c9251c1b849..fe999a3b5f8 100644 --- a/src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs +++ b/src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs @@ -40,7 +40,7 @@ pub fn check(cx: &LateContext<'_>, call: &Expr<'_>, recv: &Expr<'_>, arg: &Expr< // We've checked that `call` is a call to `Stdin::read_line()` with the right receiver, // now let's check if the first use of the string passed to `::read_line()` // is used for operations that will always fail (e.g. parsing "6\n" into a number) - for_each_local_use_after_expr(cx, local_id, call.hir_id, |expr| { + let _ = for_each_local_use_after_expr(cx, local_id, call.hir_id, |expr| { if let Some(parent) = get_parent_expr(cx, expr) { let data = if let ExprKind::MethodCall(segment, recv, args, span) = parent.kind { if args.is_empty() diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 3470c266c49..b234b190153 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -192,17 +192,17 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) { match it.kind { - hir::ItemKind::Fn { .. } => { + hir::ItemKind::Fn { ident, .. } => { // ignore main() - if it.ident.name == sym::main { + if ident.name == sym::main { let at_root = cx.tcx.local_parent(it.owner_id.def_id) == CRATE_DEF_ID; if at_root { note_prev_span_then_ret!(self.prev_span, it.span); } } }, - hir::ItemKind::Const(..) => { - if it.ident.name == kw::Underscore { + hir::ItemKind::Const(ident, ..) => { + if ident.name == kw::Underscore { note_prev_span_then_ret!(self.prev_span, it.span); } }, diff --git a/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs b/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs index 59f29d242ab..66631a69206 100644 --- a/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs +++ b/src/tools/clippy/clippy_lints/src/missing_enforced_import_rename.rs @@ -67,7 +67,7 @@ impl_lint_pass!(ImportRename => [MISSING_ENFORCED_IMPORT_RENAMES]); impl LateLintPass<'_> for ImportRename { fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { - if let ItemKind::Use(path, UseKind::Single) = &item.kind { + if let ItemKind::Use(path, UseKind::Single(_)) = &item.kind { for &res in &path.res { if let Res::Def(_, id) = res && let Some(name) = self.renames.get(&id) diff --git a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs index 675989156ca..28dc2427428 100644 --- a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs +++ b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs @@ -226,7 +226,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug { && should_lint(cx, typeck_results, block) { // we intentionally only lint structs, see lint description - if let ItemKind::Struct(data, _) = &self_item.kind { + if let ItemKind::Struct(_, data, _) = &self_item.kind { check_struct(cx, typeck_results, block, self_ty, item, data); } } diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index 2c578d81602..8045ab97d38 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -101,7 +101,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { let attrs = cx.tcx.hir_attrs(it.hir_id()); check_missing_inline_attrs(cx, attrs, it.span, desc); }, - hir::ItemKind::Trait(ref _is_auto, ref _unsafe, _generics, _bounds, trait_items) => { + hir::ItemKind::Trait(ref _is_auto, ref _unsafe, _ident, _generics, _bounds, trait_items) => { // note: we need to check if the trait is exported so we can't use // `LateLintPass::check_trait_item` here. for tit in trait_items { diff --git a/src/tools/clippy/clippy_lints/src/needless_update.rs b/src/tools/clippy/clippy_lints/src/needless_update.rs index 0cba72bd2c6..cce0617ba39 100644 --- a/src/tools/clippy/clippy_lints/src/needless_update.rs +++ b/src/tools/clippy/clippy_lints/src/needless_update.rs @@ -54,8 +54,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessUpdate { if let ExprKind::Struct(_, fields, StructTailExpr::Base(base)) = expr.kind { let ty = cx.typeck_results().expr_ty(expr); if let ty::Adt(def, _) = ty.kind() { - if fields.len() == def.non_enum_variant().fields.len() - && !def.variant(0_usize.into()).is_field_list_non_exhaustive() + let variant = def.non_enum_variant(); + if fields.len() == variant.fields.len() + && !variant.is_field_list_non_exhaustive() { span_lint( cx, diff --git a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs index fe8a02c64c6..b71dde90691 100644 --- a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs +++ b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs @@ -37,12 +37,12 @@ declare_lint_pass!(NoMangleWithRustAbi => [NO_MANGLE_WITH_RUST_ABI]); impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { - if let ItemKind::Fn { sig: fn_sig, .. } = &item.kind + if let ItemKind::Fn { ident, sig: fn_sig, .. } = &item.kind && !item.span.from_expansion() { let attrs = cx.tcx.hir_attrs(item.hir_id()); let mut app = Applicability::MaybeIncorrect; - let fn_snippet = snippet_with_applicability(cx, fn_sig.span.with_hi(item.ident.span.lo()), "..", &mut app); + let fn_snippet = snippet_with_applicability(cx, fn_sig.span.with_hi(ident.span.lo()), "..", &mut app); for attr in attrs { if let Some(ident) = attr.ident() && ident.name == rustc_span::sym::no_mangle diff --git a/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs b/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs index a82365f9431..8305bf345ef 100644 --- a/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs +++ b/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs @@ -192,7 +192,7 @@ struct LazyInfo { impl LazyInfo { fn from_item(state: &NonStdLazyStatic, cx: &LateContext<'_>, item: &Item<'_>) -> Option<Self> { // Check if item is a `once_cell:sync::Lazy` static. - if let ItemKind::Static(ty, _, body_id) = item.kind + if let ItemKind::Static(_, ty, _, body_id) = item.kind && let Some(path_def_id) = path_def_id(cx, ty) && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind && state.once_cell_sync_lazy.contains(&path_def_id) diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index 320c0286bb7..0a8e2885648 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -141,7 +141,7 @@ impl PassByRefOrValue { // Gather all the lifetimes found in the output type which may affect whether // `TRIVIALLY_COPY_PASS_BY_REF` should be linted. let mut output_regions = FxHashSet::default(); - for_each_top_level_late_bound_region(fn_sig.skip_binder().output(), |region| -> ControlFlow<!> { + let _ = for_each_top_level_late_bound_region(fn_sig.skip_binder().output(), |region| -> ControlFlow<!> { output_regions.insert(region); ControlFlow::Continue(()) }); diff --git a/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs b/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs index fd21893232d..e4a9bf7a848 100644 --- a/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs +++ b/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs @@ -58,7 +58,7 @@ impl PubUnderscoreFields { impl<'tcx> LateLintPass<'tcx> for PubUnderscoreFields { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { // This lint only pertains to structs. - let ItemKind::Struct(variant_data, _) = &item.kind else { + let ItemKind::Struct(_, variant_data, _) = &item.kind else { return; }; diff --git a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs index 6a17b83b3d0..3a5f44db872 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs @@ -52,7 +52,11 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate { && is_not_macro_export(item) && !item.span.in_external_macro(cx.sess().source_map()) { - let span = item.span.with_hi(item.ident.span.hi()); + // FIXME: `DUMMY_SP` isn't right here, because it causes the + // resulting span to begin at the start of the file. + let span = item.span.with_hi( + item.kind.ident().map(|ident| ident.span.hi()).unwrap_or(rustc_span::DUMMY_SP.hi()) + ); let descr = cx.tcx.def_kind(item.owner_id).descr(item.owner_id.to_def_id()); span_lint_and_then( cx, diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs index 8b2d597b9e3..534ba3a50c6 100644 --- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs +++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs @@ -73,7 +73,8 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors { if let Some(self_def) = self_ty.ty_adt_def() && let Some(self_local_did) = self_def.did().as_local() && let Node::Item(x) = cx.tcx.hir_node_by_def_id(self_local_did) - && let type_name = x.ident.name.as_str().to_lowercase() + && let Some(type_ident) = x.kind.ident() + && let type_name = type_ident.name.as_str().to_lowercase() && (impl_item.ident.name.as_str() == type_name || impl_item.ident.name.as_str().replace('_', "") == type_name) { diff --git a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs index 82cc5155380..20bf3a0bff1 100644 --- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs +++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs @@ -57,7 +57,7 @@ impl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray { } fn is_struct_with_trailing_zero_sized_array<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool { - if let ItemKind::Struct(data, _) = &item.kind + if let ItemKind::Struct(_, data, _) = &item.kind && let Some(last_field) = data.fields().last() && let field_ty = cx.tcx.normalize_erasing_regions( cx.typing_env(), diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs index f961e1c4d1a..fa36c9a21f6 100644 --- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs +++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs @@ -112,7 +112,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { // special handling for self trait bounds as these are not considered generics // ie. trait Foo: Display {} if let Item { - kind: ItemKind::Trait(_, _, _, bounds, ..), + kind: ItemKind::Trait(_, _, _, _, bounds, ..), .. } = item { @@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { .. }) = segments.first() && let Some(Node::Item(Item { - kind: ItemKind::Trait(_, _, _, self_bounds, _), + kind: ItemKind::Trait(_, _, _, _, self_bounds, _), .. })) = cx.tcx.hir_get_if_local(*def_id) { diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs index 151a6f67437..2e974374c99 100644 --- a/src/tools/clippy/clippy_lints/src/types/mod.rs +++ b/src/tools/clippy/clippy_lints/src/types/mod.rs @@ -451,7 +451,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id); match item.kind { - ItemKind::Static(ty, _, _) | ItemKind::Const(ty, _, _) => self.check_ty( + ItemKind::Static(_, ty, _, _) | ItemKind::Const(_, ty, _, _) => self.check_ty( cx, ty, CheckTyContext { diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs index a443043bef9..51c7d6fce31 100644 --- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs @@ -381,7 +381,7 @@ impl UnconditionalRecursion { implemented_ty_id, method_span, }; - walk_body(&mut c, body); + let _ = walk_body(&mut c, body); } } } diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs index be533ca915e..4f1a017522e 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -454,7 +454,7 @@ fn item_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) -> HasSaf let comment_start = match cx.tcx.parent_hir_node(item.hir_id()) { Node::Crate(parent_mod) => comment_start_before_item_in_mod(cx, parent_mod, parent_mod.spans.inner_span, item), Node::Item(parent_item) => { - if let ItemKind::Mod(parent_mod) = &parent_item.kind { + if let ItemKind::Mod(_, parent_mod) = &parent_item.kind { comment_start_before_item_in_mod(cx, parent_mod, parent_item.span, item) } else { // Doesn't support impls in this position. Pretend a comment was found. @@ -614,7 +614,7 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> { .. }) => maybe_global_var = true, Node::Item(hir::Item { - kind: ItemKind::Mod(_), + kind: ItemKind::Mod(..), span: item_span, .. }) => { diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs b/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs index 4158050f969..2b7d3dc0c90 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs @@ -130,9 +130,9 @@ impl LateLintPass<'_> for UnnecessaryBoxReturns { } fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { - let ItemKind::Fn { sig, .. } = &item.kind else { + let ItemKind::Fn { ident, sig, .. } = &item.kind else { return; }; - self.check_fn_item(cx, sig.decl, item.owner_id.def_id, item.ident.name); + self.check_fn_item(cx, sig.decl, item.owner_id.def_id, ident.name); } } diff --git a/src/tools/clippy/clippy_lints/src/unneeded_struct_pattern.rs b/src/tools/clippy/clippy_lints/src/unneeded_struct_pattern.rs index a74eab8b6ae..3326dea8c5d 100644 --- a/src/tools/clippy/clippy_lints/src/unneeded_struct_pattern.rs +++ b/src/tools/clippy/clippy_lints/src/unneeded_struct_pattern.rs @@ -51,7 +51,7 @@ impl LateLintPass<'_> for UnneededStructPattern { let variant = cx.tcx.adt_def(enum_did).variant_with_id(did); let has_only_fields_brackets = variant.ctor.is_some() && variant.fields.is_empty(); - let non_exhaustive_activated = !variant.def_id.is_local() && variant.is_field_list_non_exhaustive(); + let non_exhaustive_activated = variant.field_list_has_applicable_non_exhaustive(); if !has_only_fields_brackets || non_exhaustive_activated { return; } diff --git a/src/tools/clippy/clippy_lints/src/unused_trait_names.rs b/src/tools/clippy/clippy_lints/src/unused_trait_names.rs index 2577f1ceaa2..14ac65cf4df 100644 --- a/src/tools/clippy/clippy_lints/src/unused_trait_names.rs +++ b/src/tools/clippy/clippy_lints/src/unused_trait_names.rs @@ -60,9 +60,9 @@ impl_lint_pass!(UnusedTraitNames => [UNUSED_TRAIT_NAMES]); impl<'tcx> LateLintPass<'tcx> for UnusedTraitNames { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { if !item.span.in_external_macro(cx.sess().source_map()) - && let ItemKind::Use(path, UseKind::Single) = item.kind + && let ItemKind::Use(path, UseKind::Single(ident)) = item.kind // Ignore imports that already use Underscore - && item.ident.name != kw::Underscore + && ident.name != kw::Underscore // Only check traits && let Some(Res::Def(DefKind::Trait, _)) = path.res.first() && cx.tcx.maybe_unused_trait_imports(()).contains(&item.owner_id.def_id) @@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedTraitNames { && self.msrv.meets(cx, msrvs::UNDERSCORE_IMPORTS) && !is_from_proc_macro(cx, &last_segment.ident) { - let complete_span = last_segment.ident.span.to(item.ident.span); + let complete_span = last_segment.ident.span.to(ident.span); span_lint_and_sugg( cx, UNUSED_TRAIT_NAMES, diff --git a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs index 3449468ef48..8922478e718 100644 --- a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs +++ b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs @@ -131,11 +131,11 @@ impl LateLintPass<'_> for UpperCaseAcronyms { return; } match it.kind { - ItemKind::TyAlias(..) | ItemKind::Struct(..) | ItemKind::Trait(..) => { - check_ident(cx, &it.ident, it.hir_id(), self.upper_case_acronyms_aggressive); + ItemKind::TyAlias(ident, ..) | ItemKind::Struct(ident, ..) | ItemKind::Trait(_, _, ident, ..) => { + check_ident(cx, &ident, it.hir_id(), self.upper_case_acronyms_aggressive); }, - ItemKind::Enum(ref enumdef, _) => { - check_ident(cx, &it.ident, it.hir_id(), self.upper_case_acronyms_aggressive); + ItemKind::Enum(ident, ref enumdef, _) => { + check_ident(cx, &ident, it.hir_id(), self.upper_case_acronyms_aggressive); // check enum variants separately because again we only want to lint on private enums and // the fn check_variant does not know about the vis of the enum of its variants enumdef.variants.iter().for_each(|variant| { diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index 4f48fb3b8a9..004c840c331 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -242,14 +242,14 @@ fn fn_header_search_pat(header: FnHeader) -> Pat { fn item_search_pat(item: &Item<'_>) -> (Pat, Pat) { let (start_pat, end_pat) = match &item.kind { - ItemKind::ExternCrate(_) => (Pat::Str("extern"), Pat::Str(";")), + ItemKind::ExternCrate(..) => (Pat::Str("extern"), Pat::Str(";")), ItemKind::Static(..) => (Pat::Str("static"), Pat::Str(";")), ItemKind::Const(..) => (Pat::Str("const"), Pat::Str(";")), ItemKind::Fn { sig, .. } => (fn_header_search_pat(sig.header), Pat::Str("")), ItemKind::ForeignMod { .. } => (Pat::Str("extern"), Pat::Str("}")), ItemKind::TyAlias(..) => (Pat::Str("type"), Pat::Str(";")), ItemKind::Enum(..) => (Pat::Str("enum"), Pat::Str("}")), - ItemKind::Struct(VariantData::Struct { .. }, _) => (Pat::Str("struct"), Pat::Str("}")), + ItemKind::Struct(_, VariantData::Struct { .. }, _) => (Pat::Str("struct"), Pat::Str("}")), ItemKind::Struct(..) => (Pat::Str("struct"), Pat::Str(";")), ItemKind::Union(..) => (Pat::Str("union"), Pat::Str("}")), ItemKind::Trait(_, Safety::Unsafe, ..) diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 80613a51c14..eb4e1a7722f 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -644,7 +644,7 @@ fn local_item_children_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, name: Symb let root_mod; let item_kind = match tcx.hir_node_by_def_id(local_id) { Node::Crate(r#mod) => { - root_mod = ItemKind::Mod(r#mod); + root_mod = ItemKind::Mod(Ident::dummy(), r#mod); &root_mod }, Node::Item(item) => &item.kind, @@ -661,10 +661,13 @@ fn local_item_children_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, name: Symb }; match item_kind { - ItemKind::Mod(r#mod) => r#mod + ItemKind::Mod(_, r#mod) => r#mod .item_ids .iter() - .filter_map(|&item_id| res(tcx.hir_item(item_id).ident, item_id.owner_id)) + .filter_map(|&item_id| { + let ident = tcx.hir_item(item_id).kind.ident()?; + res(ident, item_id.owner_id) + }) .collect(), ItemKind::Impl(r#impl) => r#impl .items @@ -1416,8 +1419,8 @@ pub fn is_in_panic_handler(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> { let parent_id = cx.tcx.hir_get_parent_item(expr.hir_id).def_id; match cx.tcx.hir_node_by_def_id(parent_id) { - Node::Item(Item { ident, .. }) - | Node::TraitItem(TraitItem { ident, .. }) + Node::Item(item) => item.kind.ident().map(|ident| ident.name), + Node::TraitItem(TraitItem { ident, .. }) | Node::ImplItem(ImplItem { ident, .. }) => Some(ident.name), _ => None, } @@ -2634,7 +2637,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym for id in tcx.hir_module_free_items(module) { if matches!(tcx.def_kind(id.owner_id), DefKind::Const) && let item = tcx.hir_item(id) - && let ItemKind::Const(ty, _generics, _body) = item.kind + && let ItemKind::Const(ident, ty, _generics, _body) = item.kind { if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind { // We could also check for the type name `test::TestDescAndFn` @@ -2644,7 +2647,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym .iter() .any(|a| a.has_name(sym::rustc_test_marker)); if has_test_marker { - names.push(item.ident.name); + names.push(ident.name); } } } @@ -2668,10 +2671,10 @@ pub fn is_in_test_function(tcx: TyCtxt<'_>, id: HirId) -> bool { // function scope .any(|(_id, node)| { if let Node::Item(item) = node { - if let ItemKind::Fn { .. } = item.kind { + if let ItemKind::Fn { ident, .. } = item.kind { // Note that we have sorted the item names in the visitor, // so the binary_search gets the same as `contains`, but faster. - return names.binary_search(&item.ident.name).is_ok(); + return names.binary_search(&ident.name).is_ok(); } } false diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 2f0c7d8ddc5..b9ae583581e 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -27,7 +27,7 @@ fn main() { eprintln!( r#" WARNING: profiler runtime is not available, so `.coverage` files won't be {actioned} -help: try setting `profiler = true` in the `[build]` section of `config.toml`"# +help: try setting `profiler = true` in the `[build]` section of `bootstrap.toml`"# ); } diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs index 791b231c27a..8c9e4c8bb3a 100644 --- a/src/tools/jsondoclint/src/validator.rs +++ b/src/tools/jsondoclint/src/validator.rs @@ -326,6 +326,7 @@ impl<'a> Validator<'a> { self.check_type(o); } } + GenericArgs::ReturnTypeNotation => {} } } diff --git a/src/tools/linkchecker/Cargo.toml b/src/tools/linkchecker/Cargo.toml index f1be6e9e749..7123d43eb56 100644 --- a/src/tools/linkchecker/Cargo.toml +++ b/src/tools/linkchecker/Cargo.toml @@ -9,4 +9,4 @@ path = "main.rs" [dependencies] regex = "1" -html5ever = "0.27.0" +html5ever = "0.29.0" diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 19340b5d07a..84cba3f8c44 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -16,7 +16,7 @@ //! A few exceptions are allowed as there's known bugs in rustdoc, but this //! should catch the majority of "broken link" cases. -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; use std::collections::{HashMap, HashSet}; use std::io::ErrorKind; use std::path::{Component, Path, PathBuf}; @@ -544,7 +544,7 @@ fn parse_html<Sink: TokenSink>(source: &str, sink: Sink) -> Sink { let mut input = BufferQueue::default(); input.push_back(tendril.try_reinterpret().unwrap()); - let mut tok = Tokenizer::new(sink, TokenizerOpts::default()); + let tok = Tokenizer::new(sink, TokenizerOpts::default()); let _ = tok.feed(&mut input); assert!(input.is_empty()); tok.end(); @@ -554,8 +554,8 @@ fn parse_html<Sink: TokenSink>(source: &str, sink: Sink) -> Sink { #[derive(Default)] struct AttrCollector { attr_name: &'static [u8], - base: Option<String>, - found_attrs: Vec<(u64, String)>, + base: Cell<Option<String>>, + found_attrs: RefCell<Vec<(u64, String)>>, /// Tracks whether or not it is inside a <script> tag. /// /// A lot of our sources have JSON script tags which have HTML embedded @@ -564,13 +564,13 @@ struct AttrCollector { /// `TokenSinkResult::Script(…)` (and then maybe switch parser?), but I /// don't fully understand the best way to use that, and this seems good /// enough for now. - in_script: bool, + in_script: Cell<bool>, } impl TokenSink for AttrCollector { type Handle = (); - fn process_token(&mut self, token: Token, line_number: u64) -> TokenSinkResult<()> { + fn process_token(&self, token: Token, line_number: u64) -> TokenSinkResult<()> { match token { TagToken(tag) => { let tag_name = tag.name.as_bytes(); @@ -578,20 +578,20 @@ impl TokenSink for AttrCollector { if let Some(href) = tag.attrs.iter().find(|attr| attr.name.local.as_bytes() == b"href") { - self.base = Some(href.value.to_string()); + self.base.set(Some(href.value.to_string())); } return TokenSinkResult::Continue; } else if tag_name == b"script" { - self.in_script = !self.in_script; + self.in_script.set(!self.in_script.get()); } - if self.in_script { + if self.in_script.get() { return TokenSinkResult::Continue; } for attr in tag.attrs.iter() { let name = attr.name.local.as_bytes(); if name == self.attr_name { let url = attr.value.to_string(); - self.found_attrs.push((line_number, url)); + self.found_attrs.borrow_mut().push((line_number, url)); } } } @@ -607,7 +607,7 @@ impl TokenSink for AttrCollector { fn get_urls(source: &str) -> (Option<String>, Vec<(u64, String)>) { let collector = AttrCollector { attr_name: b"href", ..AttrCollector::default() }; let sink = parse_html(source, collector); - (sink.base, sink.found_attrs) + (sink.base.into_inner(), sink.found_attrs.into_inner()) } /// Retrieves id="..." attributes from HTML elements. @@ -619,7 +619,7 @@ fn parse_ids(ids: &mut HashSet<String>, file: &str, source: &str, report: &mut R let collector = AttrCollector { attr_name: b"id", ..AttrCollector::default() }; let sink = parse_html(source, collector); - for (line_number, id) in sink.found_attrs { + for (line_number, id) in sink.found_attrs.into_inner() { let encoded = small_url_encode(&id); if let Some(id) = ids.replace(id) { report.errors += 1; diff --git a/src/tools/miri/CONTRIBUTING.md b/src/tools/miri/CONTRIBUTING.md index 5a08ac9af60..0d77ca06e1b 100644 --- a/src/tools/miri/CONTRIBUTING.md +++ b/src/tools/miri/CONTRIBUTING.md @@ -153,7 +153,7 @@ MIRI_LOG=rustc_mir::interpret=info,miri::stacked_borrows ./miri run tests/pass/v Note that you will only get `info`, `warn` or `error` messages if you use a prebuilt compiler. In order to get `debug` and `trace` level messages, you need to build miri with a locally built -compiler that has `debug=true` set in `config.toml`. +compiler that has `debug=true` set in `bootstrap.toml`. #### Debugging error messages diff --git a/src/tools/miri/cargo-miri/src/setup.rs b/src/tools/miri/cargo-miri/src/setup.rs index 0cf6f1a375c..7afc8481009 100644 --- a/src/tools/miri/cargo-miri/src/setup.rs +++ b/src/tools/miri/cargo-miri/src/setup.rs @@ -115,7 +115,7 @@ pub fn setup( // https://github.com/rust-lang/miri/issues/1421, // https://github.com/rust-lang/miri/issues/2429). Looks like setting // `RUSTC_WRAPPER` to the empty string overwrites `build.rustc-wrapper` set via - // `config.toml`. + // `bootstrap.toml`. command.env("RUSTC_WRAPPER", ""); if show_setup { diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 94b593e0e32..db300f1475d 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -9f274ba3997030a2b7656755a6810fd26cb709f3 +70237a8cb905fc48ed6148d2f2dba756535a5940 diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 0bf5ae87f38..03f76cfa652 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -71,6 +71,7 @@ extern crate rustc_index; extern crate rustc_middle; extern crate rustc_session; extern crate rustc_span; +extern crate rustc_symbol_mangling; extern crate rustc_target; // Linking `rustc_driver` pulls in the required object code as the rest of the rustc crates are // shipped only as rmeta files. diff --git a/src/tools/miri/src/shims/extern_static.rs b/src/tools/miri/src/shims/extern_static.rs index 20dd3c8db2a..2feed5a8352 100644 --- a/src/tools/miri/src/shims/extern_static.rs +++ b/src/tools/miri/src/shims/extern_static.rs @@ -1,5 +1,7 @@ //! Provides the `extern static` that this platform expects. +use rustc_symbol_mangling::mangle_internal_symbol; + use crate::*; impl<'tcx> MiriMachine<'tcx> { @@ -50,7 +52,11 @@ impl<'tcx> MiriMachine<'tcx> { // "__rust_alloc_error_handler_should_panic" let val = ecx.tcx.sess.opts.unstable_opts.oom.should_panic(); let val = ImmTy::from_int(val, ecx.machine.layouts.u8); - Self::alloc_extern_static(ecx, "__rust_alloc_error_handler_should_panic", val)?; + Self::alloc_extern_static( + ecx, + &mangle_internal_symbol(*ecx.tcx, "__rust_alloc_error_handler_should_panic"), + val, + )?; if ecx.target_os_is_unix() { // "environ" is mandated by POSIX. diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 505c079143a..03c6081e992 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -12,6 +12,7 @@ use rustc_middle::mir::interpret::AllocInit; use rustc_middle::ty::Ty; use rustc_middle::{mir, ty}; use rustc_span::Symbol; +use rustc_symbol_mangling::mangle_internal_symbol; use rustc_target::callconv::{Conv, FnAbi}; use self::helpers::{ToHost, ToSoft}; @@ -51,7 +52,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Some shims forward to other MIR bodies. match link_name.as_str() { - "__rust_alloc_error_handler" => { + name if name == mangle_internal_symbol(*this.tcx, "__rust_alloc_error_handler") => { // Forward to the right symbol that implements this function. let Some(handler_kind) = this.tcx.alloc_error_handler_kind(()) else { // in real code, this symbol does not exist without an allocator @@ -59,9 +60,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "`__rust_alloc_error_handler` cannot be called when no alloc error handler is set" ); }; - let name = alloc_error_handler_name(handler_kind); + let name = + mangle_internal_symbol(*this.tcx, alloc_error_handler_name(handler_kind)); let handler = this - .lookup_exported_symbol(Symbol::intern(name))? + .lookup_exported_symbol(Symbol::intern(&name))? .expect("missing alloc error handler symbol"); return interp_ok(Some(handler)); } @@ -136,15 +138,29 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Find it if it was not cached. let mut instance_and_crate: Option<(ty::Instance<'_>, CrateNum)> = None; helpers::iter_exported_symbols(tcx, |cnum, def_id| { + if tcx.is_foreign_item(def_id) { + // Skip over imports of items + return interp_ok(()); + } + let attrs = tcx.codegen_fn_attrs(def_id); + // FIXME use tcx.symbol_name(instance) instead let symbol_name = if let Some(export_name) = attrs.export_name { export_name - } else if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { + } else if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) + || attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) + { tcx.item_name(def_id) } else { // Skip over items without an explicitly defined symbol name. return interp_ok(()); }; + let symbol_name = + if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) { + Symbol::intern(&mangle_internal_symbol(tcx, symbol_name.as_str())) + } else { + symbol_name + }; if symbol_name == link_name { if let Some((original_instance, original_cnum)) = instance_and_crate { // Make sure we are consistent wrt what is 'first' and 'second'. @@ -489,7 +505,9 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Rust allocation - "__rust_alloc" | "miri_alloc" => { + name if name == mangle_internal_symbol(*this.tcx, "__rust_alloc") + || name == "miri_alloc" => + { let default = |ecx: &mut MiriInterpCx<'tcx>| { // Only call `check_shim` when `#[global_allocator]` isn't used. When that // macro is used, we act like no shim exists, so that the exported function can run. @@ -500,9 +518,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { ecx.check_rustc_alloc_request(size, align)?; let memory_kind = match link_name.as_str() { - "__rust_alloc" => MiriMemoryKind::Rust, "miri_alloc" => MiriMemoryKind::Miri, - _ => unreachable!(), + _ => MiriMemoryKind::Rust, }; let ptr = ecx.allocate_ptr( @@ -516,15 +533,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { }; match link_name.as_str() { - "__rust_alloc" => return this.emulate_allocator(default), "miri_alloc" => { default(this)?; return interp_ok(EmulateItemResult::NeedsReturn); } - _ => unreachable!(), + _ => return this.emulate_allocator(default), } } - "__rust_alloc_zeroed" => { + name if name == mangle_internal_symbol(*this.tcx, "__rust_alloc_zeroed") => { return this.emulate_allocator(|this| { // See the comment for `__rust_alloc` why `check_shim` is only called in the // default case. @@ -543,7 +559,9 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(ptr, dest) }); } - "__rust_dealloc" | "miri_dealloc" => { + name if name == mangle_internal_symbol(*this.tcx, "__rust_dealloc") + || name == "miri_dealloc" => + { let default = |ecx: &mut MiriInterpCx<'tcx>| { // See the comment for `__rust_alloc` why `check_shim` is only called in the // default case. @@ -554,9 +572,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let align = ecx.read_target_usize(align)?; let memory_kind = match link_name.as_str() { - "__rust_dealloc" => MiriMemoryKind::Rust, "miri_dealloc" => MiriMemoryKind::Miri, - _ => unreachable!(), + _ => MiriMemoryKind::Rust, }; // No need to check old_size/align; we anyway check that they match the allocation. @@ -568,17 +585,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { }; match link_name.as_str() { - "__rust_dealloc" => { - return this.emulate_allocator(default); - } "miri_dealloc" => { default(this)?; return interp_ok(EmulateItemResult::NeedsReturn); } - _ => unreachable!(), + _ => return this.emulate_allocator(default), } } - "__rust_realloc" => { + name if name == mangle_internal_symbol(*this.tcx, "__rust_realloc") => { return this.emulate_allocator(|this| { // See the comment for `__rust_alloc` why `check_shim` is only called in the // default case. diff --git a/src/tools/miri/tests/fail/alloc/too_large.rs b/src/tools/miri/tests/fail/alloc/too_large.rs index 4e28d2401d7..c53318855ab 100644 --- a/src/tools/miri/tests/fail/alloc/too_large.rs +++ b/src/tools/miri/tests/fail/alloc/too_large.rs @@ -1,4 +1,7 @@ +#![feature(rustc_attrs)] + extern "Rust" { + #[rustc_std_internal_symbol] fn __rust_alloc(size: usize, align: usize) -> *mut u8; } diff --git a/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.rs b/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.rs index 08d84c461bf..34c6a6ce550 100644 --- a/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.rs +++ b/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.rs @@ -2,7 +2,10 @@ // because rustc does not support alignments that large. // https://github.com/rust-lang/miri/issues/3687 +#![feature(rustc_attrs)] + extern "Rust" { + #[rustc_std_internal_symbol] fn __rust_alloc(size: usize, align: usize) -> *mut u8; } diff --git a/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.rs b/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.rs index a4ab8094bf4..ce8861937f8 100644 --- a/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.rs +++ b/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.rs @@ -1,5 +1,9 @@ // Test non-power-of-two alignment. + +#![feature(rustc_attrs)] + extern "Rust" { + #[rustc_std_internal_symbol] fn __rust_alloc(size: usize, align: usize) -> *mut u8; } diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs index f174909e9d5..d0a28482054 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.rs @@ -3,6 +3,8 @@ // Avoid accidental synchronization via address reuse inside `thread::spawn`. //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0 +#![feature(rustc_attrs)] + use std::thread::spawn; #[derive(Copy, Clone)] @@ -12,6 +14,7 @@ unsafe impl<T> Send for EvilSend<T> {} unsafe impl<T> Sync for EvilSend<T> {} extern "Rust" { + #[rustc_std_internal_symbol] fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize); } diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs index 1edfbf5e61c..f56c44cabc2 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs @@ -3,6 +3,8 @@ // Avoid accidental synchronization via address reuse inside `thread::spawn`. //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0 +#![feature(rustc_attrs)] + use std::thread::spawn; #[derive(Copy, Clone)] @@ -12,6 +14,7 @@ unsafe impl<T> Send for EvilSend<T> {} unsafe impl<T> Sync for EvilSend<T> {} extern "Rust" { + #[rustc_std_internal_symbol] fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize); } diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs index 7605f1911db..a16ea25e11c 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.rs @@ -3,6 +3,8 @@ // Avoid accidental synchronization via address reuse inside `thread::spawn`. //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0 +#![feature(rustc_attrs)] + use std::thread::spawn; #[derive(Copy, Clone)] @@ -12,6 +14,7 @@ unsafe impl<T> Send for EvilSend<T> {} unsafe impl<T> Sync for EvilSend<T> {} extern "Rust" { + #[rustc_std_internal_symbol] fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize); } pub fn main() { diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs index 4f3819bd636..f3855e33c98 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs @@ -3,6 +3,8 @@ // Avoid accidental synchronization via address reuse inside `thread::spawn`. //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0 +#![feature(rustc_attrs)] + use std::thread::spawn; #[derive(Copy, Clone)] @@ -12,6 +14,7 @@ unsafe impl<T> Send for EvilSend<T> {} unsafe impl<T> Sync for EvilSend<T> {} extern "Rust" { + #[rustc_std_internal_symbol] fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize); } pub fn main() { diff --git a/src/tools/miri/tests/pass/function_calls/exported_symbol.rs b/src/tools/miri/tests/pass/function_calls/exported_symbol.rs index 27aee9c8835..d804f3642b1 100644 --- a/src/tools/miri/tests/pass/function_calls/exported_symbol.rs +++ b/src/tools/miri/tests/pass/function_calls/exported_symbol.rs @@ -40,6 +40,7 @@ fn main() { extern "Rust" { fn bar() -> i32; + #[rustc_std_internal_symbol] fn baz() -> i32; fn qux() -> i32; } @@ -63,6 +64,7 @@ fn main() { extern "C" { fn bar() -> i32; + #[rustc_std_internal_symbol] fn baz() -> i32; fn qux() -> i32; } diff --git a/src/tools/miri/tests/pass/shims/pipe.rs b/src/tools/miri/tests/pass/shims/pipe.rs index 1be29886d2d..c47feb8774a 100644 --- a/src/tools/miri/tests/pass/shims/pipe.rs +++ b/src/tools/miri/tests/pass/shims/pipe.rs @@ -1,7 +1,5 @@ //@ignore-target: windows -#![feature(anonymous_pipe)] - use std::io::{Read, Write, pipe}; fn main() { diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index 3111149f2ae..ac5d294f07e 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -369,9 +369,17 @@ fn main() -> anyhow::Result<()> { println!("Environment values\n{}", format_env_variables()); }); - with_log_group("Printing config.toml", || { - if let Ok(config) = std::fs::read_to_string("config.toml") { - println!("Contents of `config.toml`:\n{config}"); + with_log_group("Printing bootstrap.toml", || { + let config_file = if std::path::Path::new("bootstrap.toml").exists() { + "bootstrap.toml" + } else { + "config.toml" // Fall back for backward compatibility + }; + + if let Ok(config) = std::fs::read_to_string(config_file) { + println!("Contents of `bootstrap.toml`:\n{config}"); + } else { + eprintln!("Failed to read `{}`", config_file); } }); diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs index c8759bb6ff6..53ce772fa77 100644 --- a/src/tools/opt-dist/src/tests.rs +++ b/src/tools/opt-dist/src/tests.rs @@ -85,10 +85,10 @@ llvm-config = "{llvm_config}" cargo = cargo_path.to_string().replace('\\', "/"), llvm_config = llvm_config.to_string().replace('\\', "/") ); - log::info!("Using following `config.toml` for running tests:\n{config_content}"); + log::info!("Using following `bootstrap.toml` for running tests:\n{config_content}"); // Simulate a stage 0 compiler with the extracted optimized dist artifacts. - with_backed_up_file(Path::new("config.toml"), &config_content, || { + with_backed_up_file(Path::new("bootstrap.toml"), &config_content, || { let x_py = env.checkout_path().join("x.py"); let mut args = vec![ env.python_binary(), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs index 67fb73696f7..65fb342f752 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs @@ -145,19 +145,19 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> { let mut result = vec![]; if fps.is_empty() { debug!("Unrestricted search for {:?} impls...", trait_); - self.for_trait_impls(trait_, self_ty_fp, |impls| { + let _ = self.for_trait_impls(trait_, self_ty_fp, |impls| { result.extend(impls.for_trait(trait_).map(id_to_chalk)); ControlFlow::Continue(()) - }) + }); } else { - self.for_trait_impls(trait_, self_ty_fp, |impls| { + let _ = self.for_trait_impls(trait_, self_ty_fp, |impls| { result.extend( fps.iter().flat_map(move |fp| { impls.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk) }), ); ControlFlow::Continue(()) - }) + }); }; debug!("impls_for_trait returned {} impls", result.len()); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs index 6a01579bccc..e042c35d0c6 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs @@ -116,7 +116,7 @@ pub fn dyn_compatibility_of_trait_query( trait_: TraitId, ) -> Option<DynCompatibilityViolation> { let mut res = None; - dyn_compatibility_of_trait_with_callback(db, trait_, &mut |osv| { + let _ = dyn_compatibility_of_trait_with_callback(db, trait_, &mut |osv| { res = Some(osv); ControlFlow::Break(()) }); @@ -597,7 +597,7 @@ fn contains_illegal_impl_trait_in_trait( let ret = sig.skip_binders().ret(); let mut visitor = OpaqueTypeCollector(FxHashSet::default()); - ret.visit_with(visitor.as_dyn(), DebruijnIndex::INNERMOST); + let _ = ret.visit_with(visitor.as_dyn(), DebruijnIndex::INNERMOST); // Since we haven't implemented RPITIT in proper way like rustc yet, // just check whether `ret` contains RPIT for now diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs index 3060b610bb6..50851325bd5 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs @@ -53,7 +53,7 @@ fn check_dyn_compatibility<'a>( continue; }; let mut osvs = FxHashSet::default(); - dyn_compatibility_with_callback(&db, trait_id, &mut |osv| { + let _ = dyn_compatibility_with_callback(&db, trait_id, &mut |osv| { osvs.insert(match osv { DynCompatibilityViolation::SizedSelf => SizedSelf, DynCompatibilityViolation::SelfReferential => SelfReferential, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 556091c4046..3e0ce7f1933 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -1143,7 +1143,7 @@ impl<'a> InferenceContext<'a> { non_assocs: FxHashMap::default(), }; for ty in tait_candidates { - ty.visit_with(collector.as_dyn(), DebruijnIndex::INNERMOST); + let _ = ty.visit_with(collector.as_dyn(), DebruijnIndex::INNERMOST); } // Non-assoc TAITs can be define-used everywhere as long as they are diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 624767cedf8..cc02b71f05c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -1033,7 +1033,7 @@ where T: ?Sized + TypeVisitable<Interner>, { let mut collector = PlaceholderCollector { db, placeholders: FxHashSet::default() }; - value.visit_with(&mut collector, DebruijnIndex::INNERMOST); + let _ = value.visit_with(&mut collector, DebruijnIndex::INNERMOST); collector.placeholders.into_iter().collect() } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index db94351dcc9..c7228005271 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -596,7 +596,7 @@ pub(crate) fn iterate_method_candidates<T>( mut callback: impl FnMut(ReceiverAdjustments, AssocItemId, bool) -> Option<T>, ) -> Option<T> { let mut slot = None; - iterate_method_candidates_dyn( + let _ = iterate_method_candidates_dyn( ty, db, env, diff --git a/src/tools/rust-analyzer/crates/hir/src/attrs.rs b/src/tools/rust-analyzer/crates/hir/src/attrs.rs index 4351a34e822..4e45b5a250e 100644 --- a/src/tools/rust-analyzer/crates/hir/src/attrs.rs +++ b/src/tools/rust-analyzer/crates/hir/src/attrs.rs @@ -260,7 +260,7 @@ fn resolve_impl_trait_item( // attributes here. Use path resolution directly instead. // // FIXME: resolve type aliases (which are not yielded by iterate_path_candidates) - method_resolution::iterate_path_candidates( + let _ = method_resolution::iterate_path_candidates( &canonical, db, environment, diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index a8075509474..29f45846650 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -2911,7 +2911,7 @@ impl Trait { db: &dyn HirDatabase, ) -> Option<Vec<DynCompatibilityViolation>> { let mut violations = vec![]; - hir_ty::dyn_compatibility::dyn_compatibility_with_callback(db, self.id, &mut |violation| { + let _ = hir_ty::dyn_compatibility::dyn_compatibility_with_callback(db, self.id, &mut |violation| { violations.push(violation); ControlFlow::Continue(()) }); @@ -5497,7 +5497,7 @@ impl Type { .generic_def() .map_or_else(|| TraitEnvironment::empty(krate.id), |d| db.trait_environment(d)); - method_resolution::iterate_method_candidates_dyn( + let _ = method_resolution::iterate_method_candidates_dyn( &canonical, db, environment, @@ -5584,7 +5584,7 @@ impl Type { .generic_def() .map_or_else(|| TraitEnvironment::empty(krate.id), |d| db.trait_environment(d)); - method_resolution::iterate_path_candidates( + let _ = method_resolution::iterate_path_candidates( &canonical, db, environment, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs index 330587e0dbf..6f4b886a28d 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs @@ -750,7 +750,7 @@ impl FunctionBody { ast::Stmt::Item(_) => (), ast::Stmt::LetStmt(stmt) => { if let Some(pat) = stmt.pat() { - walk_pat(&pat, &mut |pat| { + let _ = walk_pat(&pat, &mut |pat| { cb(pat); std::ops::ControlFlow::<(), ()>::Continue(()) }); diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs index 0b2e8aa6836..56a66070ef7 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/node_ext.rs @@ -121,7 +121,7 @@ pub fn walk_patterns_in_expr(start: &ast::Expr, cb: &mut dyn FnMut(ast::Pat)) { match ast::Stmt::cast(node.clone()) { Some(ast::Stmt::LetStmt(l)) => { if let Some(pat) = l.pat() { - walk_pat(&pat, &mut |pat| { + let _ = walk_pat(&pat, &mut |pat| { cb(pat); ControlFlow::<(), ()>::Continue(()) }); @@ -159,7 +159,7 @@ pub fn walk_patterns_in_expr(start: &ast::Expr, cb: &mut dyn FnMut(ast::Pat)) { } } else if let Some(pat) = ast::Pat::cast(node) { preorder.skip_subtree(); - walk_pat(&pat, &mut |pat| { + let _ = walk_pat(&pat, &mut |pat| { cb(pat); ControlFlow::<(), ()>::Continue(()) }); diff --git a/src/tools/rustdoc-gui-test/src/main.rs b/src/tools/rustdoc-gui-test/src/main.rs index 5adb525d7e6..f1c6e13d3ae 100644 --- a/src/tools/rustdoc-gui-test/src/main.rs +++ b/src/tools/rustdoc-gui-test/src/main.rs @@ -20,7 +20,7 @@ fn get_browser_ui_test_version_inner(npm: &Path, global: bool) -> Option<String> Err(e) => { eprintln!( "path to npm can be wrong, provided path: {npm:?}. Try to set npm path \ - in config.toml in [build.npm]", + in bootstrap.toml in [build.npm]", ); panic!("{:?}", e) } diff --git a/tests/codegen/alloc-optimisation.rs b/tests/codegen/alloc-optimisation.rs index 8abeecf8550..19f14647c1d 100644 --- a/tests/codegen/alloc-optimisation.rs +++ b/tests/codegen/alloc-optimisation.rs @@ -5,7 +5,7 @@ pub fn alloc_test(data: u32) { // CHECK-LABEL: @alloc_test // CHECK-NEXT: start: - // CHECK-NEXT: {{.*}} load volatile i8, ptr @__rust_no_alloc_shim_is_unstable, align 1 + // CHECK-NEXT: {{.*}} load volatile i8, ptr @{{.*}}__rust_no_alloc_shim_is_unstable, align 1 // CHECK-NEXT: ret void let x = Box::new(data); drop(x); diff --git a/tests/codegen/asm/goto.rs b/tests/codegen/asm/goto.rs index 7a87bb7983b..f68c399c920 100644 --- a/tests/codegen/asm/goto.rs +++ b/tests/codegen/asm/goto.rs @@ -2,7 +2,7 @@ //@ only-x86_64 #![crate_type = "rlib"] -#![feature(asm_goto, asm_goto_with_outputs)] +#![feature(asm_goto_with_outputs)] use std::arch::asm; diff --git a/tests/codegen/box-uninit-bytes.rs b/tests/codegen/box-uninit-bytes.rs index 3b83ef3e250..0cc01148595 100644 --- a/tests/codegen/box-uninit-bytes.rs +++ b/tests/codegen/box-uninit-bytes.rs @@ -41,6 +41,6 @@ pub fn box_lotsa_padding() -> Box<LotsaPadding> { // Hide the `allocalign` attribute in the declaration of __rust_alloc // from the CHECK-NOT above, and also verify the attributes got set reasonably. -// CHECK: declare {{(dso_local )?}}noalias noundef ptr @__rust_alloc(i{{[0-9]+}} noundef, i{{[0-9]+}} allocalign noundef) unnamed_addr [[RUST_ALLOC_ATTRS:#[0-9]+]] +// CHECK: declare {{(dso_local )?}}noalias noundef ptr @{{.*}}__rust_alloc(i{{[0-9]+}} noundef, i{{[0-9]+}} allocalign noundef) unnamed_addr [[RUST_ALLOC_ATTRS:#[0-9]+]] // CHECK-DAG: attributes [[RUST_ALLOC_ATTRS]] = { {{.*}} allockind("alloc,uninitialized,aligned") allocsize(0) {{(uwtable )?}}"alloc-family"="__rust_alloc" {{.*}} } diff --git a/tests/codegen/dealloc-no-unwind.rs b/tests/codegen/dealloc-no-unwind.rs index c560d7a9932..68597817d6f 100644 --- a/tests/codegen/dealloc-no-unwind.rs +++ b/tests/codegen/dealloc-no-unwind.rs @@ -18,7 +18,7 @@ impl Drop for A { #[no_mangle] pub fn a(a: Box<i32>) { // CHECK-LABEL: define{{.*}}void @a - // CHECK: call void @__rust_dealloc + // CHECK: call void @{{.*}}__rust_dealloc // CHECK-NEXT: call void @foo let _a = A; drop(a); diff --git a/tests/codegen/issues/issue-129795.rs b/tests/codegen/issues/issue-129795.rs new file mode 100644 index 00000000000..dc64ee35c97 --- /dev/null +++ b/tests/codegen/issues/issue-129795.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -Copt-level=3 +//@ min-llvm-version: 20 +#![crate_type = "lib"] + +// Ensure that a modulo operation with an operand that is known to be +// a power-of-two is properly optimized. + +// CHECK-LABEL: @modulo_with_power_of_two_divisor +// CHECK: add i64 %divisor, -1 +// CHECK-NEXT: and i64 +// CHECK-NEXT: ret i64 +#[no_mangle] +pub fn modulo_with_power_of_two_divisor(dividend: u64, divisor: u64) -> u64 { + assert!(divisor.is_power_of_two()); + // should be optimized to (dividend & (divisor - 1)) + dividend % divisor +} diff --git a/tests/codegen/iter-repeat-n-trivial-drop.rs b/tests/codegen/iter-repeat-n-trivial-drop.rs index 4dab499a8a5..3bb942d11d5 100644 --- a/tests/codegen/iter-repeat-n-trivial-drop.rs +++ b/tests/codegen/iter-repeat-n-trivial-drop.rs @@ -47,7 +47,7 @@ pub fn iter_repeat_n_next(it: &mut std::iter::RepeatN<NotCopy>) -> Option<NotCop #[no_mangle] // CHECK-LABEL: @vec_extend_via_iter_repeat_n pub fn vec_extend_via_iter_repeat_n() -> Vec<u8> { - // CHECK: %[[ADDR:.+]] = tail call {{(noalias )?}}noundef dereferenceable_or_null(1234) ptr @__rust_alloc(i64 noundef {{(range\(i64 1, 0\) )?}}1234, i64 noundef {{(range\(i64 1, -9223372036854775807\) )?}}1) + // CHECK: %[[ADDR:.+]] = tail call {{(noalias )?}}noundef dereferenceable_or_null(1234) ptr @{{.*}}__rust_alloc(i64 noundef {{(range\(i64 1, 0\) )?}}1234, i64 noundef {{(range\(i64 1, -9223372036854775807\) )?}}1) // CHECK: tail call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(1234) %[[ADDR]], i8 42, i64 1234, let n = 1234_usize; diff --git a/tests/codegen/sanitizer/cfi/external_weak_symbols.rs b/tests/codegen/sanitizer/cfi/external_weak_symbols.rs new file mode 100644 index 00000000000..00e9b5029af --- /dev/null +++ b/tests/codegen/sanitizer/cfi/external_weak_symbols.rs @@ -0,0 +1,24 @@ +// Verifies that type metadata identifiers for for weakly-linked symbols are +// emitted correctly. +// +//@ needs-sanitizer-cfi +//@ compile-flags: -Clinker-plugin-lto -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static +#![crate_type = "bin"] +#![feature(linkage)] + +unsafe extern "C" { + #[linkage = "extern_weak"] + static FOO: Option<unsafe extern "C" fn(f64) -> ()>; +} +// CHECK: @_rust_extern_with_linkage_FOO = internal global ptr @FOO + +fn main() { + unsafe { + if let Some(method) = FOO { + method(4.2); + // CHECK: call i1 @llvm.type.test(ptr {{%method|%0}}, metadata !"_ZTSFvdE") + } + } +} + +// CHECK: declare !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} extern_weak void @FOO(double) unnamed_addr #{{[0-9]+}} diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs index 23a084c51f4..3a3453b22b4 100644 --- a/tests/codegen/try_question_mark_nop.rs +++ b/tests/codegen/try_question_mark_nop.rs @@ -63,6 +63,57 @@ pub fn result_nop_traits_32(x: Result<i32, u32>) -> Result<i32, u32> { try { x? } } +// CHECK-LABEL: @control_flow_nop_match_32 +#[no_mangle] +pub fn control_flow_nop_match_32(x: ControlFlow<i32, u32>) -> ControlFlow<i32, u32> { + // CHECK: start: + // CHECK-NEXT: insertvalue { i32, i32 } + // CHECK-NEXT: insertvalue { i32, i32 } + // CHECK-NEXT: ret { i32, i32 } + match x { + Continue(x) => Continue(x), + Break(x) => Break(x), + } +} + +// CHECK-LABEL: @control_flow_nop_traits_32 +#[no_mangle] +pub fn control_flow_nop_traits_32(x: ControlFlow<i32, u32>) -> ControlFlow<i32, u32> { + // CHECK: start: + // CHECK-NEXT: insertvalue { i32, i32 } + // CHECK-NEXT: insertvalue { i32, i32 } + // CHECK-NEXT: ret { i32, i32 } + try { x? } +} + +// CHECK-LABEL: @option_nop_match_64 +#[no_mangle] +pub fn option_nop_match_64(x: Option<u64>) -> Option<u64> { + // CHECK: start: + // TWENTY-NEXT: %[[TRUNC:[0-9]+]] = trunc nuw i64 %0 to i1 + // TWENTY-NEXT: %[[SEL:\.[0-9]+]] = select i1 %[[TRUNC]], i64 %1, i64 undef + // CHECK-NEXT: [[REG1:%[0-9a-zA-Z_.]+]] = insertvalue { i64, i64 } poison, i64 %0, 0 + // NINETEEN-NEXT: [[REG2:%[0-9a-zA-Z_.]+]] = insertvalue { i64, i64 } [[REG1]], i64 %1, 1 + // TWENTY-NEXT: [[REG2:%[0-9a-zA-Z_.]+]] = insertvalue { i64, i64 } [[REG1]], i64 %[[SEL]], 1 + // CHECK-NEXT: ret { i64, i64 } [[REG2]] + match x { + Some(x) => Some(x), + None => None, + } +} + +// CHECK-LABEL: @option_nop_traits_64 +#[no_mangle] +pub fn option_nop_traits_64(x: Option<u64>) -> Option<u64> { + // CHECK: start: + // TWENTY-NEXT: %[[TRUNC:[0-9]+]] = trunc nuw i64 %0 to i1 + // TWENTY-NEXT: %[[SEL:\.[0-9]+]] = select i1 %[[TRUNC]], i64 %1, i64 undef + // CHECK-NEXT: insertvalue { i64, i64 } + // CHECK-NEXT: insertvalue { i64, i64 } + // CHECK-NEXT: ret { i64, i64 } + try { x? } +} + // CHECK-LABEL: @result_nop_match_64 #[no_mangle] pub fn result_nop_match_64(x: Result<i64, u64>) -> Result<i64, u64> { @@ -86,48 +137,98 @@ pub fn result_nop_traits_64(x: Result<i64, u64>) -> Result<i64, u64> { try { x? } } -// CHECK-LABEL: @result_nop_match_ptr +// CHECK-LABEL: @control_flow_nop_match_64 #[no_mangle] -pub fn result_nop_match_ptr(x: Result<usize, Box<()>>) -> Result<usize, Box<()>> { +pub fn control_flow_nop_match_64(x: ControlFlow<i64, u64>) -> ControlFlow<i64, u64> { // CHECK: start: - // CHECK-NEXT: insertvalue { i{{[0-9]+}}, ptr } - // CHECK-NEXT: insertvalue { i{{[0-9]+}}, ptr } - // CHECK-NEXT: ret + // CHECK-NEXT: insertvalue { i64, i64 } + // CHECK-NEXT: insertvalue { i64, i64 } + // CHECK-NEXT: ret { i64, i64 } + match x { + Continue(x) => Continue(x), + Break(x) => Break(x), + } +} + +// CHECK-LABEL: @control_flow_nop_traits_64 +#[no_mangle] +pub fn control_flow_nop_traits_64(x: ControlFlow<i64, u64>) -> ControlFlow<i64, u64> { + // CHECK: start: + // CHECK-NEXT: insertvalue { i64, i64 } + // CHECK-NEXT: insertvalue { i64, i64 } + // CHECK-NEXT: ret { i64, i64 } + try { x? } +} + +// CHECK-LABEL: @result_nop_match_128 +#[no_mangle] +pub fn result_nop_match_128(x: Result<i128, u128>) -> Result<i128, u128> { + // CHECK: start: + // CHECK-NEXT: getelementptr inbounds {{(nuw )?}}i8 + // CHECK-NEXT: store i128 + // CHECK-NEXT: store i128 + // CHECK-NEXT: ret void match x { Ok(x) => Ok(x), Err(x) => Err(x), } } -// CHECK-LABEL: @result_nop_traits_ptr +// CHECK-LABEL: @result_nop_traits_128 #[no_mangle] -pub fn result_nop_traits_ptr(x: Result<u64, NonNull<()>>) -> Result<u64, NonNull<()>> { +pub fn result_nop_traits_128(x: Result<i128, u128>) -> Result<i128, u128> { // CHECK: start: - // CHECK-NEXT: insertvalue { i{{[0-9]+}}, ptr } - // CHECK-NEXT: insertvalue { i{{[0-9]+}}, ptr } - // CHECK-NEXT: ret + // CHECK-NEXT: getelementptr inbounds {{(nuw )?}}i8 + // CHECK-NEXT: store i128 + // CHECK-NEXT: store i128 + // CHECK-NEXT: ret void try { x? } } -// CHECK-LABEL: @control_flow_nop_match_32 +// CHECK-LABEL: @control_flow_nop_match_128 #[no_mangle] -pub fn control_flow_nop_match_32(x: ControlFlow<i32, u32>) -> ControlFlow<i32, u32> { +pub fn control_flow_nop_match_128(x: ControlFlow<i128, u128>) -> ControlFlow<i128, u128> { // CHECK: start: - // CHECK-NEXT: insertvalue { i32, i32 } - // CHECK-NEXT: insertvalue { i32, i32 } - // CHECK-NEXT: ret { i32, i32 } + // CHECK-NEXT: getelementptr inbounds {{(nuw )?}}i8 + // CHECK-NEXT: store i128 + // CHECK-NEXT: store i128 + // CHECK-NEXT: ret void match x { Continue(x) => Continue(x), Break(x) => Break(x), } } -// CHECK-LABEL: @control_flow_nop_traits_32 +// CHECK-LABEL: @control_flow_nop_traits_128 #[no_mangle] -pub fn control_flow_nop_traits_32(x: ControlFlow<i32, u32>) -> ControlFlow<i32, u32> { +pub fn control_flow_nop_traits_128(x: ControlFlow<i128, u128>) -> ControlFlow<i128, u128> { // CHECK: start: - // CHECK-NEXT: insertvalue { i32, i32 } - // CHECK-NEXT: insertvalue { i32, i32 } - // CHECK-NEXT: ret { i32, i32 } + // CHECK-NEXT: getelementptr inbounds {{(nuw )?}}i8 + // CHECK-NEXT: store i128 + // CHECK-NEXT: store i128 + // CHECK-NEXT: ret void + try { x? } +} + +// CHECK-LABEL: @result_nop_match_ptr +#[no_mangle] +pub fn result_nop_match_ptr(x: Result<usize, Box<()>>) -> Result<usize, Box<()>> { + // CHECK: start: + // CHECK-NEXT: insertvalue { i{{[0-9]+}}, ptr } + // CHECK-NEXT: insertvalue { i{{[0-9]+}}, ptr } + // CHECK-NEXT: ret + match x { + Ok(x) => Ok(x), + Err(x) => Err(x), + } +} + +// CHECK-LABEL: @result_nop_traits_ptr +#[no_mangle] +pub fn result_nop_traits_ptr(x: Result<u64, NonNull<()>>) -> Result<u64, NonNull<()>> { + // CHECK: start: + // CHECK-NEXT: insertvalue { i{{[0-9]+}}, ptr } + // CHECK-NEXT: insertvalue { i{{[0-9]+}}, ptr } + // CHECK-NEXT: ret try { x? } } diff --git a/tests/codegen/vec-calloc.rs b/tests/codegen/vec-calloc.rs index 2e2769ce130..d1c320ead01 100644 --- a/tests/codegen/vec-calloc.rs +++ b/tests/codegen/vec-calloc.rs @@ -177,6 +177,6 @@ pub fn vec_option_i32(n: usize) -> Vec<Option<i32>> { } // Ensure that __rust_alloc_zeroed gets the right attributes for LLVM to optimize it away. -// CHECK: declare noalias noundef ptr @__rust_alloc_zeroed(i64 noundef, i64 allocalign noundef) unnamed_addr [[RUST_ALLOC_ZEROED_ATTRS:#[0-9]+]] +// CHECK: declare noalias noundef ptr @{{.*}}__rust_alloc_zeroed(i64 noundef, i64 allocalign noundef) unnamed_addr [[RUST_ALLOC_ZEROED_ATTRS:#[0-9]+]] // CHECK-DAG: attributes [[RUST_ALLOC_ZEROED_ATTRS]] = { {{.*}} allockind("alloc,zeroed,aligned") allocsize(0) uwtable "alloc-family"="__rust_alloc" {{.*}} } diff --git a/tests/codegen/vec-optimizes-away.rs b/tests/codegen/vec-optimizes-away.rs index 39d5c1614c8..f6ed2898bda 100644 --- a/tests/codegen/vec-optimizes-away.rs +++ b/tests/codegen/vec-optimizes-away.rs @@ -5,7 +5,7 @@ pub fn sum_me() -> i32 { // CHECK-LABEL: @sum_me // CHECK-NEXT: {{^.*:$}} - // CHECK-NEXT: {{.*}} load volatile i8, ptr @__rust_no_alloc_shim_is_unstable, align 1 + // CHECK-NEXT: {{.*}} load volatile i8, ptr @{{.*}}__rust_no_alloc_shim_is_unstable, align 1 // CHECK-NEXT: ret i32 6 vec![1, 2, 3].iter().sum::<i32>() } diff --git a/tests/crashes/136286.rs b/tests/crashes/136286.rs deleted file mode 100644 index f0ea14bd167..00000000000 --- a/tests/crashes/136286.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ known-bug: #136286 -//@ compile-flags: --edition=2024 - -#![feature(async_fn_in_dyn_trait)] -trait A { - async fn b(self: A); -} diff --git a/tests/crashes/137706.rs b/tests/crashes/137706.rs deleted file mode 100644 index 0b46f9c237a..00000000000 --- a/tests/crashes/137706.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ known-bug: #137706 -//@ needs-rustc-debug-assertions -trait A { - fn b() -> impl IntoIterator<Item = ()>; -} - -impl A<()> for dyn A {} diff --git a/tests/crashes/137895.rs b/tests/crashes/137895.rs deleted file mode 100644 index bb624d2e9fa..00000000000 --- a/tests/crashes/137895.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: #137895 -trait A { - fn b() -> impl ?Sized + 'a; -} - -impl A for dyn A {} diff --git a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff index e9f48a85f9c..8e1cdb7182b 100644 --- a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff @@ -26,7 +26,6 @@ debug a => _9; } -+ coverage body span: $DIR/branch_match_arms.rs:14:11: 21:2 (#0) + coverage Code { bcb: bcb0 } => $DIR/branch_match_arms.rs:14:1: 15:21 (#0); + coverage Code { bcb: bcb1 } => $DIR/branch_match_arms.rs:16:17: 16:33 (#0); + coverage Code { bcb: bcb3 } => $DIR/branch_match_arms.rs:17:17: 17:33 (#0); diff --git a/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff index cbef6de917d..06e5f011c76 100644 --- a/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff @@ -4,8 +4,7 @@ fn bar() -> bool { let mut _0: bool; -+ coverage body span: $DIR/instrument_coverage.rs:29:18: 31:2 (#0) -+ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:29:1: 31:2 (#0); ++ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:27:1: 29:2 (#0); + bb0: { + Coverage::VirtualCounter(bcb0); diff --git a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff index b166d79a412..1a71cb8dea7 100644 --- a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff @@ -7,12 +7,11 @@ let mut _2: bool; let mut _3: !; -+ coverage body span: $DIR/instrument_coverage.rs:14:11: 20:2 (#0) -+ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:14:1: 14:11 (#0); -+ coverage Code { bcb: bcb1 } => $DIR/instrument_coverage.rs:16:12: 16:17 (#0); -+ coverage Code { bcb: bcb2 } => $DIR/instrument_coverage.rs:17:13: 17:18 (#0); -+ coverage Code { bcb: bcb3 } => $DIR/instrument_coverage.rs:18:10: 18:10 (#0); -+ coverage Code { bcb: bcb2 } => $DIR/instrument_coverage.rs:20:2: 20:2 (#0); ++ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:13:1: 13:11 (#0); ++ coverage Code { bcb: bcb1 } => $DIR/instrument_coverage.rs:15:12: 15:17 (#0); ++ coverage Code { bcb: bcb2 } => $DIR/instrument_coverage.rs:16:13: 16:18 (#0); ++ coverage Code { bcb: bcb3 } => $DIR/instrument_coverage.rs:17:10: 17:10 (#0); ++ coverage Code { bcb: bcb2 } => $DIR/instrument_coverage.rs:19:2: 19:2 (#0); + bb0: { + Coverage::VirtualCounter(bcb0); diff --git a/tests/mir-opt/coverage/instrument_coverage.rs b/tests/mir-opt/coverage/instrument_coverage.rs index 48647402d0f..d4ed4b67375 100644 --- a/tests/mir-opt/coverage/instrument_coverage.rs +++ b/tests/mir-opt/coverage/instrument_coverage.rs @@ -7,7 +7,6 @@ // EMIT_MIR instrument_coverage.main.InstrumentCoverage.diff // CHECK-LABEL: fn main() -// CHECK: coverage body span: // CHECK: coverage Code { bcb: bcb{{[0-9]+}} } => // CHECK: bb0: // CHECK: Coverage::VirtualCounter @@ -21,7 +20,6 @@ fn main() { // EMIT_MIR instrument_coverage.bar.InstrumentCoverage.diff // CHECK-LABEL: fn bar() -// CHECK: coverage body span: // CHECK: coverage Code { bcb: bcb{{[0-9]+}} } => // CHECK: bb0: // CHECK: Coverage::VirtualCounter diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff index 855f806aae1..1a22adeba6f 100644 --- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff +++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff @@ -7,7 +7,6 @@ coverage branch { true: BlockMarkerId(0), false: BlockMarkerId(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0) - coverage body span: $DIR/instrument_coverage_cleanup.rs:13:11: 15:2 (#0) coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 14:36 (#0); coverage Code { bcb: bcb3 } => $DIR/instrument_coverage_cleanup.rs:14:37: 14:39 (#0); coverage Code { bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:39: 14:39 (#0); diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff index df1f1e8bc50..b77969a3e16 100644 --- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff @@ -7,7 +7,6 @@ coverage branch { true: BlockMarkerId(0), false: BlockMarkerId(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0) -+ coverage body span: $DIR/instrument_coverage_cleanup.rs:13:11: 15:2 (#0) + coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 14:36 (#0); + coverage Code { bcb: bcb3 } => $DIR/instrument_coverage_cleanup.rs:14:37: 14:39 (#0); + coverage Code { bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:39: 14:39 (#0); diff --git a/tests/mir-opt/gvn_on_unsafe_binder.propagate.GVN.diff b/tests/mir-opt/gvn_on_unsafe_binder.propagate.GVN.diff new file mode 100644 index 00000000000..e28d04f1d58 --- /dev/null +++ b/tests/mir-opt/gvn_on_unsafe_binder.propagate.GVN.diff @@ -0,0 +1,35 @@ +- // MIR for `propagate` before GVN ++ // MIR for `propagate` after GVN + + fn propagate() -> unsafe<> i32 { + let mut _0: unsafe<> i32; + let _1: i32; + let mut _3: i32; + scope 1 { + debug x => _1; + let _2: unsafe<> i32; + scope 2 { + debug binder => _2; + } + } + + bb0: { +- StorageLive(_1); ++ nop; + _1 = const 1_i32; + StorageLive(_2); + StorageLive(_3); +- _3 = copy _1; +- _2 = wrap_binder!(move _3; unsafe<> i32); ++ _3 = const 1_i32; ++ _2 = const {transmute(0x00000001): unsafe<> i32}; + StorageDead(_3); +- _0 = move _2; ++ _0 = const {transmute(0x00000001): unsafe<> i32}; + StorageDead(_2); +- StorageDead(_1); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn_on_unsafe_binder.rs b/tests/mir-opt/gvn_on_unsafe_binder.rs new file mode 100644 index 00000000000..b3c0576f990 --- /dev/null +++ b/tests/mir-opt/gvn_on_unsafe_binder.rs @@ -0,0 +1,29 @@ +// skip-filecheck +//@ test-mir-pass: GVN + +// EMIT_MIR gvn_on_unsafe_binder.test.GVN.diff +// EMIT_MIR gvn_on_unsafe_binder.propagate.GVN.diff + +#![feature(unsafe_binders)] + +use std::unsafe_binder::wrap_binder; + +// Test for ICE <https://github.com/rust-lang/rust/issues/137846>. +fn test() { + unsafe { + let x = 1; + let binder: unsafe<'a> &'a i32 = wrap_binder!(&x); + } +} + +// Test that GVN propagates const values through unsafe binders. +// +// The lifetime `'a` is redundant (and doesn't print when we print out the type). +// However, we need it so that rustfmt doesn't rip out the `unsafe<>` part for now. +fn propagate() -> unsafe<'a> i32 { + unsafe { + let x = 1; + let binder: unsafe<'a> i32 = wrap_binder!(x); + binder + } +} diff --git a/tests/mir-opt/gvn_on_unsafe_binder.test.GVN.diff b/tests/mir-opt/gvn_on_unsafe_binder.test.GVN.diff new file mode 100644 index 00000000000..33814fb34f3 --- /dev/null +++ b/tests/mir-opt/gvn_on_unsafe_binder.test.GVN.diff @@ -0,0 +1,30 @@ +- // MIR for `test` before GVN ++ // MIR for `test` after GVN + + fn test() -> () { + let mut _0: (); + let _1: i32; + let mut _3: &i32; + scope 1 { + debug x => _1; + let _2: unsafe<'a> &'a i32; + scope 2 { + debug binder => _2; + } + } + + bb0: { + StorageLive(_1); + _1 = const 1_i32; + StorageLive(_2); + StorageLive(_3); + _3 = &_1; + _2 = wrap_binder!(move _3; unsafe<'a> &'a i32); + StorageDead(_3); + _0 = const (); + StorageDead(_2); + StorageDead(_1); + return; + } + } + diff --git a/tests/run-make/linker-warning/rmake.rs b/tests/run-make/linker-warning/rmake.rs index 73ad248b6f3..bc21739fefc 100644 --- a/tests/run-make/linker-warning/rmake.rs +++ b/tests/run-make/linker-warning/rmake.rs @@ -4,7 +4,7 @@ fn run_rustc() -> Rustc { let mut rustc = rustc(); rustc .arg("main.rs") - // NOTE: `link-self-contained` can vary depending on config.toml. + // NOTE: `link-self-contained` can vary depending on bootstrap.toml. // Make sure we use a consistent value. .arg("-Clink-self-contained=-linker") .arg("-Zunstable-options") diff --git a/tests/run-make/symbols-all-mangled/a_lib.rs b/tests/run-make/symbols-all-mangled/a_lib.rs new file mode 100644 index 00000000000..716dd3263c5 --- /dev/null +++ b/tests/run-make/symbols-all-mangled/a_lib.rs @@ -0,0 +1 @@ +pub fn public_rust_function() {} diff --git a/tests/run-make/symbols-all-mangled/an_executable.rs b/tests/run-make/symbols-all-mangled/an_executable.rs new file mode 100644 index 00000000000..db8df13b9a7 --- /dev/null +++ b/tests/run-make/symbols-all-mangled/an_executable.rs @@ -0,0 +1,3 @@ +pub fn public_rust_function_from_exe() {} + +fn main() {} diff --git a/tests/run-make/symbols-all-mangled/rmake.rs b/tests/run-make/symbols-all-mangled/rmake.rs new file mode 100644 index 00000000000..81f2678e55c --- /dev/null +++ b/tests/run-make/symbols-all-mangled/rmake.rs @@ -0,0 +1,84 @@ +// Check that all symbols in cdylibs, staticlibs and bins are mangled +//@ only-elf some object file formats create multiple symbols for each function with different names + +use run_make_support::object::read::{Object, ObjectSymbol}; +use run_make_support::{bin_name, dynamic_lib_name, object, rfs, rustc, static_lib_name}; + +fn main() { + let staticlib_name = static_lib_name("a_lib"); + let cdylib_name = dynamic_lib_name("a_lib"); + let exe_name = bin_name("an_executable"); + rustc().crate_type("cdylib").input("a_lib.rs").run(); + rustc().crate_type("staticlib").input("a_lib.rs").run(); + rustc().crate_type("bin").input("an_executable.rs").run(); + + symbols_check_archive(&staticlib_name); + symbols_check(&cdylib_name); + symbols_check(&exe_name); +} + +fn symbols_check_archive(path: &str) { + let binary_data = rfs::read(path); + let file = object::read::archive::ArchiveFile::parse(&*binary_data).unwrap(); + for symbol in file.symbols().unwrap().unwrap() { + let symbol = symbol.unwrap(); + let name = strip_underscore_if_apple(std::str::from_utf8(symbol.name()).unwrap()); + if name.starts_with("_ZN") || name.starts_with("_R") { + continue; // Correctly mangled + } + + let member_name = + std::str::from_utf8(file.member(symbol.offset()).unwrap().name()).unwrap(); + if !member_name.ends_with(".rcgu.o") || member_name.contains("compiler_builtins") { + continue; // All compiler-builtins symbols must remain unmangled + } + + if name == "__rust_no_alloc_shim_is_unstable" { + continue; // FIXME remove exception once we mangle this symbol + } + + if name.contains("rust_eh_personality") { + continue; // Unfortunately LLVM doesn't allow us to mangle this symbol + } + + panic!("Unmangled symbol found: {name}"); + } +} + +fn symbols_check(path: &str) { + let binary_data = rfs::read(path); + let file = object::File::parse(&*binary_data).unwrap(); + for symbol in file.symbols() { + if !symbol.is_definition() || !symbol.is_global() { + continue; + } + if symbol.is_weak() { + continue; // Likely an intrinsic from compiler-builtins + } + let name = strip_underscore_if_apple(symbol.name().unwrap()); + if name.starts_with("_ZN") || name.starts_with("_R") { + continue; // Correctly mangled + } + + if !name.contains("rust") { + // Assume that this symbol doesn't originate from rustc. This may + // be wrong, but even if so symbol_check_archive will likely + // catch it. + continue; + } + + if name == "__rust_no_alloc_shim_is_unstable" { + continue; // FIXME remove exception once we mangle this symbol + } + + if name.contains("rust_eh_personality") { + continue; // Unfortunately LLVM doesn't allow us to mangle this symbol + } + + panic!("Unmangled symbol found: {name}"); + } +} + +fn strip_underscore_if_apple(symbol: &str) -> &str { + if cfg!(target_vendor = "apple") { symbol.strip_prefix("_").unwrap() } else { symbol } +} diff --git a/tests/rustdoc-json/attrs/deprecated.rs b/tests/rustdoc-json/attrs/deprecated.rs new file mode 100644 index 00000000000..5cde7af841f --- /dev/null +++ b/tests/rustdoc-json/attrs/deprecated.rs @@ -0,0 +1,38 @@ +//@ is "$.index[*][?(@.name=='not')].attrs" [] +//@ is "$.index[*][?(@.name=='not')].deprecation" null +pub fn not() {} + +//@ is "$.index[*][?(@.name=='raw')].attrs" [] +//@ is "$.index[*][?(@.name=='raw')].deprecation" '{"since": null, "note": null}' +#[deprecated] +pub fn raw() {} + +//@ is "$.index[*][?(@.name=='equals_string')].attrs" [] +//@ is "$.index[*][?(@.name=='equals_string')].deprecation" '{"since": null, "note": "here is a reason"}' +#[deprecated = "here is a reason"] +pub fn equals_string() {} + +//@ is "$.index[*][?(@.name=='since')].attrs" [] +//@ is "$.index[*][?(@.name=='since')].deprecation" '{"since": "yoinks ago", "note": null}' +#[deprecated(since = "yoinks ago")] +pub fn since() {} + +//@ is "$.index[*][?(@.name=='note')].attrs" [] +//@ is "$.index[*][?(@.name=='note')].deprecation" '{"since": null, "note": "7"}' +#[deprecated(note = "7")] +pub fn note() {} + +//@ is "$.index[*][?(@.name=='since_and_note')].attrs" [] +//@ is "$.index[*][?(@.name=='since_and_note')].deprecation" '{"since": "tomorrow", "note": "sorry"}' +#[deprecated(since = "tomorrow", note = "sorry")] +pub fn since_and_note() {} + +//@ is "$.index[*][?(@.name=='note_and_since')].attrs" [] +//@ is "$.index[*][?(@.name=='note_and_since')].deprecation" '{"since": "a year from tomorrow", "note": "your welcome"}' +#[deprecated(note = "your welcome", since = "a year from tomorrow")] +pub fn note_and_since() {} + +//@ is "$.index[*][?(@.name=='neither_but_parens')].attrs" [] +//@ is "$.index[*][?(@.name=='neither_but_parens')].deprecation" '{"since": null, "note": null}' +#[deprecated()] +pub fn neither_but_parens() {} diff --git a/tests/rustdoc-json/attrs/repr_align.rs b/tests/rustdoc-json/attrs/repr_align.rs new file mode 100644 index 00000000000..bebbe1fea34 --- /dev/null +++ b/tests/rustdoc-json/attrs/repr_align.rs @@ -0,0 +1,8 @@ +#![no_std] + +//@ is "$.index[*][?(@.name=='Aligned')].attrs" '["#[attr = Repr([ReprAlign(Align(4 bytes))])]\n"]' +#[repr(align(4))] +pub struct Aligned { + a: i8, + b: i64, +} diff --git a/tests/rustdoc-json/attrs/repr_c.rs b/tests/rustdoc-json/attrs/repr_c.rs new file mode 100644 index 00000000000..609d33d94de --- /dev/null +++ b/tests/rustdoc-json/attrs/repr_c.rs @@ -0,0 +1,18 @@ +#![no_std] + +//@ is "$.index[*][?(@.name=='ReprCStruct')].attrs" '["#[attr = Repr([ReprC])]\n"]' +#[repr(C)] +pub struct ReprCStruct(pub i64); + +//@ is "$.index[*][?(@.name=='ReprCEnum')].attrs" '["#[attr = Repr([ReprC])]\n"]' +#[repr(C)] +pub enum ReprCEnum { + First, +} + +//@ is "$.index[*][?(@.name=='ReprCUnion')].attrs" '["#[attr = Repr([ReprC])]\n"]' +#[repr(C)] +pub union ReprCUnion { + pub left: i64, + pub right: u64, +} diff --git a/tests/rustdoc-json/attrs/repr_combination.rs b/tests/rustdoc-json/attrs/repr_combination.rs new file mode 100644 index 00000000000..662bfef67cb --- /dev/null +++ b/tests/rustdoc-json/attrs/repr_combination.rs @@ -0,0 +1,78 @@ +#![no_std] + +// Combinations of `#[repr(..)]` attributes. + +//@ is "$.index[*][?(@.name=='ReprCI8')].attrs" '["#[attr = Repr([ReprC, ReprInt(SignedInt(I8))])]\n"]' +#[repr(C, i8)] +pub enum ReprCI8 { + First, +} + +//@ is "$.index[*][?(@.name=='SeparateReprCI16')].attrs" '["#[attr = Repr([ReprC, ReprInt(SignedInt(I16))])]\n"]' +#[repr(C)] +#[repr(i16)] +pub enum SeparateReprCI16 { + First, +} + +//@ is "$.index[*][?(@.name=='ReversedReprCUsize')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(Usize)), ReprC])]\n"]' +#[repr(usize, C)] +pub enum ReversedReprCUsize { + First, +} + +//@ is "$.index[*][?(@.name=='ReprCPacked')].attrs" '["#[attr = Repr([ReprC, ReprPacked(Align(1 bytes))])]\n"]' +#[repr(C, packed)] +pub struct ReprCPacked { + a: i8, + b: i64, +} + +//@ is "$.index[*][?(@.name=='SeparateReprCPacked')].attrs" '["#[attr = Repr([ReprC, ReprPacked(Align(2 bytes))])]\n"]' +#[repr(C)] +#[repr(packed(2))] +pub struct SeparateReprCPacked { + a: i8, + b: i64, +} + +//@ is "$.index[*][?(@.name=='ReversedReprCPacked')].attrs" '["#[attr = Repr([ReprPacked(Align(2 bytes)), ReprC])]\n"]' +#[repr(packed(2), C)] +pub struct ReversedReprCPacked { + a: i8, + b: i64, +} + +//@ is "$.index[*][?(@.name=='ReprCAlign')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(16 bytes))])]\n"]' +#[repr(C, align(16))] +pub struct ReprCAlign { + a: i8, + b: i64, +} + +//@ is "$.index[*][?(@.name=='SeparateReprCAlign')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(2 bytes))])]\n"]' +#[repr(C)] +#[repr(align(2))] +pub struct SeparateReprCAlign { + a: i8, + b: i64, +} + +//@ is "$.index[*][?(@.name=='ReversedReprCAlign')].attrs" '["#[attr = Repr([ReprAlign(Align(2 bytes)), ReprC])]\n"]' +#[repr(align(2), C)] +pub struct ReversedReprCAlign { + a: i8, + b: i64, +} + +//@ is "$.index[*][?(@.name=='AlignedExplicitRepr')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(16 bytes)), ReprInt(SignedInt(Isize))])]\n"]' +#[repr(C, align(16), isize)] +pub enum AlignedExplicitRepr { + First, +} + +//@ is "$.index[*][?(@.name=='ReorderedAlignedExplicitRepr')].attrs" '["#[attr = Repr([ReprInt(SignedInt(Isize)), ReprC, ReprAlign(Align(16 bytes))])]\n"]' +#[repr(isize, C, align(16))] +pub enum ReorderedAlignedExplicitRepr { + First, +} diff --git a/tests/rustdoc-json/attrs/repr_int_enum.rs b/tests/rustdoc-json/attrs/repr_int_enum.rs new file mode 100644 index 00000000000..2ad57de2798 --- /dev/null +++ b/tests/rustdoc-json/attrs/repr_int_enum.rs @@ -0,0 +1,19 @@ +#![no_std] + +//@ is "$.index[*][?(@.name=='I8')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I8))])]\n"]' +#[repr(i8)] +pub enum I8 { + First, +} + +//@ is "$.index[*][?(@.name=='I32')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I32))])]\n"]' +#[repr(i32)] +pub enum I32 { + First, +} + +//@ is "$.index[*][?(@.name=='Usize')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(Usize))])]\n"]' +#[repr(usize)] +pub enum Usize { + First, +} diff --git a/tests/rustdoc-json/attrs/repr_packed.rs b/tests/rustdoc-json/attrs/repr_packed.rs new file mode 100644 index 00000000000..33acc23b7c8 --- /dev/null +++ b/tests/rustdoc-json/attrs/repr_packed.rs @@ -0,0 +1,18 @@ +#![no_std] + +// Note the normalization: +// `#[repr(packed)]` in has the implict "1" in rustdoc JSON. + +//@ is "$.index[*][?(@.name=='Packed')].attrs" '["#[attr = Repr([ReprPacked(Align(1 bytes))])]\n"]' +#[repr(packed)] +pub struct Packed { + a: i8, + b: i64, +} + +//@ is "$.index[*][?(@.name=='PackedAligned')].attrs" '["#[attr = Repr([ReprPacked(Align(4 bytes))])]\n"]' +#[repr(packed(4))] +pub struct PackedAligned { + a: i8, + b: i64, +} diff --git a/tests/rustdoc-json/attrs/repr_transparent.rs b/tests/rustdoc-json/attrs/repr_transparent.rs new file mode 100644 index 00000000000..ef6e69f8703 --- /dev/null +++ b/tests/rustdoc-json/attrs/repr_transparent.rs @@ -0,0 +1,22 @@ +#![no_std] + +// Rustdoc JSON currently includes `#[repr(transparent)]` +// even if the transparency is not part of the public API +// +// https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent + +//@ is "$.index[*][?(@.name=='Transparent')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]' +#[repr(transparent)] +pub struct Transparent(pub i64); + +//@ is "$.index[*][?(@.name=='TransparentNonPub')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]' +#[repr(transparent)] +pub struct TransparentNonPub(i64); + +//@ is "$.index[*][?(@.name=='AllZst')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]' +#[repr(transparent)] +pub struct AllZst<'a>(pub core::marker::PhantomData<&'a ()>, ()); + +//@ is "$.index[*][?(@.name=='AllZstNotPublic')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]' +#[repr(transparent)] +pub struct AllZstNotPublic<'a>(core::marker::PhantomData<&'a ()>, ()); diff --git a/tests/rustdoc-json/return-type-notation.rs b/tests/rustdoc-json/return-type-notation.rs new file mode 100644 index 00000000000..2219642bfc5 --- /dev/null +++ b/tests/rustdoc-json/return-type-notation.rs @@ -0,0 +1,18 @@ +//@ edition: 2021 +// ignore-tidy-linelength + +#![crate_type = "lib"] +#![feature(return_type_notation)] + +pub trait Foo { + async fn bar(); +} + +//@ is "$.index[*][?(@.name=='foo')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.args.angle_bracketed.constraints[0].args" '"return_type_notation"' +//@ ismany "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates[*].bound_predicate.type.qualified_path.args" '"return_type_notation"' '"return_type_notation"' +pub fn foo<T: Foo<bar(..): Send>>() +where + <T as Foo>::bar(..): 'static, + T::bar(..): Sync, +{ +} diff --git a/tests/rustdoc-ui/remap-path-prefix-macro.rs b/tests/rustdoc-ui/remap-path-prefix-macro.rs new file mode 100644 index 00000000000..1be22694b8c --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-macro.rs @@ -0,0 +1,9 @@ +// Regression test for "attempted to remap an already remapped filename" ICE in rustdoc +// when using --remap-path-prefix with macro rendering. +// <https://github.com/rust-lang/rust/issues/138520> + +//@ compile-flags:-Z unstable-options --remap-path-prefix={{src-base}}=remapped_path +//@ rustc-env:RUST_BACKTRACE=0 +//@ build-pass + +macro_rules! f(() => {}); diff --git a/tests/rustdoc/return-type-notation.rs b/tests/rustdoc/return-type-notation.rs new file mode 100644 index 00000000000..405e98eb28d --- /dev/null +++ b/tests/rustdoc/return-type-notation.rs @@ -0,0 +1,18 @@ +//@ edition: 2021 + +#![crate_type = "lib"] +#![feature(return_type_notation)] + +pub trait Foo { + async fn bar(); +} + +//@ has "return_type_notation/fn.foo.html" +//@ has - '//pre[@class="rust item-decl"]' "pub fn foo<T: Foo<bar(..): Send>>()" +//@ has - '//pre[@class="rust item-decl"]' "where <T as Foo>::bar(..): 'static, T::bar(..): Sync" +pub fn foo<T: Foo<bar(..): Send>>() +where + <T as Foo>::bar(..): 'static, + T::bar(..): Sync, +{ +} diff --git a/tests/ui/asm/x86_64/bad-options.rs b/tests/ui/asm/x86_64/bad-options.rs index 6424a1b1d42..123febc06fc 100644 --- a/tests/ui/asm/x86_64/bad-options.rs +++ b/tests/ui/asm/x86_64/bad-options.rs @@ -1,6 +1,6 @@ //@ only-x86_64 -#![feature(asm_unwind, asm_goto)] +#![feature(asm_unwind)] use std::arch::{asm, global_asm}; diff --git a/tests/ui/asm/x86_64/goto-block-safe.rs b/tests/ui/asm/x86_64/goto-block-safe.rs index ee833a48a4b..b739e9f9ced 100644 --- a/tests/ui/asm/x86_64/goto-block-safe.rs +++ b/tests/ui/asm/x86_64/goto-block-safe.rs @@ -2,7 +2,6 @@ //@ needs-asm-support #![deny(unreachable_code)] -#![feature(asm_goto)] use std::arch::asm; diff --git a/tests/ui/asm/x86_64/goto-block-safe.stderr b/tests/ui/asm/x86_64/goto-block-safe.stderr index 49818db7484..ee7313bc8be 100644 --- a/tests/ui/asm/x86_64/goto-block-safe.stderr +++ b/tests/ui/asm/x86_64/goto-block-safe.stderr @@ -1,5 +1,5 @@ error[E0133]: call to unsafe function `unreachable_unchecked` is unsafe and requires unsafe function or block - --> $DIR/goto-block-safe.rs:14:17 + --> $DIR/goto-block-safe.rs:13:17 | LL | unsafe { | ------ items do not inherit unsafety from separate enclosing items diff --git a/tests/ui/asm/x86_64/goto.rs b/tests/ui/asm/x86_64/goto.rs index 50e7441509a..00a8e588f96 100644 --- a/tests/ui/asm/x86_64/goto.rs +++ b/tests/ui/asm/x86_64/goto.rs @@ -3,7 +3,7 @@ //@ needs-asm-support #![deny(unreachable_code)] -#![feature(asm_goto, asm_goto_with_outputs)] +#![feature(asm_goto_with_outputs)] use std::arch::asm; diff --git a/tests/ui/async-await/async-closures/imm-deref-lending.rs b/tests/ui/async-await/async-closures/imm-deref-lending.rs new file mode 100644 index 00000000000..59f8d434d9c --- /dev/null +++ b/tests/ui/async-await/async-closures/imm-deref-lending.rs @@ -0,0 +1,46 @@ +//@ edition: 2021 +//@ check-pass + +#![feature(impl_trait_in_bindings)] + +struct FooS { + precise: i32, +} + +fn ref_inside_mut(f: &mut &FooS) { + let x: impl AsyncFn() = async move || { + let y = &f.precise; + }; +} + +fn mut_inside_ref(f: &&mut FooS) { + let x: impl AsyncFn() = async move || { + let y = &f.precise; + }; +} + +fn mut_ref_inside_mut(f: &mut &mut FooS) { + let x: impl AsyncFn() = async move || { + let y = &f.precise; + }; +} + +fn ref_inside_box(f: Box<&FooS>) { + let x: impl AsyncFn() = async move || { + let y = &f.precise; + }; +} + +fn box_inside_ref(f: &Box<FooS>) { + let x: impl AsyncFn() = async move || { + let y = &f.precise; + }; +} + +fn box_inside_box(f: Box<Box<FooS>>) { + let x: impl AsyncFn() = async move || { + let y = &f.precise; + }; +} + +fn main() {} diff --git a/tests/ui/async-await/async-closures/imm-deref-not-lending.rs b/tests/ui/async-await/async-closures/imm-deref-not-lending.rs new file mode 100644 index 00000000000..bd1197cc636 --- /dev/null +++ b/tests/ui/async-await/async-closures/imm-deref-not-lending.rs @@ -0,0 +1,49 @@ +//@ edition: 2021 + +#![feature(impl_trait_in_bindings)] + +struct FooS { + precise: i32, +} + +fn ref_inside_mut(f: &mut &FooS) { + let x: impl Fn() -> _ = async move || { + let y = &f.precise; + }; +} + +fn mut_inside_ref(f: &&mut FooS) { + let x: impl Fn() -> _ = async move || { + let y = &f.precise; + }; +} + +// Expected to fail, no immutable reference here. +fn mut_ref_inside_mut(f: &mut &mut FooS) { + let x: impl Fn() -> _ = async move || { + //~^ ERROR async closure does not implement `Fn` + let y = &f.precise; + }; +} + +fn ref_inside_box(f: Box<&FooS>) { + let x: impl Fn() -> _ = async move || { + let y = &f.precise; + }; +} + +fn box_inside_ref(f: &Box<FooS>) { + let x: impl Fn() -> _ = async move || { + let y = &f.precise; + }; +} + +// Expected to fail, no immutable reference here. +fn box_inside_box(f: Box<Box<FooS>>) { + let x: impl Fn() -> _ = async move || { + //~^ ERROR async closure does not implement `Fn` + let y = &f.precise; + }; +} + +fn main() {} diff --git a/tests/ui/async-await/async-closures/imm-deref-not-lending.stderr b/tests/ui/async-await/async-closures/imm-deref-not-lending.stderr new file mode 100644 index 00000000000..cd3ff55e458 --- /dev/null +++ b/tests/ui/async-await/async-closures/imm-deref-not-lending.stderr @@ -0,0 +1,14 @@ +error: async closure does not implement `Fn` because it captures state from its environment + --> $DIR/imm-deref-not-lending.rs:23:29 + | +LL | let x: impl Fn() -> _ = async move || { + | ^^^^^^^^^^^^^ + +error: async closure does not implement `Fn` because it captures state from its environment + --> $DIR/imm-deref-not-lending.rs:43:29 + | +LL | let x: impl Fn() -> _ = async move || { + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/async-await/dyn/mut-is-pointer-like.rs b/tests/ui/async-await/dyn/mut-is-pointer-like.rs index 93e8281164c..a82567e372e 100644 --- a/tests/ui/async-await/dyn/mut-is-pointer-like.rs +++ b/tests/ui/async-await/dyn/mut-is-pointer-like.rs @@ -1,11 +1,9 @@ //@ aux-build:block-on.rs //@ edition: 2021 -//@ run-pass -//@ check-run-results +//@ known-bug: #133119 #![allow(refining_impl_trait)] #![feature(async_fn_in_dyn_trait)] -//~^ WARN the feature `async_fn_in_dyn_trait` is incomplete extern crate block_on; diff --git a/tests/ui/async-await/dyn/mut-is-pointer-like.stderr b/tests/ui/async-await/dyn/mut-is-pointer-like.stderr index 7c72ce43cf0..bf20473924b 100644 --- a/tests/ui/async-await/dyn/mut-is-pointer-like.stderr +++ b/tests/ui/async-await/dyn/mut-is-pointer-like.stderr @@ -1,5 +1,5 @@ warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/mut-is-pointer-like.rs:7:12 + --> $DIR/mut-is-pointer-like.rs:6:12 | LL | #![feature(async_fn_in_dyn_trait)] | ^^^^^^^^^^^^^^^^^^^^^ @@ -7,5 +7,65 @@ LL | #![feature(async_fn_in_dyn_trait)] = note: see issue #133119 <https://github.com/rust-lang/rust/issues/133119> for more information = note: `#[warn(incomplete_features)]` on by default -warning: 1 warning emitted +error[E0038]: the trait `AsyncTrait` is not dyn compatible + --> $DIR/mut-is-pointer-like.rs:35:16 + | +LL | let x: Pin<&mut dyn AsyncTrait<Output = ()>> = f; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> + --> $DIR/mut-is-pointer-like.rs:16:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +... +LL | async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output; + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + +error[E0038]: the trait `AsyncTrait` is not dyn compatible + --> $DIR/mut-is-pointer-like.rs:35:56 + | +LL | let x: Pin<&mut dyn AsyncTrait<Output = ()>> = f; + | ^ `AsyncTrait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> + --> $DIR/mut-is-pointer-like.rs:16:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +... +LL | async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output; + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + = note: required for the cast from `Pin<&mut {async block@$DIR/mut-is-pointer-like.rs:32:32: 32:37}>` to `Pin<&mut dyn AsyncTrait<Output = ()>>` + +error[E0277]: the trait bound `dyn AsyncTrait<Output = ()>: AsyncTrait` is not satisfied + --> $DIR/mut-is-pointer-like.rs:36:11 + | +LL | x.async_dispatch().await; + | ^^^^^^^^^^^^^^ the trait `AsyncTrait` is not implemented for `dyn AsyncTrait<Output = ()>` + +error[E0038]: the trait `AsyncTrait` is not dyn compatible + --> $DIR/mut-is-pointer-like.rs:36:9 + | +LL | x.async_dispatch().await; + | ^^^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> + --> $DIR/mut-is-pointer-like.rs:16:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +... +LL | async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output; + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + +error: aborting due to 4 previous errors; 1 warning emitted +Some errors have detailed explanations: E0038, E0277. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/async-await/dyn/works.rs b/tests/ui/async-await/dyn/works.rs index 0732a3ee2f2..f406a7b593f 100644 --- a/tests/ui/async-await/dyn/works.rs +++ b/tests/ui/async-await/dyn/works.rs @@ -1,11 +1,9 @@ //@ aux-build:block-on.rs //@ edition: 2021 -//@ run-pass -//@ check-run-results +//@ known-bug: #133119 #![allow(refining_impl_trait)] #![feature(async_fn_in_dyn_trait)] -//~^ WARN the feature `async_fn_in_dyn_trait` is incomplete extern crate block_on; diff --git a/tests/ui/async-await/dyn/works.stderr b/tests/ui/async-await/dyn/works.stderr index 2c7db7c32f5..47abeab5aac 100644 --- a/tests/ui/async-await/dyn/works.stderr +++ b/tests/ui/async-await/dyn/works.stderr @@ -1,5 +1,5 @@ warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/works.rs:7:12 + --> $DIR/works.rs:6:12 | LL | #![feature(async_fn_in_dyn_trait)] | ^^^^^^^^^^^^^^^^^^^^^ @@ -7,5 +7,75 @@ LL | #![feature(async_fn_in_dyn_trait)] = note: see issue #133119 <https://github.com/rust-lang/rust/issues/133119> for more information = note: `#[warn(incomplete_features)]` on by default -warning: 1 warning emitted +error[E0038]: the trait `AsyncTrait` is not dyn compatible + --> $DIR/works.rs:27:34 + | +LL | let x: &dyn AsyncTrait = &"hello, world!"; + | ^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> + --> $DIR/works.rs:14:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +LL | async fn async_dispatch(&self); + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + = help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead. + = note: required for the cast from `&&'static str` to `&dyn AsyncTrait` + +error[E0038]: the trait `AsyncTrait` is not dyn compatible + --> $DIR/works.rs:27:16 + | +LL | let x: &dyn AsyncTrait = &"hello, world!"; + | ^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> + --> $DIR/works.rs:14:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +LL | async fn async_dispatch(&self); + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + = help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead. + +error[E0038]: the trait `AsyncTrait` is not dyn compatible + --> $DIR/works.rs:28:11 + | +LL | x.async_dispatch().await; + | ^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> + --> $DIR/works.rs:14:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +LL | async fn async_dispatch(&self); + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + = help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead. + +error[E0038]: the trait `AsyncTrait` is not dyn compatible + --> $DIR/works.rs:28:9 + | +LL | x.async_dispatch().await; + | ^^^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> + --> $DIR/works.rs:14:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +LL | async fn async_dispatch(&self); + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + = help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead. + +error: aborting due to 4 previous errors; 1 warning emitted +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/async-await/dyn/wrong-size.rs b/tests/ui/async-await/dyn/wrong-size.rs index ac15dd26067..f5fce3648ac 100644 --- a/tests/ui/async-await/dyn/wrong-size.rs +++ b/tests/ui/async-await/dyn/wrong-size.rs @@ -1,7 +1,7 @@ //@ edition: 2021 +//@ known-bug: #133119 #![feature(async_fn_in_dyn_trait)] -//~^ WARN the feature `async_fn_in_dyn_trait` is incomplete use std::future::Future; @@ -19,5 +19,5 @@ impl AsyncTrait for &'static str { fn main() { let x: &dyn AsyncTrait = &"hello, world!"; - //~^ ERROR `impl Future<Output = ()>` needs to have the same ABI as a pointer + // FIXME ~^ ERROR `impl Future<Output = ()>` needs to have the same ABI as a pointer } diff --git a/tests/ui/async-await/dyn/wrong-size.stderr b/tests/ui/async-await/dyn/wrong-size.stderr index 0202b5f2409..b4684f4fc17 100644 --- a/tests/ui/async-await/dyn/wrong-size.stderr +++ b/tests/ui/async-await/dyn/wrong-size.stderr @@ -1,5 +1,5 @@ warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/wrong-size.rs:3:12 + --> $DIR/wrong-size.rs:4:12 | LL | #![feature(async_fn_in_dyn_trait)] | ^^^^^^^^^^^^^^^^^^^^^ @@ -7,15 +7,41 @@ LL | #![feature(async_fn_in_dyn_trait)] = note: see issue #133119 <https://github.com/rust-lang/rust/issues/133119> for more information = note: `#[warn(incomplete_features)]` on by default -error[E0277]: `impl Future<Output = ()>` needs to have the same ABI as a pointer +error[E0038]: the trait `AsyncTrait` is not dyn compatible --> $DIR/wrong-size.rs:21:30 | LL | let x: &dyn AsyncTrait = &"hello, world!"; - | ^^^^^^^^^^^^^^^^ `impl Future<Output = ()>` needs to be a pointer-like type + | ^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible | - = help: the trait `for<'a> PointerLike` is not implemented for `impl Future<Output = ()>` +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> + --> $DIR/wrong-size.rs:9:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +LL | async fn async_dispatch(&self); + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + = help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead. = note: required for the cast from `&&'static str` to `&dyn AsyncTrait` -error: aborting due to 1 previous error; 1 warning emitted +error[E0038]: the trait `AsyncTrait` is not dyn compatible + --> $DIR/wrong-size.rs:21:12 + | +LL | let x: &dyn AsyncTrait = &"hello, world!"; + | ^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> + --> $DIR/wrong-size.rs:9:14 + | +LL | trait AsyncTrait { + | ---------- this trait is not dyn compatible... +LL | async fn async_dispatch(&self); + | ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async` + = help: consider moving `async_dispatch` to another trait + = help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead. + +error: aborting due to 2 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/attributes/outer-mod-attr-applies-only-to-first.rs b/tests/ui/attributes/outer-mod-attr-applies-only-to-first.rs new file mode 100644 index 00000000000..ec521c1afb5 --- /dev/null +++ b/tests/ui/attributes/outer-mod-attr-applies-only-to-first.rs @@ -0,0 +1,16 @@ +//! Regression test to check that outer attributes applied to the first module item is applied to +//! its attached module item only, and not also to other subsequent module items +//! +//! Commit: <https://github.com/rust-lang/rust/commit/7aee9f7b56f8d96f9444ebb1d06e32e024b81974> + +//@ check-pass +//@ compile-flags: --cfg=first +//@ no-auto-check-cfg + +#[cfg(first)] +mod hello {} + +#[cfg(not_set)] +mod hello {} + +fn main() {} diff --git a/tests/ui/cast/cast_lit_suffix-issue-138392.fixed b/tests/ui/cast/cast_lit_suffix-issue-138392.fixed new file mode 100644 index 00000000000..c6fbd09f89c --- /dev/null +++ b/tests/ui/cast/cast_lit_suffix-issue-138392.fixed @@ -0,0 +1,6 @@ +//@ run-rustfix +#![allow(unused_parens)] +fn main() { + let _x: u8 = (4u8); //~ ERROR: mismatched types + let _y: u8 = (4u8); //~ ERROR: mismatched types +} diff --git a/tests/ui/cast/cast_lit_suffix-issue-138392.rs b/tests/ui/cast/cast_lit_suffix-issue-138392.rs new file mode 100644 index 00000000000..86dbbbbf126 --- /dev/null +++ b/tests/ui/cast/cast_lit_suffix-issue-138392.rs @@ -0,0 +1,6 @@ +//@ run-rustfix +#![allow(unused_parens)] +fn main() { + let _x: u8 = (4i32); //~ ERROR: mismatched types + let _y: u8 = (4.0f32); //~ ERROR: mismatched types +} diff --git a/tests/ui/cast/cast_lit_suffix-issue-138392.stderr b/tests/ui/cast/cast_lit_suffix-issue-138392.stderr new file mode 100644 index 00000000000..998fcfc36dc --- /dev/null +++ b/tests/ui/cast/cast_lit_suffix-issue-138392.stderr @@ -0,0 +1,31 @@ +error[E0308]: mismatched types + --> $DIR/cast_lit_suffix-issue-138392.rs:4:18 + | +LL | let _x: u8 = (4i32); + | -- ^^^^^^ expected `u8`, found `i32` + | | + | expected due to this + | +help: change the type of the numeric literal from `i32` to `u8` + | +LL - let _x: u8 = (4i32); +LL + let _x: u8 = (4u8); + | + +error[E0308]: mismatched types + --> $DIR/cast_lit_suffix-issue-138392.rs:5:18 + | +LL | let _y: u8 = (4.0f32); + | -- ^^^^^^^^ expected `u8`, found `f32` + | | + | expected due to this + | +help: change the type of the numeric literal from `f32` to `u8` + | +LL - let _y: u8 = (4.0f32); +LL + let _y: u8 = (4u8); + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/dupe-first-attr.rs b/tests/ui/dupe-first-attr.rs deleted file mode 100644 index c254df050c1..00000000000 --- a/tests/ui/dupe-first-attr.rs +++ /dev/null @@ -1,25 +0,0 @@ -//@ run-pass - -// Regression test for a problem with the first mod attribute -// being applied to every mod - - -#[cfg(target_os = "linux")] -mod hello {} - -#[cfg(target_os = "macos")] -mod hello {} - -#[cfg(target_os = "windows")] -mod hello {} - -#[cfg(target_os = "freebsd")] -mod hello {} - -#[cfg(target_os = "dragonfly")] -mod hello {} - -#[cfg(target_os = "android")] -mod hello {} - -fn main() {} diff --git a/tests/ui/duplicate_entry_error.rs b/tests/ui/duplicate_entry_error.rs deleted file mode 100644 index 5a25802c6e7..00000000000 --- a/tests/ui/duplicate_entry_error.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ normalize-stderr: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" -// note-pattern: first defined in crate `std`. - -// Test for issue #31788 and E0152 - -#![feature(lang_items)] - -extern crate core; - -use core::panic::PanicInfo; - -#[lang = "panic_impl"] -fn panic_impl(info: &PanicInfo) -> ! { -//~^ ERROR: found duplicate lang item `panic_impl` - loop {} -} - -fn main() {} diff --git a/tests/ui/error-codes/E0152-duplicate-lang-items.rs b/tests/ui/error-codes/E0152-duplicate-lang-items.rs new file mode 100644 index 00000000000..089810b1ad2 --- /dev/null +++ b/tests/ui/error-codes/E0152-duplicate-lang-items.rs @@ -0,0 +1,20 @@ +//! Validates the correct printing of E0152 in the case of duplicate "lang_item" function +//! definitions. +//! +//! Issue: <https://github.com/rust-lang/rust/issues/31788> + +//@ error-pattern: first defined in crate `std` +//@ normalize-stderr: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" +#![feature(lang_items)] + +extern crate core; + +use core::panic::PanicInfo; + +#[lang = "panic_impl"] +fn panic_impl(info: &PanicInfo) -> ! { + //~^ ERROR: found duplicate lang item `panic_impl` + loop {} +} + +fn main() {} diff --git a/tests/ui/duplicate_entry_error.stderr b/tests/ui/error-codes/E0152-duplicate-lang-items.stderr index 958e9c7527d..3c3d64322f3 100644 --- a/tests/ui/duplicate_entry_error.stderr +++ b/tests/ui/error-codes/E0152-duplicate-lang-items.stderr @@ -1,5 +1,5 @@ error[E0152]: found duplicate lang item `panic_impl` - --> $DIR/duplicate_entry_error.rs:13:1 + --> $DIR/E0152-duplicate-lang-items.rs:15:1 | LL | / fn panic_impl(info: &PanicInfo) -> ! { LL | | @@ -7,9 +7,9 @@ LL | | loop {} LL | | } | |_^ | - = note: the lang item is first defined in crate `std` (which `duplicate_entry_error` depends on) + = note: the lang item is first defined in crate `std` (which `E0152_duplicate_lang_items` depends on) = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib - = note: second definition in the local crate (`duplicate_entry_error`) + = note: second definition in the local crate (`E0152_duplicate_lang_items`) error: aborting due to 1 previous error diff --git a/tests/ui/duplicate-label-E0381-issue-129274.rs b/tests/ui/error-codes/E0381-duplicated-label.rs index b2156e630c8..84a85caa65d 100644 --- a/tests/ui/duplicate-label-E0381-issue-129274.rs +++ b/tests/ui/error-codes/E0381-duplicated-label.rs @@ -1,3 +1,6 @@ +//! Regression test for duplicated label in E0381 error message. +//! +//! Issue: <https://github.com/rust-lang/rust/issues/129274> fn main() { fn test() { loop { diff --git a/tests/ui/duplicate-label-E0381-issue-129274.stderr b/tests/ui/error-codes/E0381-duplicated-label.stderr index 7f8bddb17c5..36e6d966f09 100644 --- a/tests/ui/duplicate-label-E0381-issue-129274.stderr +++ b/tests/ui/error-codes/E0381-duplicated-label.stderr @@ -1,5 +1,5 @@ error[E0381]: used binding `blah` is possibly-uninitialized - --> $DIR/duplicate-label-E0381-issue-129274.rs:8:33 + --> $DIR/E0381-duplicated-label.rs:11:33 | LL | let blah: Option<String>; | ---- binding declared here but left uninitialized diff --git a/tests/ui/feature-gates/feature-gate-asm_goto.rs b/tests/ui/feature-gates/feature-gate-asm_goto.rs deleted file mode 100644 index beac4590349..00000000000 --- a/tests/ui/feature-gates/feature-gate-asm_goto.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ only-x86_64 - -use std::arch::asm; - -fn main() { - unsafe { - asm!("jmp {}", label {}); - //~^ ERROR label operands for inline assembly are unstable - } -} diff --git a/tests/ui/feature-gates/feature-gate-asm_goto.stderr b/tests/ui/feature-gates/feature-gate-asm_goto.stderr deleted file mode 100644 index 62fd1a320d3..00000000000 --- a/tests/ui/feature-gates/feature-gate-asm_goto.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0658]: label operands for inline assembly are unstable - --> $DIR/feature-gate-asm_goto.rs:7:24 - | -LL | asm!("jmp {}", label {}); - | ^^^^^^^^ - | - = note: see issue #119364 <https://github.com/rust-lang/rust/issues/119364> for more information - = help: add `#![feature(asm_goto)]` 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 1 previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.rs b/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.rs index 294827f78d2..26b7d5d2fbf 100644 --- a/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.rs +++ b/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.rs @@ -1,7 +1,5 @@ //@ only-x86_64 -#![feature(asm_goto)] - use std::arch::asm; fn main() { diff --git a/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.stderr b/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.stderr index ff7a7d5760a..06e11301565 100644 --- a/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.stderr +++ b/tests/ui/feature-gates/feature-gate-asm_goto_with_outputs.stderr @@ -1,5 +1,5 @@ error[E0658]: using both label and output operands for inline assembly is unstable - --> $DIR/feature-gate-asm_goto_with_outputs.rs:10:52 + --> $DIR/feature-gate-asm_goto_with_outputs.rs:8:52 | LL | asm!("mov {}, 1", "jmp {}", out(reg) _out, label {}); | ^^^^^^^^ diff --git a/tests/ui/feature-gates/feature-gate-print-check-cfg.rs b/tests/ui/feature-gates/feature-gate-print-check-cfg.rs deleted file mode 100644 index 304e0c132e5..00000000000 --- a/tests/ui/feature-gates/feature-gate-print-check-cfg.rs +++ /dev/null @@ -1,3 +0,0 @@ -//@ compile-flags: --print=check-cfg - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-print-check-cfg.stderr b/tests/ui/feature-gates/feature-gate-print-check-cfg.stderr deleted file mode 100644 index 62ee44b94a4..00000000000 --- a/tests/ui/feature-gates/feature-gate-print-check-cfg.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: the `-Z unstable-options` flag must also be passed to enable the check-cfg print option - diff --git a/tests/ui/loops/label-on-block-suggest-move.rs b/tests/ui/loops/label-on-block-suggest-move.rs new file mode 100644 index 00000000000..656034cd0e9 --- /dev/null +++ b/tests/ui/loops/label-on-block-suggest-move.rs @@ -0,0 +1,90 @@ +// see https://github.com/rust-lang/rust/issues/138585 +#![allow(break_with_label_and_loop)] // doesn't work locally + +fn main() { + loop 'a: {} + //~^ ERROR: block label not supported here + //~| HELP: if you meant to label the loop, move this label before the loop + while false 'a: {} + //~^ ERROR: block label not supported here + //~| HELP: if you meant to label the loop, move this label before the loop + for i in [0] 'a: {} + //~^ ERROR: block label not supported here + //~| HELP: if you meant to label the loop, move this label before the loop + 'a: loop { + // first block is parsed as the break expr's value with or without parens + while break 'a 'b: {} 'c: {} + //~^ ERROR: block label not supported here + //~| HELP: if you meant to label the loop, move this label before the loop + while break 'a ('b: {}) 'c: {} + //~^ ERROR: block label not supported here + //~| HELP: if you meant to label the loop, move this label before the loop + + // without the parens, the first block is parsed as the while-loop's body + // (see the 'no errors' section) + // #[allow(break_with_label_and_loop)] (doesn't work locally) + while (break 'a {}) 'c: {} + //~^ ERROR: block label not supported here + //~| HELP: if you meant to label the loop, move this label before the loop + } + + // do not suggest moving the label if there is already a label on the loop + 'a: loop 'b: {} + //~^ ERROR: block label not supported here + //~| HELP: remove this block label + 'a: while false 'b: {} + //~^ ERROR: block label not supported here + //~| HELP: remove this block label + 'a: for i in [0] 'b: {} + //~^ ERROR: block label not supported here + //~| HELP: remove this block label + 'a: loop { + // first block is parsed as the break expr's value with or without parens + 'd: while break 'a 'b: {} 'c: {} + //~^ ERROR: block label not supported here + //~| HELP: remove this block label + 'd: while break 'a ('b: {}) 'c: {} + //~^ ERROR: block label not supported here + //~| HELP: remove this block label + + // without the parens, the first block is parsed as the while-loop's body + // (see the 'no errors' section) + // #[allow(break_with_label_and_loop)] (doesn't work locally) + 'd: while (break 'a {}) 'c: {} + //~^ ERROR: block label not supported here + //~| HELP: remove this block label + } + + // no errors + loop { 'a: {} } + 'a: loop { 'b: {} } + while false { 'a: {} } + 'a: while false { 'b: {} } + for i in [0] { 'a: {} } + 'a: for i in [0] { 'b: {} } + 'a: {} + 'a: { 'b: {} } + 'a: loop { + // first block is parsed as the break expr's value if it is a labeled block + while break 'a 'b: {} {} + 'd: while break 'a 'b: {} {} + while break 'a ('b: {}) {} + 'd: while break 'a ('b: {}) {} + // first block is parsed as the while-loop's body if it has no label + // (the break expr is parsed as having no value), + // so the second block is a normal stmt-block, and the label is allowed + while break 'a {} 'c: {} + while break 'a {} {} + 'd: while break 'a {} 'c: {} + 'd: while break 'a {} {} + } + + // unrelated errors that should not be affected + 'a: 'b: {} + //~^ ERROR: expected `while`, `for`, `loop` or `{` after a label + //~| HELP: consider removing the label + loop { while break 'b: {} {} } + //~^ ERROR: parentheses are required around this expression to avoid confusion with a labeled break expression + //~| HELP: wrap the expression in parentheses + //~| ERROR: `break` or `continue` with no label in the condition of a `while` loop [E0590] +} diff --git a/tests/ui/loops/label-on-block-suggest-move.stderr b/tests/ui/loops/label-on-block-suggest-move.stderr new file mode 100644 index 00000000000..66866703ca6 --- /dev/null +++ b/tests/ui/loops/label-on-block-suggest-move.stderr @@ -0,0 +1,140 @@ +error: block label not supported here + --> $DIR/label-on-block-suggest-move.rs:5:10 + | +LL | loop 'a: {} + | ^^^ not supported here + | +help: if you meant to label the loop, move this label before the loop + | +LL - loop 'a: {} +LL + 'a: loop {} + | + +error: block label not supported here + --> $DIR/label-on-block-suggest-move.rs:8:17 + | +LL | while false 'a: {} + | ^^^ not supported here + | +help: if you meant to label the loop, move this label before the loop + | +LL - while false 'a: {} +LL + 'a: while false {} + | + +error: block label not supported here + --> $DIR/label-on-block-suggest-move.rs:11:18 + | +LL | for i in [0] 'a: {} + | ^^^ not supported here + | +help: if you meant to label the loop, move this label before the loop + | +LL - for i in [0] 'a: {} +LL + 'a: for i in [0] {} + | + +error: block label not supported here + --> $DIR/label-on-block-suggest-move.rs:16:31 + | +LL | while break 'a 'b: {} 'c: {} + | ^^^ not supported here + | +help: if you meant to label the loop, move this label before the loop + | +LL - while break 'a 'b: {} 'c: {} +LL + 'c: while break 'a 'b: {} {} + | + +error: block label not supported here + --> $DIR/label-on-block-suggest-move.rs:19:33 + | +LL | while break 'a ('b: {}) 'c: {} + | ^^^ not supported here + | +help: if you meant to label the loop, move this label before the loop + | +LL - while break 'a ('b: {}) 'c: {} +LL + 'c: while break 'a ('b: {}) {} + | + +error: block label not supported here + --> $DIR/label-on-block-suggest-move.rs:26:29 + | +LL | while (break 'a {}) 'c: {} + | ^^^ not supported here + | +help: if you meant to label the loop, move this label before the loop + | +LL - while (break 'a {}) 'c: {} +LL + 'c: while (break 'a {}) {} + | + +error: block label not supported here + --> $DIR/label-on-block-suggest-move.rs:32:14 + | +LL | 'a: loop 'b: {} + | ^^^ not supported here + +error: block label not supported here + --> $DIR/label-on-block-suggest-move.rs:35:21 + | +LL | 'a: while false 'b: {} + | ^^^ not supported here + +error: block label not supported here + --> $DIR/label-on-block-suggest-move.rs:38:22 + | +LL | 'a: for i in [0] 'b: {} + | ^^^ not supported here + +error: block label not supported here + --> $DIR/label-on-block-suggest-move.rs:43:35 + | +LL | 'd: while break 'a 'b: {} 'c: {} + | ^^^ not supported here + +error: block label not supported here + --> $DIR/label-on-block-suggest-move.rs:46:37 + | +LL | 'd: while break 'a ('b: {}) 'c: {} + | ^^^ not supported here + +error: block label not supported here + --> $DIR/label-on-block-suggest-move.rs:53:33 + | +LL | 'd: while (break 'a {}) 'c: {} + | ^^^ not supported here + +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/label-on-block-suggest-move.rs:83:9 + | +LL | 'a: 'b: {} + | ^^ expected `while`, `for`, `loop` or `{` after a label + | +help: consider removing the label + | +LL - 'a: 'b: {} +LL + 'b: {} + | + +error: parentheses are required around this expression to avoid confusion with a labeled break expression + --> $DIR/label-on-block-suggest-move.rs:86:24 + | +LL | loop { while break 'b: {} {} } + | ^^^^^^ + | +help: wrap the expression in parentheses + | +LL | loop { while break ('b: {}) {} } + | + + + +error[E0590]: `break` or `continue` with no label in the condition of a `while` loop + --> $DIR/label-on-block-suggest-move.rs:86:18 + | +LL | loop { while break 'b: {} {} } + | ^^^^^^^^^^^^ unlabeled `break` in the condition of a `while` loop + +error: aborting due to 15 previous errors + +For more information about this error, try `rustc --explain E0590`. diff --git a/tests/ui/macros/duplicate-builtin.rs b/tests/ui/macros/duplicate-builtin.rs deleted file mode 100644 index c75782128f4..00000000000 --- a/tests/ui/macros/duplicate-builtin.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ compile-flags:--crate-type lib -#![feature(decl_macro)] -#![feature(rustc_attrs)] - -#[rustc_builtin_macro] -pub macro test($item:item) { -//~^ NOTE previously defined - /* compiler built-in */ -} - -mod inner { - #[rustc_builtin_macro] - pub macro test($item:item) { - //~^ ERROR attempted to define built-in macro more than once [E0773] - /* compiler built-in */ - } -} diff --git a/tests/ui/macros/duplicate-builtin.stderr b/tests/ui/macros/duplicate-builtin.stderr deleted file mode 100644 index 887a4fbbdc8..00000000000 --- a/tests/ui/macros/duplicate-builtin.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0773]: attempted to define built-in macro more than once - --> $DIR/duplicate-builtin.rs:13:5 - | -LL | / pub macro test($item:item) { -LL | | -LL | | /* compiler built-in */ -LL | | } - | |_____^ - | -note: previously defined here - --> $DIR/duplicate-builtin.rs:6:1 - | -LL | / pub macro test($item:item) { -LL | | -LL | | /* compiler built-in */ -LL | | } - | |_^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0773`. diff --git a/tests/ui/macros/unknown-builtin.rs b/tests/ui/macros/unknown-builtin.rs index 048f5d68d34..aa6e04d3fb8 100644 --- a/tests/ui/macros/unknown-builtin.rs +++ b/tests/ui/macros/unknown-builtin.rs @@ -1,12 +1,11 @@ -//@ error-pattern: attempted to define built-in macro more than once - #![feature(rustc_attrs)] #[rustc_builtin_macro] macro_rules! unknown { () => () } //~ ERROR cannot find a built-in macro with name `unknown` +// Defining another `line` builtin macro should not cause an error. #[rustc_builtin_macro] -macro_rules! line { () => () } //~ NOTE previously defined here +macro_rules! line { () => () } fn main() { line!(); diff --git a/tests/ui/macros/unknown-builtin.stderr b/tests/ui/macros/unknown-builtin.stderr index 22f54e04e54..1a83398891b 100644 --- a/tests/ui/macros/unknown-builtin.stderr +++ b/tests/ui/macros/unknown-builtin.stderr @@ -1,18 +1,8 @@ error: cannot find a built-in macro with name `unknown` - --> $DIR/unknown-builtin.rs:6:1 + --> $DIR/unknown-builtin.rs:4:1 | LL | macro_rules! unknown { () => () } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0773]: attempted to define built-in macro more than once - --> $SRC_DIR/core/src/macros/mod.rs:LL:COL - | -note: previously defined here - --> $DIR/unknown-builtin.rs:9:1 - | -LL | macro_rules! line { () => () } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0773`. diff --git a/tests/ui/match/privately-uninhabited-issue-137999.rs b/tests/ui/match/privately-uninhabited-issue-137999.rs new file mode 100644 index 00000000000..918393a0c6a --- /dev/null +++ b/tests/ui/match/privately-uninhabited-issue-137999.rs @@ -0,0 +1,44 @@ +//@ edition:2024 +//@ check-fail + +mod m { + enum Void {} + + pub struct Internal { + _v: Void, + } + + pub enum Test { + A(u32, u32), + B(Internal), + } +} + +use m::Test; + +pub fn f1(x: &mut Test) { + let r1: &mut u32 = match x { + Test::A(a, _) => a, + _ => todo!(), + }; + + let r2: &mut u32 = match x { //~ ERROR cannot use `*x` because it was mutably borrowed + Test::A(_, b) => b, + _ => todo!(), + }; + + let _ = *r1; + let _ = *r2; +} + +pub fn f2(x: &mut Test) { + let r = &mut *x; + match x { //~ ERROR cannot use `*x` because it was mutably borrowed + Test::A(_, _) => {} + _ => {} + } + + let _ = r; +} + +fn main() {} diff --git a/tests/ui/match/privately-uninhabited-issue-137999.stderr b/tests/ui/match/privately-uninhabited-issue-137999.stderr new file mode 100644 index 00000000000..6f74a75375e --- /dev/null +++ b/tests/ui/match/privately-uninhabited-issue-137999.stderr @@ -0,0 +1,26 @@ +error[E0503]: cannot use `*x` because it was mutably borrowed + --> $DIR/privately-uninhabited-issue-137999.rs:25:30 + | +LL | Test::A(a, _) => a, + | - `x.0` is borrowed here +... +LL | let r2: &mut u32 = match x { + | ^ use of borrowed `x.0` +... +LL | let _ = *r1; + | --- borrow later used here + +error[E0503]: cannot use `*x` because it was mutably borrowed + --> $DIR/privately-uninhabited-issue-137999.rs:36:11 + | +LL | let r = &mut *x; + | ------- `*x` is borrowed here +LL | match x { + | ^ use of borrowed `*x` +... +LL | let _ = r; + | - borrow later used here + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0503`. diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.fixed b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.fixed index 85b1853c23b..922c883f4f7 100644 --- a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.fixed +++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.fixed @@ -1,16 +1,17 @@ //@ run-rustfix +//@ revisions: current next +//@[next] compile-flags: -Znext-solver #![allow(unused_variables, dead_code)] -use std::collections::BTreeMap; -use std::collections::HashSet; +use std::collections::{BTreeMap, HashSet}; -#[derive(Debug,Eq,PartialEq,Hash)] +#[derive(Debug, Eq, PartialEq, Hash)] #[derive(Clone)] enum Day { Mon, } struct Class { - days: BTreeMap<u32, HashSet<Day>> + days: BTreeMap<u32, HashSet<Day>>, } impl Class { diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.stderr b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.stderr index 6a9d76f7998..301f3c3a458 100644 --- a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.stderr +++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:18:39 + --> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:19:39 | LL | let mut x: HashSet<Day> = v.clone(); | ------------ ^^^^^^^^^ expected `HashSet<Day>`, found `&HashSet<Day>` @@ -9,7 +9,7 @@ LL | let mut x: HashSet<Day> = v.clone(); = note: expected struct `HashSet<_>` found reference `&HashSet<_>` note: `HashSet<Day>` does not implement `Clone`, so `&HashSet<Day>` was cloned instead - --> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:18:39 + --> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:19:39 | LL | let mut x: HashSet<Day> = v.clone(); | ^ diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.fixed b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.fixed new file mode 100644 index 00000000000..922c883f4f7 --- /dev/null +++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.fixed @@ -0,0 +1,31 @@ +//@ run-rustfix +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +#![allow(unused_variables, dead_code)] +use std::collections::{BTreeMap, HashSet}; + +#[derive(Debug, Eq, PartialEq, Hash)] +#[derive(Clone)] +enum Day { + Mon, +} + +struct Class { + days: BTreeMap<u32, HashSet<Day>>, +} + +impl Class { + fn do_stuff(&self) { + for (_, v) in &self.days { + let mut x: HashSet<Day> = v.clone(); //~ ERROR + let y: Vec<Day> = x.drain().collect(); + println!("{:?}", x); + } + } +} + +fn fail() { + let c = Class { days: BTreeMap::new() }; + c.do_stuff(); +} +fn main() {} diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr new file mode 100644 index 00000000000..301f3c3a458 --- /dev/null +++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr @@ -0,0 +1,25 @@ +error[E0308]: mismatched types + --> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:19:39 + | +LL | let mut x: HashSet<Day> = v.clone(); + | ------------ ^^^^^^^^^ expected `HashSet<Day>`, found `&HashSet<Day>` + | | + | expected due to this + | + = note: expected struct `HashSet<_>` + found reference `&HashSet<_>` +note: `HashSet<Day>` does not implement `Clone`, so `&HashSet<Day>` was cloned instead + --> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:19:39 + | +LL | let mut x: HashSet<Day> = v.clone(); + | ^ + = help: `Clone` is not implemented because the trait bound `Day: Clone` is not satisfied +help: consider annotating `Day` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | enum Day { + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.rs b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.rs index 740cda470d9..6f7b55be8bd 100644 --- a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.rs +++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.rs @@ -1,15 +1,16 @@ //@ run-rustfix +//@ revisions: current next +//@[next] compile-flags: -Znext-solver #![allow(unused_variables, dead_code)] -use std::collections::BTreeMap; -use std::collections::HashSet; +use std::collections::{BTreeMap, HashSet}; -#[derive(Debug,Eq,PartialEq,Hash)] +#[derive(Debug, Eq, PartialEq, Hash)] enum Day { Mon, } struct Class { - days: BTreeMap<u32, HashSet<Day>> + days: BTreeMap<u32, HashSet<Day>>, } impl Class { diff --git a/tests/ui/print-request/stability.rs b/tests/ui/print-request/stability.rs new file mode 100644 index 00000000000..b205b055569 --- /dev/null +++ b/tests/ui/print-request/stability.rs @@ -0,0 +1,103 @@ +//! Check that we properly gate unstable print requests (`--print=KIND`) and require the user to +//! specify `-Z unstable-options` to use unstable print requests. + +// We don't care about the exact *stdout* output (i.e. what the print requests actually give back) +// for the purposes of this test. +//@ dont-check-compiler-stdout + +// We want to check for the core error message of the unstable print requests being `-Z +// unstable-options`-gated and not the help because the help can change with addition of a new print +// request, which is not important for the purposes of this test. +//@ dont-check-compiler-stderr + +// ======================= +// Unstable print requests +// ======================= + +//@ revisions: all_target_specs_json +//@[all_target_specs_json] compile-flags: --print=all-target-specs-json +//@[all_target_specs_json] error-pattern: the `-Z unstable-options` flag must also be passed + +//@ revisions: check_cfg +//@[check_cfg] compile-flags: --print=check-cfg +//@[check_cfg] error-pattern: the `-Z unstable-options` flag must also be passed + +//@ revisions: target_spec_json +//@[target_spec_json] compile-flags: --print=target-spec-json +//@[target_spec_json] error-pattern: the `-Z unstable-options` flag must also be passed + +// ======================= +// Stable print requests +// ======================= + +//@ revisions: calling_conventions +//@[calling_conventions] compile-flags: --print=calling-conventions +//@[calling_conventions] check-pass + +//@ revisions: cfg +//@[cfg] compile-flags: --print=cfg +//@[cfg] check-pass + +//@ revisions: code_models +//@[code_models] compile-flags: --print=code-models +//@[code_models] check-pass + +//@ revisions: crate_name +//@[crate_name] compile-flags: --print=crate-name +//@[crate_name] check-pass + +// Note: `--print=deployment_target` is only accepted on Apple targets. +//@ revisions: deployment_target +//@[deployment_target] only-apple +//@[deployment_target] compile-flags: --print=deployment-target +//@[deployment_target] check-pass + +//@ revisions: file_names +//@[file_names] compile-flags: --print=file-names +//@[file_names] check-pass + +//@ revisions: host_tuple +//@[host_tuple] compile-flags: --print=host-tuple +//@[host_tuple] check-pass + +//@ revisions: link_args +//@[link_args] compile-flags: --print=link-args +//@[link_args] check-pass + +//@ revisions: native_static_libs +//@[native_static_libs] compile-flags: --print=native-static-libs +//@[native_static_libs] check-pass + +//@ revisions: relocation_models +//@[relocation_models] compile-flags: --print=relocation-models +//@[relocation_models] check-pass + +//@ revisions: split_debuginfo +//@[split_debuginfo] compile-flags: --print=split-debuginfo +//@[split_debuginfo] check-pass + +//@ revisions: stack_protector_strategies +//@[stack_protector_strategies] compile-flags: --print=stack-protector-strategies +//@[stack_protector_strategies] check-pass + +//@ revisions: target_cpus +//@[target_cpus] compile-flags: --print=target-cpus +//@[target_cpus] check-pass + +//@ revisions: target_features +//@[target_features] compile-flags: --print=target-features +//@[target_features] check-pass + +//@ revisions: target_libdir +//@[target_libdir] compile-flags: --print=target-libdir +//@[target_libdir] check-pass + +//@ revisions: target_list +//@[target_list] compile-flags: --print=target-list +//@[target_list] check-pass + +//@ revisions: tls_models +//@[tls_models] compile-flags: --print=tls-models +//@[tls_models] check-pass + +fn main() {} diff --git a/tests/ui/tool-attributes/crate-attr.rs b/tests/ui/tool-attributes/crate-attr.rs new file mode 100644 index 00000000000..c6d7974945f --- /dev/null +++ b/tests/ui/tool-attributes/crate-attr.rs @@ -0,0 +1,5 @@ +//@ check-pass +//@ compile-flags: -Z crate-attr=feature(register_tool) -Z crate-attr=register_tool(foo) + +#[allow(foo::bar)] +fn main() {} diff --git a/tests/ui/tool-attributes/multiple-registered.rs b/tests/ui/tool-attributes/multiple-registered.rs new file mode 100644 index 00000000000..4d54c2dcb08 --- /dev/null +++ b/tests/ui/tool-attributes/multiple-registered.rs @@ -0,0 +1,7 @@ +//@ check-pass + +#![feature(register_tool)] +#![register_tool(foo, bar, baz)] + +#[allow(foo::a, bar::b, baz::c)] +fn main() {} diff --git a/tests/ui/tool-attributes/nested-disallowed.rs b/tests/ui/tool-attributes/nested-disallowed.rs new file mode 100644 index 00000000000..8e780427761 --- /dev/null +++ b/tests/ui/tool-attributes/nested-disallowed.rs @@ -0,0 +1,4 @@ +#![feature(register_tool)] +#![register_tool(foo::bar)] //~ ERROR only accepts identifiers + +fn main() {} diff --git a/tests/ui/tool-attributes/nested-disallowed.stderr b/tests/ui/tool-attributes/nested-disallowed.stderr new file mode 100644 index 00000000000..1af73fc2f19 --- /dev/null +++ b/tests/ui/tool-attributes/nested-disallowed.stderr @@ -0,0 +1,8 @@ +error: `register_tool` only accepts identifiers + --> $DIR/nested-disallowed.rs:2:18 + | +LL | #![register_tool(foo::bar)] + | ^^^^^^^^ not an identifier + +error: aborting due to 1 previous error + diff --git a/tests/ui/write-fmt-errors.rs b/tests/ui/write-fmt-errors.rs index 1dafb9a784b..b48fa3f11cc 100644 --- a/tests/ui/write-fmt-errors.rs +++ b/tests/ui/write-fmt-errors.rs @@ -4,7 +4,7 @@ #![feature(io_error_uncategorized)] use std::fmt; -use std::io::{self, Error, Write, sink}; +use std::io::{self, Error, Write}; use std::panic::catch_unwind; struct ErrorDisplay; @@ -33,7 +33,7 @@ fn main() { assert!(res.is_err(), "writer error did not propagate"); // Test that the error from the formatter is detected. - let res = catch_unwind(|| write!(sink(), "{} {} {}", 1, ErrorDisplay, "bar")); + let res = catch_unwind(|| write!(vec![], "{} {} {}", 1, ErrorDisplay, "bar")); let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap(); assert!( err.contains("formatting trait implementation returned an error"), diff --git a/triagebot.toml b/triagebot.toml index 293ad259910..cd488a7cdf6 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -421,7 +421,7 @@ trigger_files = [ trigger_files = [ "Cargo.toml", "configure", - "config.example.toml", + "bootstrap.example.toml", "src/bootstrap", "src/build_helper", "src/tools/rust-installer", @@ -948,9 +948,9 @@ This PR modifies `src/bootstrap/defaults`. If appropriate, please update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/src/utils/change_tracker.rs`. """ -[mentions."config.example.toml"] +[mentions."bootstrap.example.toml"] message = """ -This PR modifies `config.example.toml`. +This PR modifies `bootstrap.example.toml`. If appropriate, please update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/src/utils/change_tracker.rs`. """ @@ -1082,7 +1082,6 @@ contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html" users_on_vacation = [ "jyn514", "ChrisDenton", - "jieyouxu", ] [[assign.warn_non_default_branch.exceptions]] |
